diff --git a/week4-4/week4-4.ino b/week4-4/week4-4.ino index 9836f6a..0e9a934 100644 --- a/week4-4/week4-4.ino +++ b/week4-4/week4-4.ino @@ -3,7 +3,7 @@ const int LED[] = {11, 10, 9, 8, 7, 6, 5, 4}; const int BUTTON[] = {A0, A1, A2, A3}; -int clk = 0; // 定義每個模式中的計數器 +unsigned int clk = 0; // the counter in every mode void setup() { for (int i = 0; i < 8; i++) { @@ -15,23 +15,29 @@ void setup() { } } +/* + * 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) { - for (int i = 0; i < 8; i++) { - digitalWrite(LED[7 - i], !((value >> i) % 2)); - } + (*f)(clk); clk += 1; checkpoint = millis(); } } /* - * Function: get_mode - * Return the current mode from buttons input - * - * Side effects: reset the clk on button pressed - */ + 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++) { @@ -45,20 +51,12 @@ unsigned int get_mode() { } /* - * Function: binary - * Display the LED as binary of clk - * - * increase clk per DELAY - * Side effect: increase clk per DELAY - */ + Function: binary + Display the LED as binary of clk +*/ void binary(unsigned int value) { - static unsigned long checkpoint = 0; - if (millis() - checkpoint > DELAY) { - for (int i = 0; i < 8; i++) { - digitalWrite(LED[7 - i], !((value >> i) % 2)); - } - clk += 1; - checkpoint = millis(); + for (int i = 0; i < 8; i++) { + digitalWrite(LED[7 - i], !((value >> i) % 2)); } } @@ -67,16 +65,12 @@ void gray_code(unsigned int value) { } /* - * Function: random_popup - * Randomly blink LED - * - * Randomly select LED. Each LED will turn on for 3 clk - * Side effect: increase clk per DELAY - */ -void random_popup() { - static unsigned long checkpoint = 0; - static int hp[] = {0, 0, 0, 0, 0, 0, 0, 0}; - + 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++) { @@ -84,26 +78,20 @@ void random_popup() { } } - if (millis() - checkpoint > DELAY) { - for (int i = 0; i < 8; i++) { - - // Decrease hp - if (hp[i] > 0) { - hp[i] -= 1; - } - digitalWrite(LED[i], !(hp[i])); + for (int i = 0; i < 8; i++) { + // Decrease hp + if (hp[i] > 0) { + hp[i] -= 1; } - - // randomly select LED which is not turned on - int choice; - do { - choice = random(8); - } while (hp[choice] > 0); - hp[choice] = 4; - - checkpoint = millis(); - clk++; + 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() { @@ -115,13 +103,13 @@ void clear_all() { void loop() { const int mode = get_mode(); if (mode == 1) { - binary(clk); + call_interval(binary); } if (mode == 2) { - gray_code(clk); + call_interval(gray_code); } if (mode == 3) { - random_popup(); + call_interval(random_popup); } if (mode == 4) { clear_all(); diff --git a/week5-1/week5-1.ino b/week5-1/week5-1.ino new file mode 100644 index 0000000..b24d973 --- /dev/null +++ b/week5-1/week5-1.ino @@ -0,0 +1,45 @@ +const unsigned int scan[] = {5, 6, 7, 8}; +#define DATA 10 +#define LATCH 11 +#define CLK 12 + +byte numbers[] = { + 0xC0, 0xF9, 0xA4, 0xB0, 0x99, + 0x92, 0x82, 0xF8, 0x80, 0x90 +}; + +void setup() { + for (int i = 0; i < 4; i++) { + pinMode(scan[i], OUTPUT); + digitalWrite(scan[i], HIGH); + } + pinMode(DATA, OUTPUT); + pinMode(LATCH, OUTPUT); + pinMode(CLK, OUTPUT); +} + +void setDigits(int number, int digits[4]) { + for (int i = 0; i < 4; i++) { + digits[i] = number % 10; + number /= 10; + } +} + +void loop() { + static int number = 0; + static unsigned long checkpoint = 0; + static int digits[4]; + for (int i = 0; i < 4; i++) { + digitalWrite(LATCH, LOW); + shiftOut(DATA, CLK, MSBFIRST, numbers[digits[i]]); + digitalWrite(LATCH, HIGH); + digitalWrite(scan[i], LOW); + delay(1); + digitalWrite(scan[i], HIGH); + } + if (millis() - checkpoint > 200) { + number++; + setDigits(number, digits); + checkpoint = millis(); + } +} diff --git a/week5-3/week5-3.ino b/week5-3/week5-3.ino new file mode 100644 index 0000000..5f64d40 --- /dev/null +++ b/week5-3/week5-3.ino @@ -0,0 +1,50 @@ +const unsigned int scan[] = {5, 6, 7, 8}; +#define DATA 10 +#define LATCH 11 +#define CLK 12 +const int date[] = {2022, 323}; + +byte numbers[] = { + 0xC0, 0xF9, 0xA4, 0xB0, 0x99, + 0x92, 0x82, 0xF8, 0x80, 0x90 +}; + +void setup() { + for (int i = 0; i < 4; i++) { + pinMode(scan[i], OUTPUT); + digitalWrite(scan[i], HIGH); + } + pinMode(DATA, OUTPUT); + pinMode(LATCH, OUTPUT); + pinMode(CLK, OUTPUT); +} + +void setDigits(int number, int digits[4]) { + for (int i = 0; i < 4; i++) { + digits[i] = number % 10; + number /= 10; + } +} + +void show(int digits[4]) { + for (int i = 0; i < 4; i++) { + digitalWrite(LATCH, LOW); + shiftOut(DATA, CLK, MSBFIRST, numbers[digits[i]]); + digitalWrite(LATCH, HIGH); + digitalWrite(scan[i], LOW); + delay(1); + digitalWrite(scan[i], HIGH); + } +} + +void loop() { + static unsigned long checkpoint = 0; + static int digits[4]; + static bool mode = false; + show(digits); + if (millis() - checkpoint > 500) { + mode = !mode; + setDigits(date[mode], digits); + checkpoint = millis(); + } +} diff --git a/week5-4/week5-4.ino b/week5-4/week5-4.ino new file mode 100644 index 0000000..327f3d3 --- /dev/null +++ b/week5-4/week5-4.ino @@ -0,0 +1,42 @@ +const unsigned int scan[] = {5, 6, 7, 8}; +#define DATA 10 +#define LATCH 11 +#define CLK 12 + +byte numbers[] = { + 0xC0, 0xF9, 0xA4, 0xB0, 0x99, + 0x92, 0x82, 0xF8, 0x80, 0x90 +}; + +void setup() { + for (int i = 0; i < 4; i++) { + pinMode(scan[i], OUTPUT); + digitalWrite(scan[i], HIGH); + } + pinMode(DATA, OUTPUT); + pinMode(LATCH, OUTPUT); + pinMode(CLK, OUTPUT); +} + +void show(int digits[10], int shift) { + for (int i = 0; i < 4; i++) { + digitalWrite(LATCH, LOW); + shiftOut(DATA, CLK, MSBFIRST, numbers[digits[(shift + i) % 10]]); + digitalWrite(LATCH, HIGH); + digitalWrite(scan[3-i], LOW); + delay(1); + digitalWrite(scan[3-i], HIGH); + } +} + +void loop() { + static unsigned long checkpoint = 0; + static int digits[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + static int count = 0; + show(digits, count); + if (millis() - checkpoint > 500) { + count--; + if (count < 0) count = 9; + checkpoint = millis(); + } +} diff --git a/week5-5/week5-5.ino b/week5-5/week5-5.ino new file mode 100644 index 0000000..b2e95b0 --- /dev/null +++ b/week5-5/week5-5.ino @@ -0,0 +1,90 @@ +const unsigned int scan[] = {5, 6, 7, 8}; +const unsigned int LED[] = {9, 13, 2, 3}; +const unsigned int BUTTON[] = {A0, A1}; +#define DATA 10 +#define LATCH 11 +#define CLK 12 + +void setup() { + for (int i = 0; i < 4; i++) { + pinMode(scan[i], OUTPUT); + digitalWrite(scan[i], HIGH); + } + for (int i = 0; i < 4; i++) { + pinMode(LED[i], OUTPUT); + digitalWrite(LED[i], HIGH); + } + for (int i = 0; i < 2; i++) { + pinMode(BUTTON[i], INPUT); + } + pinMode(DATA, OUTPUT); + pinMode(LATCH, OUTPUT); + pinMode(CLK, OUTPUT); +} + +int get_mode() { + static int last = 0; + for (int i = 0; i < 2; i++) { + if (!digitalRead(BUTTON[i])) { + last = i+1; + return last; + } + } + return last; +} + +void show(byte digits[4]) { + for (int i = 0; i < 4; i++) { + digitalWrite(LATCH, LOW); + shiftOut(DATA, CLK, MSBFIRST, ~digits[i]); + digitalWrite(LATCH, HIGH); + digitalWrite(scan[3 - i], LOW); + delay(1); + digitalWrite(scan[3 - i], HIGH); + } +} + +void mode_display() { + static byte digits[4]; + static byte p = 0; + static unsigned long checkpoint = 0; + show(digits); + if (millis() - checkpoint > 200) { + if (p == 4) { + // all the numbers are turned on, reset + p = 0; + for (int i = 0; i < 4; i++) digits[i] = 0; + } + digits[p] <<= 1; + digits[p] += 1; + if (digits[p] == 0xFF) { + // if current digit is full, change to the next one + p++; + } + checkpoint = millis(); + } +} + +void mode_led() { + static unsigned long checkpoint; + static int c = 0; + if (millis() - checkpoint > 200) { + for (int i = 0; i < 4; i++) { + digitalWrite(LED[i], i != c%4); + } + c++; + checkpoint = millis(); + } +} + +void loop() { + switch (get_mode()) { + case 1: + mode_display(); + break; + + case 2: + mode_led(); + break; + } +}