643f2c2a5b9c48f7889480f28d38dae22b256d3f
[liquid-crystal-terminal.git] / terminal / terminal.ino
1 #include <LiquidCrystal.h>
2
3 LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
4
5 #define COLS 20
6 #define ROWS 4
7
8 /**
9 * Special characters.
10 * See https://www.quinapalus.com/hd44780udg.html to make more.
11 * Define which ones are used (max. 8) in setup().
12 * When they need to be changed at runtime, make sure the cursor is disabled
13 * and call setCursor afterwards.
14 */
15 byte char_music[8] = {0x02,0x03,0x02,0x0e,0x1e,0x0c,0x00};
16 byte char_bar_1[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x1f};
17 byte char_bar_2[8] = {0x00,0x00,0x00,0x00,0x00,0x1f,0x1f};
18 byte char_bar_3[8] = {0x00,0x00,0x00,0x00,0x1f,0x1f,0x1f};
19 byte char_bar_4[8] = {0x00,0x00,0x00,0x1f,0x1f,0x1f,0x1f};
20 byte char_bar_5[8] = {0x00,0x00,0x1f,0x1f,0x1f,0x1f,0x1f};
21 byte char_bar_6[8] = {0x00,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f};
22 byte char_bar_7[8] = {0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f};
23 byte char_hbar_start_empty[8] = {0x1f,0x10,0x10,0x10,0x10,0x10,0x1f};
24 byte char_hbar_start_full[8] = {0x1f,0x10,0x17,0x17,0x17,0x10,0x1f};
25 byte char_hbar_inner_empty[8] = {0x1f,0x00,0x00,0x00,0x00,0x00,0x1f};
26 byte char_hbar_inner_half[8] = {0x1f,0x00,0x1c,0x1c,0x1c,0x00,0x1f};
27 byte char_hbar_inner_full[8] = {0x1f,0x00,0x1f,0x1f,0x1f,0x00,0x1f};
28 byte char_hbar_end_empty[8] = {0x1f,0x01,0x01,0x01,0x01,0x01,0x1f};
29 byte char_hbar_end_full[8] = {0x1f,0x01,0x1d,0x1d,0x1d,0x01,0x1f};
30
31 struct terminal {
32 byte x;
33 byte y;
34 char contents[COLS * ROWS];
35 };
36
37 void redraw(struct terminal *term)
38 {
39 lcd.noCursor();
40 lcd.clear();
41 lcd.home();
42 for (byte i = 0; i < COLS * ROWS; i++) {
43 if (i % COLS == 0)
44 lcd.setCursor(i % COLS, i / COLS);
45 lcd.write(term->contents[i]);
46 }
47 lcd.cursor();
48 }
49
50 void scroll_up(struct terminal *term)
51 {
52 for (byte i = 0; i < COLS * (ROWS - 1); i++)
53 term->contents[i] = term->contents[i + COLS];
54 for (byte i = COLS * (ROWS - 1); i < COLS * ROWS; i++)
55 term->contents[i] = ' ';
56 redraw(term);
57 }
58
59 /**
60 * Special character meanings are defined here.
61 */
62 void write(struct terminal *term, char ch)
63 {
64 switch (ch) {
65 case '\r':
66 term->x = 0;
67 lcd.setCursor(term->x, term->y);
68 break;
69 case '\n':
70 if (++term->y >= ROWS) {
71 term->y--;
72 scroll_up(term);
73 }
74 lcd.setCursor(term->x, term->y);
75 break;
76 case 0x7f:
77 if (term->x != 0) {
78 term->x--;
79 term->contents[term->x + term->y * COLS] = 0x00;
80 lcd.setCursor(term->x, term->y);
81 lcd.write(' ');
82 lcd.setCursor(term->x, term->y);
83 }
84 break;
85 default:
86 term->contents[term->x + term->y * COLS] = ch;
87 lcd.write(ch);
88 if (++term->x >= COLS) {
89 term->x = 0;
90 if (++term->y >= ROWS) {
91 term->y--;
92 scroll_up(term);
93 }
94 lcd.setCursor(term->x, term->y);
95 }
96 }
97 }
98
99 struct terminal term;
100
101 char message[] =
102 "Beste Mart, van\r\n"
103 "harte gefeliciteerd!"
104 "Hier een herprogram-"
105 "meerbare terminal. ";
106
107 void setup()
108 {
109 lcd.createChar(0, char_music);
110 lcd.createChar(1, char_hbar_start_full);
111 lcd.createChar(2, char_hbar_start_empty);
112 lcd.createChar(3, char_hbar_inner_full);
113 lcd.createChar(4, char_hbar_inner_half);
114 lcd.createChar(5, char_hbar_inner_empty);
115 lcd.createChar(6, char_hbar_end_full);
116 lcd.createChar(7, char_hbar_end_empty);
117
118 lcd.begin(COLS, ROWS);
119 lcd.blink();
120 Serial.begin(9600);
121
122 for (byte i = 0; i < ROWS * COLS; i++)
123 term.contents[i] = ' ';
124
125 for (byte i = 0; i < sizeof(message) - 1; i++)
126 write(&term, message[i]);
127 }
128
129 void loop()
130 {
131 if (Serial.available()) {
132 write(&term, Serial.read());
133 }
134 }