16x2 LCD Menu for Arduino
Introduction
I just want to share this beautiful LCD Menu implementation that you may use to your next Arduino project. The original code is for PIC microcontrollers, and just ported it for Arduino. My apologies to the original author of the source code, all credits goes to you, Sir.
Video Demonstration
Source Code
1#include "LiquidCrystal.h"
2
3LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
4
5// Definitions:
6#define DISPLAY_ROWS 2
7#define PER_SPACE 1
8
9#define KEYPAD_ROWS 4
10#define KEYPAD_COLS 4
11
12// Pin assignments:
13#define LCD_BACKLIGHT_PIN 10
14#define LED_PIN 11
15
16unsigned char selected = 1;
17unsigned char prev_key;
18byte lcd_brightness_val = 127;
19byte led_brightness_val = 127;
20int led_fadeAmount = 5;
21bool isLcdBacklit = true;
22bool isKeyDisabled = false;
23bool isSetLCDBrightnessMode = false;
24bool isSetLEDBrightnessMode = false;
25bool isLEDEnableMode = false;
26bool led_state = false;
27bool isBlinkLED = false;
28bool isFadeLED = false;
29
30char buttonPressed = '0';
31char lastButtonState = '0';
32unsigned long lastDebounceTime = 0;
33unsigned long debounceDelay = 100;
34
35// ####################################
36unsigned long checkButtonTaskTimer = 0;
37const unsigned long checkButtonTaskInterval = 300;
38unsigned long updateLCDTaskTimer = 0;
39const unsigned long updateLCDTaskInterval = 400;
40
41unsigned long blinkLEDTaskTimer = 0;
42const unsigned long blinkLEDTaskInterval = 500;
43
44typedef const struct MenuStructure
45{
46 const char *text;
47 unsigned char num_menupoints;
48 unsigned char up;
49 unsigned char down;
50 unsigned char enter;
51 void (*fp) (void);
52} MenuEntry;
53
54const char menu_000[] = " LCD Menu: "; // 0
55const char menu_001[] = " LED Control "; // 1
56const char menu_002[] = " LCD Control "; // 2
57const char menu_003[] = " Messages "; // 3
58const char menu_004[] = " Option4 "; // 4
59const char menu_005[] = " Option5 "; // 5
60const char menu_006[] = " Option6 "; // 6
61const char menu_007[] = " Option7 "; // 7
62const char menu_008[] = " Option8 "; // 8
63const char menu_009[] = " start "; // 9
64
65const char menu_100[] = " LED Control: "; // 10
66const char menu_101[] = " LED Enable "; // 11
67const char menu_102[] = " Blinking "; // 12
68const char menu_103[] = " Brightness "; // 13
69const char menu_104[] = " Fading "; // 14
70const char menu_105[] = " Return "; // 15
71
72const char menu_200[] = " LCD Control: "; // 16
73const char menu_201[] = " Backlight "; // 17
74const char menu_202[] = " Brightness "; // 18
75const char menu_203[] = " Return "; // 19
76
77const char menu_300[] = " Messages: "; // 20
78const char menu_301[] = " Write "; // 21
79const char menu_302[] = " Inbox "; // 22
80const char menu_303[] = " Outbox "; // 23
81const char menu_304[] = " Return "; // 24
82
83void start(void);
84void LED_light();
85void LED_blink();
86void LED_brightness();
87void LED_fade();
88void LCD_backlight();
89void LCD_brightness();
90void show_menu(void);
91void checkButton();
92
93MenuEntry menu[] =
94{
95 // text, num_menupoints, up, down, enter, *fp
96 {menu_000, 10, 0, 0, 0, 0}, // 0
97 {menu_001, 10, 1, 2, 11, 0}, // 1
98 {menu_002, 10, 1, 3, 17, 0}, // 2
99 {menu_003, 10, 2, 4, 21, 0}, // 3
100 {menu_004, 10, 3, 5, 4, 0}, // 4
101 {menu_005, 10, 4, 6, 5, 0}, // 5
102 {menu_006, 10, 5, 7, 6, 0}, // 6
103 {menu_007, 10, 6, 8, 7, 0}, // 7
104 {menu_008, 10, 7, 9, 8, 0}, // 8
105 {menu_009, 10, 8, 9, 1, start}, // 9
106
107 {menu_100, 6, 0, 0, 0, 0}, // 10
108 {menu_101, 6, 11, 12, 11, LED_light}, // 11
109 {menu_102, 6, 11, 13, 12, LED_blink}, // 12
110 {menu_103, 6, 12, 14, 13, LED_brightness}, // 13
111 {menu_104, 6, 13, 15, 14, LED_fade}, // 14
112 {menu_105, 6, 14, 15, 1, 0}, // 15
113
114 {menu_200, 4, 0, 0, 0, 0}, // 16
115 {menu_201, 4, 17, 18, 17, LCD_backlight}, // 17
116 {menu_202, 4, 17, 19, 18, LCD_brightness}, // 18
117 {menu_203, 4, 18, 19, 2, 0}, // 19
118
119 {menu_300, 5, 0, 0, 0, 0}, // 20
120 {menu_301, 5, 21, 22, 21, 0}, // 21
121 {menu_302, 5, 21, 23, 22, 0}, // 22
122 {menu_303, 5, 22, 24, 23, 0}, // 23
123 {menu_304, 5, 23, 24, 3, 0} // 24
124
125};
126
127void setup() {
128 // put your set code here, to run once:
129 lcd.clear();
130 lcd.begin(16, 2);
131 pinMode(LCD_BACKLIGHT_PIN, OUTPUT);
132 pinMode(LED_PIN, OUTPUT);
133 analogWrite(LCD_BACKLIGHT_PIN, lcd_brightness_val);
134 digitalWrite(LED_PIN, led_state);
135 pinMode(13, OUTPUT);
136 Serial.begin(9600);
137 show_menu();
138 Serial.println("Setup DONE");
139}
140
141void loop() {
142 if(millis() >= checkButtonTaskTimer + checkButtonTaskInterval){
143 checkButtonTaskTimer += checkButtonTaskInterval;
144 // do the task
145 checkButton();
146 }
147
148 if(millis() >= updateLCDTaskTimer + updateLCDTaskInterval){
149 updateLCDTaskTimer += updateLCDTaskInterval;
150 // do the task
151 //show_menu();
152 }
153
154 if ( (isBlinkLED) ) {
155 if(millis() >= blinkLEDTaskTimer + blinkLEDTaskInterval){
156 blinkLEDTaskTimer += blinkLEDTaskInterval;
157 // do the task
158 if (led_state) {
159 led_state = false;
160 } else {
161 led_state = true;
162 }
163 digitalWrite(LED_PIN, led_state);
164 }
165 }
166
167 if (isFadeLED) {
168 // change the brightness for next time through the loop:
169 led_brightness_val = led_brightness_val + led_fadeAmount;
170 // reverse the direction of the fading at the ends of the fade:
171 if (led_brightness_val <= 0 || led_brightness_val >= 255) {
172 led_fadeAmount = -led_fadeAmount;
173 }
174 analogWrite(LED_PIN, led_brightness_val);
175 }
176}
177
178void start() {
179 lcd.setCursor(0, 0);
180 lcd.print(" ");
181 lcd.setCursor(0, 0);
182 lcd.print("start works!");
183 digitalWrite(LED_PIN, HIGH);
184 delay(1000);
185 digitalWrite(LED_PIN, LOW);
186}
187
188void LED_light() {
189 isLEDEnableMode = true;
190
191 if (led_state) {
192 led_state = false;
193 } else {
194 led_state = true;
195 }
196 digitalWrite(LED_PIN, led_state);
197}
198
199void LED_blink() {
200 if (isBlinkLED) {
201 isBlinkLED = false;
202 } else {
203 isBlinkLED = true;
204 }
205}
206
207void LED_brightness() {
208 show_led_brightness();
209 isKeyDisabled = true;
210 isSetLEDBrightnessMode = true;
211}
212
213void LED_fade() {
214 if (isFadeLED) {
215 isFadeLED = false;
216 } else {
217 isFadeLED = true;
218 }
219}
220
221void LCD_backlight() {
222 if (isLcdBacklit) {
223 analogWrite(LCD_BACKLIGHT_PIN,0);
224 isLcdBacklit = false;
225 } else {
226 lcd_brightness_val = 255;
227 analogWrite(LCD_BACKLIGHT_PIN,lcd_brightness_val);
228 isLcdBacklit = true;
229 }
230}
231
232void LCD_brightness() {
233
234 show_lcd_brightness();
235 isLcdBacklit = true;
236 isKeyDisabled = true;
237 isSetLCDBrightnessMode = true;
238}
239
240void show_menu(void)
241{
242 unsigned char line_cnt = 0;
243 unsigned char from = 0;
244 unsigned char till = 0;
245 unsigned char temp = 0;
246 while (till <= selected)
247 {
248 till += menu[till].num_menupoints;
249 }
250 from = till - menu[selected].num_menupoints;
251 till--;
252 temp = from;
253 // browsing somewhere in the middle
254 if ((selected >= (from+PER_SPACE)) && (selected <= till ))
255 {
256 from = selected-PER_SPACE;
257 till = from + (DISPLAY_ROWS-1);
258 for (from; from<=till; from++)
259 {
260 lcd.setCursor(0, line_cnt);
261 lcd.print(menu[from].text);
262 line_cnt = line_cnt + 1;
263 }
264 }
265
266 // browsing somewhere in the top or the bottom
267 else
268 {
269 // top of the menu
270 if (selected < (from+PER_SPACE)) // 2 lines
271 {
272 //till = from + 3;
273 till = from + (DISPLAY_ROWS-1); // 2 lines
274 for (from; from<=till; from++)
275 {
276 lcd.setCursor(0, line_cnt);
277 lcd.print(menu[from].text);
278 line_cnt = line_cnt + 1;
279 }
280 }
281
282 // bottom of the menu
283 if (selected == till)
284 {
285 from = till - (DISPLAY_ROWS-1); // 2 lines
286
287 for (from; from<=till; from++)
288 {
289 lcd.setCursor(0, line_cnt);
290 lcd.print(menu[from].text);
291 line_cnt = line_cnt + 1;
292 }
293 }
294 }
295 lcd.setCursor(0, 2);
296 lcd.print(">");
297}
298
299void checkButton() {
300 int x = analogRead (0);
301
302 if (x < 50) {
303 buttonPressed = 'R';
304 } else if (x < 150) {
305 buttonPressed = 'U';
306 } else if (x < 300){
307 buttonPressed = 'D';
308 } else if (x < 450){
309 buttonPressed = 'L';
310 } else if (x < 700){
311 buttonPressed = 'S';
312 } else {
313 buttonPressed = '0';
314 }
315 processButton(buttonPressed);
316}
317
318void processButton(char buttonPressed) {
319 switch ( buttonPressed ) {
320 case 'R':
321 if (isKeyDisabled) {
322 } else {
323 if (menu[selected].fp != 0)
324 {
325 menu[selected].fp();
326 }
327 prev_key = selected;
328 selected = menu[selected].enter;
329 show_menu();
330 }
331 break;
332 case 'U': // U
333 if (isKeyDisabled) {
334 if (isSetLCDBrightnessMode) {
335 lcd_brightness_val = lcd_brightness_val + 10;
336 analogWrite(LCD_BACKLIGHT_PIN,lcd_brightness_val);
337 show_lcd_brightness();
338 } else if (isSetLEDBrightnessMode) {
339 led_brightness_val = led_brightness_val + 10;
340 analogWrite(LED_PIN,led_brightness_val);
341 show_led_brightness();
342 }
343 } else {
344 prev_key = selected;
345 selected = menu[selected].up;
346 show_menu();
347 }
348 break;
349 case 'D': // D
350 if (isKeyDisabled) {
351 if (isSetLCDBrightnessMode) {
352 lcd_brightness_val = lcd_brightness_val - 10;
353 analogWrite(LCD_BACKLIGHT_PIN,lcd_brightness_val);
354 show_lcd_brightness();
355 } else if (isSetLEDBrightnessMode) {
356 led_brightness_val = led_brightness_val - 10;
357 analogWrite(LED_PIN,led_brightness_val);
358 show_led_brightness();
359 }
360 } else {
361 prev_key = selected;
362 selected = menu[selected].down;
363 show_menu();
364 }
365 break;
366 case 'L': // L
367 if (isKeyDisabled) {
368 isKeyDisabled = false;
369 isSetLCDBrightnessMode = false;
370 hide_lcd_brightness();
371 isSetLEDBrightnessMode = false;
372 hide_led_brightness();
373 }
374 show_menu();
375 break;
376 case 'S': // S
377 show_menu();
378 break;
379 default:
380 break;
381 }
382}
383
384void show_lcd_brightness() {
385 lcd.setCursor(12,1);
386 float temp = (float) lcd_brightness_val / 255 * 100;
387 if (temp < 10) {
388 lcd.print(": ");
389 lcd.print(temp);
390 } else if (temp < 100) {
391 lcd.print(": ");
392 lcd.print(temp);
393 } else {
394 lcd.print(":");
395 lcd.print(temp);
396 }
397}
398
399void hide_lcd_brightness() {
400 lcd.setCursor(12,1);
401 lcd.print(" ");
402}
403
404void show_led_brightness() {
405 lcd.setCursor(12,1);
406 float temp = (float) led_brightness_val / 255 * 100;
407 if (temp < 10) {
408 lcd.print(": ");
409 lcd.print(temp);
410 } else if (temp < 100) {
411 lcd.print(": ");
412 lcd.print(temp);
413 } else {
414 lcd.print(":");
415 lcd.print(temp);
416 }
417}
418
419void hide_led_brightness() {
420 lcd.setCursor(12,1);
421 lcd.print(" ");
422}
Call To Action
If you have any question, please leave it in the comment box. Thank you and have a good day.
Posts in this series
- How to Get Started with ATTiny85 in Arduino IDE
- Tutorial: How to use MFRC522 RFID module using Arduino
- SOS Flasher Using Millis Function with Enable Switch
- Tutorial: How to use DS3231 RTC in Arduino
- Tutorial: How to use 0.96 OLED - a small and cute display
- Tutorial: Getting Started with the NRF24L01 | How to use | Arduino
- Tutorial: How to use SIM800L GSM Module for Controlling Anything | Arduino
- Tutorial: How to use Keypad | Text Entry Mode | Arduino
- Tutorial: How to use 4x4 Keypad | Arduino
- Project Idea: Arduino Voltmeter
- Project Idea: Door Lock Security | Arduino
- Multitasking with Arduino | Relay Timer Controller | using millis
- Tutorial Understanding Blink Without Delay | How to millis
- Arduino Simple LCD Menu
- How to use SIM800L GSM Module using Arduino | Make or Answer Voice Calls
- Tutorial: How to Use Arduino Uno as HID | Part 2: Arduino Mouse Emulation
- Tutorial: How to Use Arduino Uno as HID | Part 1: Arduino Keyboard Emulation
- Tutorial: How to use SIM800L DTMF to Control Anything | Arduino
- Tutorial: Arduino EEPROM
- How to use SIM800L GSM Module | Arduino | Send and Receive SMS
- Tutorial: Arduino GPIO | How to use Arduino Pins
- MIT App Inventor for Arduino
- RC Car using L298N, HC-06, and Arduino Uno
- How to Use LCD Keypad Shield for Arduino
- How to Use Arduino Interrupts
- Project: Automatic Alcohol Dispenser
- TUTORIAL: How to use HC-SR04 Ultrasonic Sensor with Arduino
- Source Code: Astronomia Meme and Funeral Dance | melodies the Arduino way
- How to Get Started with L293D Motor Driver Shield with Arduino
- How to Get Started with L298N Motor Driver module using Arduino
- Part 2: Wav Music Player with Lyrics Using Arduino and SD Card
- Interfacing Infrared to Arduino Uno
- Part 1: Wav Music Player Using Arduino Uno and SD Card
- How to Interface Stepper Motor to Arduino Uno
- How To Play MP3 Files on Arduino from SD Card
- What is Arduino Software Serial
- How to Interface SD card to Arduino (without SD card shield)?
- Playing Melodies Using Arduino
- 8 Degrees Of Freedom (DOF) Robot Using Arduino Uno
- How to Interface PS2 Controller to Arduino Uno
- Part 3: DF Player Mini Tinkering with Arduino Nano and LCD
- How to Interface HC-06 to Arduino
- How to make a Remote Control RC car using Arduino and HC-06 bluetooth module
- Part 2: DF Player Mini Tinkering with Arduino Nano
- Part 1: DF Player Mini - a mini cheap mp3 player
No comments yet!