//16x2 LCD
#include <LiquidCrystal_I2C.h> //SDA = A4, SCL = A5
LiquidCrystal_I2C lcd(0x27, 16, 2);
//Defining pins for rotary encoder
const int RotaryCLK = 2; //CLK pin on the rotary encoder
const int RotaryDT = 4; //DT pin on the rotary encoder
const int RotarySW = 3; //SW pin on the rotary encoder (Button function)
//Defining variables for rotary encoder and button
int ButtonCounter = 0; //counts the button clicks
int RotateCounter = 0; //counts the rotation clicks
int Rotatesubcounter = 0;
bool rotated = true; //info of the rotation
bool ButtonPressed = false; //info of the button
//Statuses
int CLKNow;
int CLKPrevious;
int DTNow;
int DTPrevious;
//-----------------------User definitions------------------
bool Menu = true ;
bool SubMenu = false ;
bool RotateFlag = false;
bool flag = true;
// Timers
float TimeNow1;
float TimeNow2;
//------------------------------
//Define the LCD Arrow (-->)
uint8_t arrow[8] = {0x00, 0x04 ,0x06, 0x1f, 0x06, 0x04, 0x00};
enum pages{root_menu,submenu,return_back};
enum selected_menu{no_menu_selected,menu1,menu2,menu3,menu4};
enum selected_submenu{no_submenu_selected,submenu1,submenu2,back};
enum selected_menu menu_x = no_menu_selected;
enum selected_submenu submenu_x = no_submenu_selected;
enum pages current_page = root_menu;
void setup()
{
//Serial.begin(9600); //we don't use the serial in this example
//------------------------------------------------------
lcd.init(); // initialize the lcd
lcd.backlight();
//------------------------------------------------------
lcd.setCursor(0,0);
lcd.print("ElectroWave");
delay(500);
lcd.clear();
delay(1000); //wait 3 sec
//------------------------------------------------------
//setting up pins
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
pinMode(4, INPUT_PULLUP);
//Create the Arrrow for LCD (-->)
lcd.createChar(0, arrow);
//Store states
CLKPrevious = digitalRead(RotaryCLK);
DTPrevious = digitalRead(RotaryDT);
attachInterrupt(digitalPinToInterrupt(RotaryCLK), rotate, CHANGE);
attachInterrupt(digitalPinToInterrupt(RotarySW), buttonPressed, FALLING); //either falling or rising but never "change".
TimeNow1 = millis(); //Start timer 1
}
void loop()
{
switch(current_page)
{
case root_menu: root_menu_func(); break;
case submenu1: SUBMENU_1(); break;
case return_back: current_page=root_menu; break;
}
}
void root_menu_func()
{
if(rotated == true) //refresh the CLK
{
switch(RotateCounter)
{
//------------------------------------------Menu_1---------------------------------------------------
case 0: //Menu 0 case
screen_0();
menu_x=menu1;
break; //Break Menu 0 --> case 0
//------------------------------------------Menu_2---------------------------------------------------
case 1:
screen_1();
break;
//------------------------------------------Menu_3---------------------------------------------------
case 2:
screen_2();
break;
//------------------------------------------Menu_4---------------------------------------------------
case 3:
screen_3();
break;
}
}
//ButtonPressed = false; //reset this variable
}
void submenu1_func()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.write(0);
lcd.setCursor(1,0);
lcd.print("xxxxxxxxxxxxxxxxxxxxxx");
}
void which_menu_is_selected(selected_menu menu_x,selected_submenu submenu_x)
{
if (menu_x == menu1 && submenu_x == no_submenu_selected)
{
SUBMENU_1();
}
else if (menu_x == menu1 && submenu_x == back)
{
root_menu_func();
}
else
{
lcd.clear();
lcd.setCursor(0,0);
lcd.write(0);
lcd.setCursor(1,0);
lcd.print("xxxx34566xxxxxxxx");
}
}
void buttonPressed()
{
if(menu_x == menu1)
{
current_page=submenu;
}
if(submenu_x == back)
{
current_page=return_back;
submenu_x =no_submenu_selected;
}
//This timer is a "software debounce". It is not the most effective solution, but it works
TimeNow2 = millis();
if(TimeNow2 - TimeNow1 > 500)
{
//ButtonPressed = true;
SubMenu = true;
}
TimeNow1 = millis(); //"reset" timer; the next 500 ms is counted from this moment
//which_menu_is_selected(menu_x,submenu_x);
}
void rotate()
{
CLKNow = digitalRead(RotaryCLK); //Read the state of the CLK pin
// If last and current state of CLK are different, then a pulse occurred
if (CLKNow != CLKPrevious && CLKNow == 1)
{
// If the DT state is different than the CLK state then
// the encoder is rotating CCW so increase
if ((digitalRead(RotaryDT) != CLKNow) && (Menu==true) )
{
RotateCounter++;
}
else
{
RotateCounter--;
}
if ((digitalRead(RotaryDT) != CLKNow) && (Menu==false) )
{
Rotatesubcounter++;
}
else
{
Rotatesubcounter--;
}
}
if(RotateCounter > 3 )
{
RotateCounter = 0;
}
if(RotateCounter < 0)
{
RotateCounter = 3;
}
if(Rotatesubcounter > 2 )
{
Rotatesubcounter = 0;
}
if(Rotatesubcounter < 0)
{
Rotatesubcounter = 2;
}
CLKPrevious = CLKNow; // Store last CLK state
rotated = true;
}
void MENU_ID()
{
if(rotated == true) //refresh the CLK
{
switch(RotateCounter)
{
//------------------------------------------Menu_1---------------------------------------------------
case 0: //Menu 0 case
screen_0();
menu_x=menu1;
break; //Break Menu 0 --> case 0
//------------------------------------------Menu_2---------------------------------------------------
case 1:
screen_1();
menu_x=menu2;
break;
//------------------------------------------Menu_3---------------------------------------------------
case 2:
screen_2();
break;
//------------------------------------------Menu_4---------------------------------------------------
case 3:
screen_3();
break;
}
}
//ButtonPressed = false; //reset this variable
}
void screen_0()
{
//lcd.clear();
lcd.setCursor(7,0);
lcd.print(" ");
lcd.setCursor(0,0); //Stat at the first row first column
lcd.write(0);
lcd.setCursor(1,0);
lcd.print("Menu 1");
lcd.setCursor(6,1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("Menu 2");
menu_x = menu1;
}
void screen_1()
{
//lcd.clear();
lcd.setCursor(6,0);
lcd.print(" ");
lcd.setCursor(0,0);
lcd.print("Menu 1");
lcd.setCursor(7,0);
lcd.print(" ");
lcd.setCursor(0,1); //Stat at the first row first column
lcd.write(0);
lcd.setCursor(1,1);
lcd.print("Menu 2");
menu_x = menu2;
}
void screen_2()
{
//lcd.clear();
lcd.setCursor(7,0);
lcd.print(" ");
lcd.setCursor(0,0); //Stat at the first row first column
lcd.write(0);
lcd.setCursor(1,0);
lcd.print("Menu 3");
lcd.setCursor(6,1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("Menu 4");
menu_x = menu3;
}
void screen_3()
{
//lcd.clear();
lcd.setCursor(6,0);
lcd.print(" ");
lcd.setCursor(0,0);
lcd.print("Menu 3");
lcd.setCursor(0,1); //Stat at the first row first column
lcd.write(0);
lcd.setCursor(7,0);
lcd.print(" ");
lcd.setCursor(1,1);
lcd.print("Menu 4");
menu_x = menu4;
}
//---------------------------SubMenu Void------------------------------
void subscreen_0()
{
//lcd.clear();
lcd.setCursor(0,0); //Stat at the first row first column
lcd.write(0);
lcd.setCursor(1,0);
lcd.print("SubMenu 1");
lcd.setCursor(0,1);
lcd.print("SubMenu 2");
submenu_x = submenu1;
}
void subscreen_1()
{
//lcd.clear();
lcd.setCursor(0,0);
lcd.print("SubMenu 1");
lcd.setCursor(0,1); //Stat at the first row first column
lcd.write(0);
lcd.setCursor(1,1);
lcd.print("SubMenu 2");
submenu_x = submenu2;
}
void subscreen_2()
{
lcd.clear();
lcd.setCursor(0,0); //Stat at the first row first column
lcd.write(0);
lcd.setCursor(1,0);
lcd.print("Back");
submenu_x = back;
}
void SUBMENU_1()
{
if (rotated==true)
{
switch(Rotatesubcounter)
{
//------------------------------------------Menu_1---------------------------------------------------
case 0: //Menu 0 case
subscreen_0();
break; //Break Menu 0 --> case 0
//------------------------------------------Menu_2---------------------------------------------------
case 1:
subscreen_1();
break;
//------------------------------------------Menu_3---------------------------------------------------
case 2:
subscreen_2();
break;
//------------------------------------------Menu_4---------------------------------------------------
}
}
}
void SUBMENU_2()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Submenu2");
delay(1000);
Menu = true ;
SubMenu = false ;
}