//LCD config
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4); //sometimes the LCD adress is not 0x3f. Change to 0x27 if it dosn't work.
uint8_t arrow[8] = {0x0, 0x04 ,0x06, 0x1f, 0x06, 0x04, 0x00, 0x00};
//Variables for the menu encoder
int counter = 0;
int page=1;
int Ready=1;
int submenu=0;
int last_counter = 0;
bool clk_State;
bool Last_State;
bool dt_State;
int pushed = 0;
//The pin for the push button
#define push 10
void setup()
{
pinMode (push,INPUT); //Define the pin as input
lcd.init(); //Init the LCD
lcd.backlight(); //Activate backlight
lcd.createChar(1, arrow); //Create the arrow symbol
lcd.home(); //Home the LCD
PCICR |= (1 << PCIE0); //enable PCMSK0 scan
PCMSK0 |= (1 << PCINT0); //Set pin D8 trigger an interrupt on state change.
PCMSK0 |= (1 << PCINT1); //Set pin D9 trigger an interrupt on state change.
DDRB &= B11111100; //8, 9 as input for the encoder clock and data pins
Last_State = (PINB & B00000001); //pin 8 state (clock pin)?
//Prepare the DFplayer module comunication and settings
Serial.begin(115200);
//Print the initial text. Delete these lines if you don't want that
lcd.clear();
lcd.setCursor(0,0);
lcd.write(0);
lcd.print(" ARCELIK ");
lcd.write(0);
lcd.setCursor(0,1);
lcd.print(" ELEKTRONIK MTY ");
delay(2000);
//Print the first page menu.
lcd.clear();
lcd.setCursor(0,0);
lcd.write(1);
lcd.print("ACI KONTROLU");
lcd.setCursor(0,1);
lcd.print(" PARAMETRE GIRISI");
}
void loop() {
if((last_counter > counter) || (last_counter < counter) || pushed) //Only print on the LCD when a step is detected or the button is pushed.
{
Ready=1;
//Menü ilk sayfası
if(submenu == 0)
{
if(0 <= counter && counter < 5)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.write(1);
lcd.print("ACI KONTROLU");
lcd.setCursor(0,1);
lcd.print(" PARAMETRE GIRISI");
page=1;
pushed=0;
}
if(5 < counter && counter < 10)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" ACI KONTROLU");
lcd.setCursor(0,1);
lcd.write(1);
lcd.print("PARAMETRE GIRISI");
page=2;
pushed=0;
}
if(10 < counter && counter < 15)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.write(1);
lcd.print("BASLAT");
page=3;
pushed=0;
}
}//submenu = 0;
//menü ikinci sayfası
if(submenu == 1)
{
if(0 <= counter && counter < 5)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.write(1);
lcd.print("Latte");
lcd.setCursor(0,1);
lcd.print(" Cappuccino");
page=1;
pushed=0;
}
if(5 < counter && counter < 10)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" Latte");
lcd.setCursor(0,1);
lcd.write(1);
lcd.print("Cappuccino");
page=2;
pushed=0;
}
if(10 < counter && counter < 15)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.write(1);
lcd.print("Americano");
lcd.setCursor(0,1);
lcd.print(" Back");
page=3;
pushed=0;
}
}//submenu = 1
}//end of the MENU prints on the LCD
last_counter = counter; //Save the value of the last state
//Now we detect when we push the button
if(digitalRead(push))
{
if(submenu == 1)
{
if(page==1)
{
submenu=0;
counter=1;
pushed=0;
Ready=0;
lcd.clear();
lcd.setCursor(0,0);
lcd.write(1);
lcd.print("ILERI");
lcd.setCursor(0,1);
lcd.print(" GERI");
delay(10000);
}
if(page==2)
{
submenu=0;
counter=0;
pushed=0;
Ready=0;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("DENEME");
lcd.setCursor(0,1);
lcd.print(" Wait ");
delay(10000);
}
if(page==3)
{
submenu=0;
counter=0;
pushed=0;
Ready=0;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Making coffee...");
lcd.setCursor(0,1);
lcd.print(" Wait ");
delay(10000);
}
if(page==4)
{
submenu=0;
counter=0;
pushed=0;
Ready=0;
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" Going back... ");
lcd.setCursor(0,1);
lcd.print(" Wait ");
delay(10000);;
}
}//end of submenu 1
if(submenu == 0 && Ready==1)
{
if(page==1)
{
submenu=1;
counter=0;
pushed=1;
delay(500);
}
if(page==2)
{
submenu=2;
counter=0;
pushed=1;delay(500);
}
if(page==3)
{
submenu=3;
counter=0;
pushed=1;delay(500);
}
}//end of submenu 0
}
//Add limit for the counter. Each line of the menu has 5 points. Since my menu has 4 lines the maximum counter will be from 0 to 20
//If you add more lines for the menu, increase this value
if(counter > 15)
{
counter=15;
}
if(counter < 0)
{
counter=0;
}
}//end void
//Interruption vector
ISR(PCINT0_vect){
clk_State = (PINB & B00000001); //pin 8 state, clock pin?
dt_State = (PINB & B00000010);
if (clk_State != Last_State){
// If the data state is different to the clock state, that means the encoder is rotating clockwise
if (dt_State != clk_State) {
counter ++;
}
else {
counter --;
}
}
Last_State = clk_State; // Updates the previous state of the data with the current state
}