#define YELLOW 0 #define BUTTON 1 #define M 2 #define I 3 #define U 4 #define TICKS_SEC 20 #define TICK_MS (1000 / TICKS_SEC) #define INACTIVE_SEC 60 #define VMAX 80 enum State { S_START, S_RECITE, S_GAP, S_RABBIT_RIGHT, S_MU }; byte down; int inactive; int active; byte state; int arg; int tick; byte len; byte v[VMAX]; void setup() { // initialize the digital pin as an output. pinMode(YELLOW, OUTPUT); pinMode(BUTTON, INPUT_PULLUP); pinMode(M, OUTPUT); pinMode(I, OUTPUT); pinMode(U, OUTPUT); } void set(byte m, byte i, byte u) { digitalWrite(M, m ? HIGH : LOW); digitalWrite(I, i ? HIGH : LOW); digitalWrite(U, u ? HIGH : LOW); } #define setM() set(1,0,0) #define setI() set(0,1,0) #define setU() set(0,0,1) #define set0() set(0,0,0) void on() { digitalWrite(YELLOW, HIGH); } void off() { digitalWrite(YELLOW, LOW); } void loop() { off(); down = (digitalRead(BUTTON) == LOW); // Keep track of active & inactive times. if (down) { ++active; inactive = 0; } else { ++inactive; active = 0; } // Check for victory. if (len==2 && v[0]==M && v[1]==I) state=S_MU; if (down) { set(1,1,1); arg=0; state=S_RABBIT_RIGHT; } else switch (state) { case S_START: // len = 2; v[0] = M; v[1] = I; len = 4; v[0] = M; v[1] = I; v[2] = U; v[3] = U; // state = S_RABBIT_RIGHT; state = S_RECITE; break; case S_RECITE: // init arg to 0 #define TICKS_ON ((int)(500/TICK_MS)) #define TICKS_OFF ((int)(500/TICK_MS)) if (tick < TICKS_ON) { switch (v[arg]) { case M: setM(); break; case I: setI(); break; case U: setU(); break; default: set0(); } } else if (tick < TICKS_ON+TICKS_OFF) { set0(); } else { tick = 0; ++arg; if (arg >= len) state = S_GAP; } break; case S_GAP: #define TICKS_GAP ((int)(2000/TICK_MS)) if (tick < TICKS_GAP) { set0(); } else { tick = 0; arg = 0; state = S_RECITE; } break; case S_RABBIT_RIGHT: #define TICKS_RABBIT ((int)(100/TICK_MS)) if (tick < 1*TICKS_RABBIT) { setM(); } else if (tick < 2*TICKS_RABBIT) { setI(); } else if (tick < 3*TICKS_RABBIT) { setU(); } else if (tick < 6*TICKS_RABBIT) { set0(); } else { tick = 0; ++arg; if (arg > 5) { tick=TICKS_GAP/3; state=S_GAP; } } break; } delay(TICK_MS); ++tick; }