#define DELAY 200 const int LED[] = {11, 10, 9, 8, 7, 6, 5, 4}; const int BUTTON[] = {A0, A1, A2, A3}; unsigned int clk = 0; // the counter in every mode void setup() { for (int i = 0; i < 8; i++) { pinMode(LED[i], OUTPUT); digitalWrite(LED[i], HIGH); } for (int i = 0; i < 4; i++) { pinMode(BUTTON[i], INPUT); } } /* * Function: call_interval * Call a function per DELAY * * f: the function being called * * Side effect: increase clk per DELAY */ void call_interval( void (*f)(unsigned int) ) { static unsigned long checkpoint = 0; if (millis() - checkpoint > DELAY) { (*f)(clk); clk += 1; checkpoint = millis(); } } /* Function: get_mode Return the current mode from buttons input Side effects: reset the clk on button pressed */ unsigned int get_mode() { static int last = 0; for (int i = 0; i < 4; i++) { if (!digitalRead(BUTTON[i])) { last = i + 1; clk = 0; return last; } } return last; } /* Function: binary Display the LED as binary of clk */ void binary(unsigned int value) { for (int i = 0; i < 8; i++) { digitalWrite(LED[7 - i], !((value >> i) % 2)); } } void gray_code(unsigned int value) { binary(value ^ (value >> 1)); } /* Function: random_popup Randomly select LED. Each LED will be turned on for 3 clk */ void random_popup(unsigned int clk) { static int hp[8]; // Reset hp on mode changing if (clk == 0) { for (int i = 0; i < 8; i++) { hp[i] = 0; } } for (int i = 0; i < 8; i++) { // Decrease hp if (hp[i] > 0) { hp[i] -= 1; } digitalWrite(LED[i], !(hp[i])); } // randomly select LED which is not turned on int choice; do { choice = random(8); } while (hp[choice] > 0); hp[choice] = 4; } void clear_all() { for (int i = 0; i < 8; i++) { digitalWrite(LED[i], HIGH); } } void loop() { const int mode = get_mode(); if (mode == 1) { call_interval(binary); } if (mode == 2) { call_interval(gray_code); } if (mode == 3) { call_interval(random_popup); } if (mode == 4) { clear_all(); } delay(1); }