#include "LiquidCrystal_I2C.h"
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);
// Pin assignments for digital push buttons
#define BUTTON_ENTER 2
#define BUTTON_UP 3
#define BUTTON_DOWN 4
#define BUTTON_LEFT 5
// Definitions:
#define DISPLAY_ROWS 2
#define PER_SPACE 1
#define KEYPAD_ROWS 4
#define KEYPAD_COLS 4
unsigned char selected = 1;
unsigned char prev_key;
bool isKeyDisabled = false;
char buttonPressed = '0';
char lastButtonState = '0';
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 100;
// ####################################
unsigned long checkButtonTaskTimer = 0;
const unsigned long checkButtonTaskInterval = 300;
unsigned long updateLCDTaskTimer = 0;
const unsigned long updateLCDTaskInterval = 400;
typedef const struct MenuStructure
{
const char *text;
unsigned char num_menupoints;
unsigned char up;
unsigned char down;
unsigned char enter;
void (*fp) (void);
} MenuEntry;
void start(void);
void show_menu(void);
void checkButton();
const char menu_000[] = " Settings: "; // 0
const char menu_001[] = " Set Area "; // 1
const char menu_002[] = " Set Date "; // 2
const char menu_003[] = " Set Time "; // 3
const char menu_004[] = " FactoryReset"; // 4
const char menu_100[] = " Set Area: "; // 5
const char menu_101[] = " Rectangle "; // 6
const char menu_102[] = " Circle "; // 7
const char menu_103[] = " Return "; // 8
const char menu_104[] = " In mm.. "; // 9
const char menu_105[] = " Length "; // 10
const char menu_106[] = " Bredth "; // 11
const char menu_107[] = " Return "; // 12
const char menu_108[] = " In mm.. "; // 13
const char menu_109[] = " Diameter "; // 14
const char menu_110[] = " Return "; // 15
MenuEntry menu[] =
{
// text, num_menupoints, up, down, enter, *fp
{menu_000, 5, 0, 0, 0, 0}, // 0
{menu_001, 5, 1, 2, 6, 0}, // 1
{menu_002, 5, 1, 3, 2, 0}, // 2
{menu_003, 5, 2, 4, 3, 0}, // 3
{menu_004, 5, 3, 4, 4, 0}, // 4
{menu_100, 4, 0, 0, 0, 0}, // 5
{menu_101, 4, 6, 7, 10, 0}, // 6
{menu_102, 4, 6, 8, 14, 0}, // 7
{menu_103, 4, 7, 8, 1, 0}, // 8
{menu_104, 4, 0, 0, 0, 0}, // 9
{menu_105, 4, 10, 11, 10, 0}, // 10
{menu_106, 4, 10, 12, 11, 0}, // 11
{menu_107, 4, 11, 12, 6, 0}, // 12
{menu_108, 3, 0, 0, 0, 0}, // 13
{menu_109, 3, 14, 15, 14, 0}, // 14
{menu_110, 3, 14, 15, 6, 0}, // 15
};
void setup() {
// put your set code here, to run once:
lcd.clear();
lcd.begin(16, 2);
pinMode(BUTTON_ENTER, INPUT_PULLUP);
pinMode(BUTTON_UP, INPUT_PULLUP);
pinMode(BUTTON_DOWN, INPUT_PULLUP);
pinMode(BUTTON_LEFT, INPUT_PULLUP);
Serial.begin(9600);
show_menu();
Serial.println("Setup DONE");
}
void loop() {
if(millis() >= checkButtonTaskTimer + checkButtonTaskInterval){
checkButtonTaskTimer += checkButtonTaskInterval;
// do the task
checkButton();
}
if(millis() >= updateLCDTaskTimer + updateLCDTaskInterval){
updateLCDTaskTimer += updateLCDTaskInterval;
// do the task
show_menu();
}
}
void show_menu(void)
{
unsigned char line_cnt = 0;
unsigned char from = 0;
unsigned char till = 0;
unsigned char temp = 0;
while (till <= selected)
{
till += menu[till].num_menupoints;
}
from = till - menu[selected].num_menupoints;
till--;
temp = from;
// browsing somewhere in the middle
if ((selected >= (from+PER_SPACE)) && (selected <= till ))
{
from = selected-PER_SPACE;
till = from + (DISPLAY_ROWS-1);
for (from; from<=till; from++)
{
lcd.setCursor(0, line_cnt);
lcd.print(menu[from].text);
line_cnt = line_cnt + 1;
}
}
// browsing somewhere in the top or the bottom
else
{
// top of the menu
if (selected < (from+PER_SPACE)) // 2 lines
{
//till = from + 3;
till = from + (DISPLAY_ROWS-1); // 2 lines
for (from; from<=till; from++)
{
lcd.setCursor(0, line_cnt);
lcd.print(menu[from].text);
line_cnt = line_cnt + 1;
}
}
// bottom of the menu
if (selected == till)
{
from = till - (DISPLAY_ROWS-1); // 2 lines
for (from; from<=till; from++)
{
lcd.setCursor(0, line_cnt);
lcd.print(menu[from].text);
line_cnt = line_cnt + 1;
}
}
}
lcd.setCursor(0, selected - from);
lcd.print(">");
}
void checkButton() {
// Read the state of digital push buttons
int buttonEnterState = digitalRead(BUTTON_ENTER);
int buttonUpState = digitalRead(BUTTON_UP);
int buttonDownState = digitalRead(BUTTON_DOWN);
int buttonLeftState = digitalRead(BUTTON_LEFT);
// Determine which button is pressed based on the state
if (buttonEnterState == LOW) {
buttonPressed = 'E';
} else if (buttonUpState == LOW) {
buttonPressed = 'U';
} else if (buttonDownState == LOW) {
buttonPressed = 'D';
} else if (buttonLeftState == LOW) {
buttonPressed = 'L';
} else {
buttonPressed = '0';
}
processButton(buttonPressed);
}
void processButton(char buttonPressed) {
switch ( buttonPressed ) {
case 'E':
if (isKeyDisabled) {
} else {
if (menu[selected].fp != 0)
{
menu[selected].fp();
}
prev_key = selected;
selected = menu[selected].enter;
show_menu();
}
break;
case 'U': // U
if (isKeyDisabled) {
} else {
prev_key = selected;
selected = menu[selected].up;
show_menu();
}
break;
case 'D': // D
if (isKeyDisabled) {
} else {
prev_key = selected;
selected = menu[selected].down;
show_menu();
}
break;
case 'L': // L
if (isKeyDisabled) {
isKeyDisabled = false;
}
show_menu();
break;
default:
break;
}
}
nano:12
nano:11
nano:10
nano:9
nano:8
nano:7
nano:6
nano:5
nano:4
nano:3
nano:2
nano:GND.2
nano:RESET.2
nano:0
nano:1
nano:13
nano:3.3V
nano:AREF
nano:A0
nano:A1
nano:A2
nano:A3
nano:A4
nano:A5
nano:A6
nano:A7
nano:5V
nano:RESET
nano:GND.1
nano:VIN
nano:12.2
nano:5V.2
nano:13.2
nano:11.2
nano:RESET.3
nano:GND.3
lcd1:GND
lcd1:VCC
lcd1:SDA
lcd1:SCL
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
btn2:1.l
btn2:2.l
btn2:1.r
btn2:2.r
btn3:1.l
btn3:2.l
btn3:1.r
btn3:2.r
btn4:1.l
btn4:2.l
btn4:1.r
btn4:2.r
led1:A
led1:C
r1:1
r1:2