119 lines
2.1 KiB
C++
119 lines
2.1 KiB
C++
#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);
|
|
}
|