#include "LiquidCrystal_I2C.h"
#include <Wire.h>
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 20, 4);
// Pin assignments for digital push buttons
#define BUTTON_ENTER 16
#define BUTTON_UP 17
#define BUTTON_DOWN 5
#define BUTTON_LEFT 18
// Definitions:
#define DISPLAY_ROWS 4
#define PER_SPACE 3
#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[] = " Factory Reset"; // 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.init();
lcd.backlight();
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;
// Calculate the 'till' position
while (till <= selected) {
till += menu[till].num_menupoints;
}
from = till - menu[selected].num_menupoints;
till--;
// Adjust 'from' and 'till' to fit the display window
if ((selected >= (from + PER_SPACE)) && (selected <= till)) {
from = selected - PER_SPACE;
till = from + (DISPLAY_ROWS - 1);
} else if (selected < (from + PER_SPACE)) {
till = from + (DISPLAY_ROWS - 1);
} else if (selected == till) {
from = till - (DISPLAY_ROWS - 1);
}
// Clear previous display
// lcd.clear();
// Display the menu items in the current window
for (unsigned char i = from; i <= till; i++) {
lcd.setCursor(0, line_cnt);
lcd.print(menu[i].text);
line_cnt++;
}
// Highlight the selected item
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;
}
}