#include "LiquidCrystal_I2C.h"
LiquidCrystal_I2C lcd(0x27,20,4);
//DEFINE FOR OLED
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#define ROOT_MENU_CNT 3
#define SUB_MENU1_CNT 4
#define SUB_MENU2_CNT 5
#define SUB_MENU3_CNT 2
// setup the emum with all the menu pages options
enum pageType {ROOT_MENU, SUB_MENU1, SUB_MENU2, SUB_MENU3};
// holds which page is currently selected
enum pageType currPage = ROOT_MENU;
// selected item pointer for the root menu
uint8_t root_Pos = 1;
// constants holding port addresses
const int BTN_ACCEPT = A0;
const int BTN_UP = A2;
const int BTN_DOWN = A1;
const int BTN_CANCEL = A3;
// =======================================================================================
// || SETUP ||
// =======================================================================================
void setup() {
// Inițializarea ecranului OLED
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) {
display.println(F("Failed to initialize SSD1306 OLED!"));
for (;;); // Oprire dacă inițializarea nu reușește
}
// Curățarea ecranului la pornire
display.clearDisplay();
display.display();
lcd.init();
lcd.backlight();
// init the display port to be used as a display return
//display.begin(115200);
// setup the basic I/O's
pinMode(BTN_ACCEPT, INPUT_PULLUP);
pinMode(BTN_UP, INPUT_PULLUP);
pinMode(BTN_DOWN, INPUT_PULLUP);
pinMode(BTN_CANCEL, INPUT_PULLUP);
}
// =======================================================================================
// || MAIN LOOP ||
// =======================================================================================
void loop() {
display.setRotation(1);
switch (currPage){
case ROOT_MENU: page_RootMenu(); break;
case SUB_MENU1: page_SubMenu1(); break;
case SUB_MENU2: page_SubMenu2(); break;
case SUB_MENU3: page_SubMenu3(); break;
}
}
// =======================================================================================
// || PAGE - ROOT MENU ||
// =======================================================================================
void page_RootMenu(void) {
//flag for updating the display
boolean updateDisplay = true;
// tracks when entered top of loop
uint32_t loopStartMs;
//tracks button states
boolean btn_Up_WasDown = false;
boolean btn_Down_WasDown = false;
boolean btn_Accept_WasDown = false;
display.clearDisplay(); // Curățare ecran
display.setTextSize(1); // Dimensiune text
display.setTextColor(SSD1306_WHITE); // Culoare text
display.setCursor(0, 40); // Poziționare cursor
//inner loop
while (true){
// capture start time
loopStartMs = millis();
// print the display
if (updateDisplay){
// clear the update flag
updateDisplay = false;
//clear the display
clearScreen();
//menu title
lcd.println(F("MAIN MENU"));
//print a divider line
//printDivider();
// print the items
printSelected(1, root_Pos); lcd.println(F("SUB 1"));
printSelected(2, root_Pos); lcd.println(F("SUB 2"));
printSelected(3, root_Pos); lcd.println(F("SUB 3"));
printSelected(1, root_Pos); display.println(F("SUB 1"));
printSelected(2, root_Pos); display.println(F("SUB 2"));
printSelected(3, root_Pos); display.println(F("SUB 3"));
//lcd.println();
//lcd.println();
display.display();
delay(200);
//print a divider line
//printDivider();
}
// capture the button down states
if (btnIsDown(BTN_UP)) {btn_Up_WasDown = true;}
if (btnIsDown(BTN_DOWN)) {btn_Down_WasDown = true;}
if (btnIsDown(BTN_ACCEPT)) {btn_Accept_WasDown = true;}
//move the pointer down
if (btn_Down_WasDown && btnIsUp(BTN_DOWN)){
if (root_Pos == ROOT_MENU_CNT) {root_Pos = 1;} else {root_Pos++;}
updateDisplay = true;
btn_Down_WasDown = false;
}
//move the pointer Up
if (btn_Up_WasDown && btnIsUp(BTN_UP)){
if (root_Pos == 1) {root_Pos = ROOT_MENU_CNT;} else {root_Pos--;}
updateDisplay = true;
btn_Up_WasDown = false;
}
//move to the selected page
if (btn_Accept_WasDown && btnIsUp(BTN_ACCEPT)){
switch (root_Pos) {
case 1: currPage = SUB_MENU1; return;
case 2: currPage = SUB_MENU2; return;
case 3: currPage = SUB_MENU3; return;
}
}
// keep a specific pace
while (millis() - loopStartMs < 25) {delay(2);}
}
}
// =======================================================================================
// || PAGE - SUB MENU1 ||
// =======================================================================================
void page_SubMenu1(void) {
//flag for updating the display
boolean updateDisplay = true;
// tracks when entered top of loop
uint32_t loopStartMs;
//tracks button states
boolean btn_Up_WasDown = false;
boolean btn_Down_WasDown = false;
boolean btn_Cancel_WasDown = false;
// selected item pointer
uint8_t sub_Pos = 1;
//inner loop
while (true){
// capture start time
loopStartMs = millis();
// print the display
if (updateDisplay){
// clear the update flag
updateDisplay = false;
//clear the display
clearScreen();
//menu title
display.print(F("SUB MENU 1\n"));
//print a divider line
//printDivider();
// print the items
printSelected(1, sub_Pos); display.print(F("1Item\n"));
printSelected(2, sub_Pos); display.print(F("2Item\n"));
//print a divider line
//printDivider();
}
// capture the button down states
if (btnIsDown(BTN_UP)) {btn_Up_WasDown = true;}
if (btnIsDown(BTN_DOWN)) {btn_Down_WasDown = true;}
if (btnIsDown(BTN_CANCEL)) {btn_Cancel_WasDown = true;}
//move the pointer down
if (btn_Down_WasDown && btnIsUp(BTN_DOWN)){
if (sub_Pos == SUB_MENU1_CNT) {sub_Pos = 1;} else {sub_Pos++;}
updateDisplay = true;
btn_Down_WasDown = false;
}
//move the pointer Up
if (btn_Up_WasDown && btnIsUp(BTN_UP)){
if (sub_Pos == 1) {sub_Pos = SUB_MENU1_CNT;} else {sub_Pos--;}
updateDisplay = true;
btn_Up_WasDown = false;
}
//move to the go to the root menu
if (btn_Cancel_WasDown && btnIsUp(BTN_CANCEL)){currPage = ROOT_MENU; return;}
// keep a specific pace
while (millis() - loopStartMs < 25) {delay(2);}
}
}
// =======================================================================================
// || PAGE - SUB MENU2 ||
// =======================================================================================
void page_SubMenu2(void) {
//flag for updating the display
boolean updateDisplay = true;
// tracks when entered top of loop
uint32_t loopStartMs;
//tracks button states
boolean btn_Up_WasDown = false;
boolean btn_Down_WasDown = false;
boolean btn_Cancel_WasDown = false;
// selected item pointer
uint8_t sub_Pos = 1;
//inner loop
while (true){
// capture start time
loopStartMs = millis();
// print the display
if (updateDisplay){
// clear the update flag
updateDisplay = false;
//clear the display
clearScreen();
//menu title
display.println(F("[ SUB MENU #2 ]"));
//print a divider line
printDivider();
// print the items
printSelected(1, sub_Pos); display.println(F("The First Item"));
printSelected(2, sub_Pos); display.println(F("The Second Item"));
printSelected(3, sub_Pos); display.println(F("The Third Item"));
printSelected(4, sub_Pos); display.println(F("The Forth Item"));
printSelected(5, sub_Pos); display.println(F("The Fifth Item"));
//print a divider line
printDivider();
}
// capture the button down states
if (btnIsDown(BTN_UP)) {btn_Up_WasDown = true;}
if (btnIsDown(BTN_DOWN)) {btn_Down_WasDown = true;}
if (btnIsDown(BTN_CANCEL)) {btn_Cancel_WasDown = true;}
//move the pointer down
if (btn_Down_WasDown && btnIsUp(BTN_DOWN)){
if (sub_Pos == SUB_MENU2_CNT) {sub_Pos = 1;} else {sub_Pos++;}
updateDisplay = true;
btn_Down_WasDown = false;
}
//move the pointer Up
if (btn_Up_WasDown && btnIsUp(BTN_UP)){
if (sub_Pos == 1) {sub_Pos = SUB_MENU2_CNT;} else {sub_Pos--;}
updateDisplay = true;
btn_Up_WasDown = false;
}
//move to the go to the root menu
if (btn_Cancel_WasDown && btnIsUp(BTN_CANCEL)){currPage = ROOT_MENU; return;}
// keep a specific pace
while (millis() - loopStartMs < 25) {delay(2);}
}
}
// =======================================================================================
// || PAGE - SUB MENU3 ||
// =======================================================================================
void page_SubMenu3(void) {
//flag for updating the display
boolean updateDisplay = true;
// tracks when entered top of loop
uint32_t loopStartMs;
//tracks button states
boolean btn_Up_WasDown = false;
boolean btn_Down_WasDown = false;
boolean btn_Cancel_WasDown = false;
// selected item pointer
uint8_t sub_Pos = 1;
//inner loop
while (true){
// capture start time
loopStartMs = millis();
// print the display
if (updateDisplay){
// clear the update flag
updateDisplay = false;
//clear the display
clearScreen();
//menu title
display.println(F("[ SUB MENU #3 ]"));
//print a divider line
printDivider();
// print the items
printSelected(1, sub_Pos); display.println(F("The First Item"));
printSelected(2, sub_Pos); display.println(F("The Second Item"));
//print a divider line
printDivider();
}
// capture the button down states
if (btnIsDown(BTN_UP)) {btn_Up_WasDown = true;}
if (btnIsDown(BTN_DOWN)) {btn_Down_WasDown = true;}
if (btnIsDown(BTN_CANCEL)) {btn_Cancel_WasDown = true;}
//move the pointer down
if (btn_Down_WasDown && btnIsUp(BTN_DOWN)){
if (sub_Pos == SUB_MENU3_CNT) {sub_Pos = 1;} else {sub_Pos++;}
updateDisplay = true;
btn_Down_WasDown = false;
}
//move the pointer Up
if (btn_Up_WasDown && btnIsUp(BTN_UP)){
if (sub_Pos == 1) {sub_Pos = SUB_MENU3_CNT;} else {sub_Pos--;}
updateDisplay = true;
btn_Up_WasDown = false;
}
//move to the go to the root menu
if (btn_Cancel_WasDown && btnIsUp(BTN_CANCEL)){currPage = ROOT_MENU; return;}
// keep a specific pace
while (millis() - loopStartMs < 25) {delay(2);}
}
}
// =======================================================================================
// || TOOLS - DISPLAY ||
// =======================================================================================
void printSelected(uint8_t p1, uint8_t p2){
if(p1 == p2){
display.print(F("-->"));
}
else {
display.print(F(" "));
}
}
void clearScreen(void){
for (uint8_t i = 0; i < 100; i++) {display.println();}
}
void printDivider(void){
for (uint8_t i = 0; i < 19; i++) {display.print("-");}
// lcd.println();
}
// =======================================================================================
// || TOOLS - BUTTON PRESSING ||
// =======================================================================================
boolean btnIsDown(int btn){
return digitalRead(btn) == LOW && digitalRead(btn) == LOW;
}
boolean btnIsUp(int btn){
return digitalRead(btn) == HIGH && digitalRead(btn) == HIGH;
}