From a9522d6808b266cea8e3c43623dd5e642b46d7c7 Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Sat, 17 Jun 2017 14:38:33 +0000 Subject: [PATCH] Final version --- terminal/terminal.ino | 217 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 206 insertions(+), 11 deletions(-) diff --git a/terminal/terminal.ino b/terminal/terminal.ino index 643f2c2..7595e50 100644 --- a/terminal/terminal.ino +++ b/terminal/terminal.ino @@ -1,9 +1,54 @@ #include -LiquidCrystal lcd(12, 11, 5, 4, 3, 2); +// LED pins +#define LEDS_GRN 15 // Analog 1; Common green anode +#define LEDS_RED 16 // Analog 2; Common red anode +#define LED1 13 // LED1 cathode +#define LED2 12 // LED2 cathode +#define LED3 11 // LED3 cathode +#define LED4 10 // LED4 cathode -#define COLS 20 -#define ROWS 4 +#define LED_OFF 0x00 +#define LED_GRN 0x01 +#define LED_RED 0x02 +#define LED_BLINK 0x04 + +struct leds { + byte a:3; + byte b:3; + byte c:3; + byte d:3; + unsigned int counter; +}; +struct leds leds; + +// Button pin +#define BUTTON 14 // Analog 0; push button + +// LCD pins +#define LCD_REGSEL 3 // Register select +#define LCD_ENABLE 4 // Chip enable +#define LCD_D4 5 // Data line +#define LCD_D5 6 // Data line +#define LCD_D6 7 // Data line +#define LCD_D7 8 // Data line +#define LCD_BL 2 // Backlight + +LiquidCrystal lcd(LCD_REGSEL, LCD_ENABLE, LCD_D4, LCD_D5, LCD_D6, LCD_D7); + +enum backlight_state { + BL_OFF, + BL_ON, + BL_FLASH +}; +struct backlight { + enum backlight_state state; + unsigned int timer; +}; +struct backlight backlight; + +#define COLS 40 +#define ROWS 2 /** * Special characters. @@ -99,10 +144,97 @@ void write(struct terminal *term, char ch) struct terminal term; char message[] = - "Beste Mart, van\r\n" - "harte gefeliciteerd!" - "Hier een herprogram-" - "meerbare terminal. "; + "Beste Mart, van harte gefeliciteerd! \x00\x00\r\n" + "Hier een herprogrammeerbare terminal. "; + +/** + * Tasks for the LEDs. Needs to be called every few ms(?) for multiplexing. + * When an LED is blinking and in the off period, it is necessary to call + * digitalWrite() twice and set the cathode. This ensures that the function + * takes equally long to return on every iteration, s.t. the blinking duty + * cycle is exactly 50% and LEDs blink equally bright, regardless of the status + * of other LEDs. + */ +void led_tasks() +{ + leds.counter++; + switch (leds.counter & 0x03) { + case 0: + digitalWrite(LED4, 1); + if ((leds.a & LED_BLINK) && leds.counter & 0x4000) { + digitalWrite(LEDS_GRN, 0); + digitalWrite(LEDS_RED, 0); + } else { + digitalWrite(LEDS_GRN, leds.a & 1); + digitalWrite(LEDS_RED, leds.a & 2); + } + digitalWrite(LED1, 0); + break; + case 1: + digitalWrite(LED1, 1); + if ((leds.b & LED_BLINK) && leds.counter & 0x4000) { + digitalWrite(LEDS_GRN, 0); + digitalWrite(LEDS_RED, 0); + } else { + digitalWrite(LEDS_GRN, leds.b & 1); + digitalWrite(LEDS_RED, leds.b & 2); + } + digitalWrite(LED2, 0); + break; + case 2: + digitalWrite(LED2, 1); + if ((leds.c & LED_BLINK) && leds.counter & 0x4000) { + digitalWrite(LEDS_GRN, 0); + digitalWrite(LEDS_RED, 0); + } else { + digitalWrite(LEDS_GRN, leds.c & 1); + digitalWrite(LEDS_RED, leds.c & 2); + } + digitalWrite(LED3, 0); + break; + case 3: + digitalWrite(LED3, 1); + if ((leds.d & LED_BLINK) && leds.counter & 0x4000) { + digitalWrite(LEDS_GRN, 0); + digitalWrite(LEDS_RED, 0); + } else { + digitalWrite(LEDS_GRN, leds.d & 1); + digitalWrite(LEDS_RED, leds.d & 2); + } + digitalWrite(LED4, 0); + break; + } +} + +void button_tasks() +{ + if (digitalRead(BUTTON)) { + bl_flash(); + } +} + +void bl_tasks() +{ + if (backlight.state == BL_FLASH) + if (!--backlight.timer) + backlight.state = BL_OFF; + + switch (backlight.state) { + case BL_OFF: + digitalWrite(LCD_BL, 0); + break; + case BL_FLASH: + case BL_ON: + digitalWrite(LCD_BL, 1); + break; + } +} + +void bl_flash() +{ + backlight.state = BL_FLASH; + backlight.timer = (unsigned int) -1; +} void setup() { @@ -117,18 +249,81 @@ void setup() lcd.begin(COLS, ROWS); lcd.blink(); - Serial.begin(9600); + Serial.begin(115200); for (byte i = 0; i < ROWS * COLS; i++) term.contents[i] = ' '; for (byte i = 0; i < sizeof(message) - 1; i++) write(&term, message[i]); + + pinMode(LCD_BL, OUTPUT); + + pinMode(LEDS_GRN, OUTPUT); + pinMode(LEDS_RED, OUTPUT); + pinMode(LED1, OUTPUT); + pinMode(LED2, OUTPUT); + pinMode(LED3, OUTPUT); + pinMode(LED4, OUTPUT); + + pinMode(BUTTON, INPUT); + + leds.a = LED_GRN | LED_BLINK; + leds.b = LED_RED | LED_BLINK; + leds.c = LED_GRN | LED_BLINK; + leds.d = LED_RED | LED_BLINK; } -void loop() +enum read_state { + S_DEFAULT, + S_LED, + S_BACKLIGHT +}; +enum read_state read_state; + +void handle_character(char c) { - if (Serial.available()) { - write(&term, Serial.read()); + switch (read_state) { + case S_DEFAULT: + switch (c) { + case '\x11': + read_state = S_LED; + break; + case '\x12': + read_state = S_BACKLIGHT; + break; + default: + write(&term, c); + break; + } + break; + + case S_LED: + switch (c & 0x30) { + case 0x00: leds.a = c & 0x0f; break; + case 0x10: leds.b = c & 0x0f; break; + case 0x20: leds.c = c & 0x0f; break; + case 0x30: leds.d = c & 0x0f; break; + } + read_state = S_DEFAULT; + break; + + case S_BACKLIGHT: + if (c == 0x02) + bl_flash(); + else + backlight.state = (enum backlight_state) c; + read_state = S_DEFAULT; + break; } } + +void loop() +{ + led_tasks(); + button_tasks(); + bl_tasks(); + + while (Serial.available()) + handle_character(Serial.read()); +} -- 2.20.1