/*
I2C LCD + 로터리엔코더를 활용해서 메뉴를 만드는 예제 입니다.
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Versatile_RotaryEncoder.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // 0x27 주소를 가진 16x2 사이즈 LCD
int menu = 0; // switch문에서 쓰일 변수
const int clk = 2; // nano D2
const int dt = 3; // nano D3
const int sw = 4; // nano D4
void handleRotate(int8_t rotation);
void handlePress();
void handlePressRelease();
Versatile_RotaryEncoder *versatile_encoder;
int count = 0;
void setup()
{
Serial.begin(9600);
lcd.init(); // worki 에서는 이걸 쓰세요
//lcd.begin(); // LCD 초기화 , 실제 회뢰에서 이걸 쓰세요
lcd.backlight(); // LCD 백라이트 켜기
lcd.blink();
// 아래 4줄의 코드를 안 적으면 lcd 초기화면이 비어있어서 부득이하게 넣었습니다.
lcd.setCursor(0, 0);
lcd.print(">Menu 1");
lcd.setCursor(1, 1);
lcd.print("Menu 2");
initRotoryEncoder(); // 로터리 엔코더 관련 SETUP 초기화 함수
delay(500);
}
void loop()
{
if (versatile_encoder->ReadEncoder())
{
updateMenu();
}
}
void updateMenu()
{
switch (menu)
{
case 0:
menu = 1;
break;
case 1:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(">Menu 1");
lcd.setCursor(1, 1);
lcd.print("Menu 2");
break;
case 2:
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("Menu 1");
lcd.setCursor(0, 1);
lcd.print(">Menu 2");
break;
case 3:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(">Menu 3");
lcd.setCursor(1, 1);
lcd.print("Menu 4");
break;
case 4:
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("Menu 3");
lcd.setCursor(0, 1);
lcd.print(">Menu 4");
break;
case 5:
menu = 4;
break;
default:
break;
}
}
void executeAction()
{
switch(menu)
{
case 1:
action1(); //별도 함수로 빼도 되기도 하고 직접코드를 넣어도 됩니다.
break;
case 2:
action2();
break;
case 3:
action3();
break;
case 4:
action4();
break;
}
}
void action1() // delay 만큼 구성을 보여주고 다시 메뉴 선택화면을 넘어갑니다.
{
lcd.clear();
lcd.print(">Executing #1");
delay(2000);
}
void action2()
{
lcd.clear();
lcd.print(">Executing #2");
delay(2000);
}
void action3()
{
lcd.clear();
lcd.print(">Executing #3");
delay(2000);
}
void action4()
{
lcd.clear();
lcd.print(">Executing #4");
delay(2000);
}
// Implement your functions here accordingly to your needs
void initRotoryEncoder() // setup이 복잡해서 따로 빼놨습니다.
{
versatile_encoder = new Versatile_RotaryEncoder(clk, dt, sw);
versatile_encoder->setHandleRotate(handleRotate);
versatile_encoder->setHandlePress(handlePress);
versatile_encoder->setHandlePressRelease(handlePressRelease);
Serial.println("RotoryEncoder is Ready!");
}
void handleRotate(int8_t rotation)
{
Serial.print("#1 Rotated: ");
if (rotation > 0)
{
Serial.println("Right");
menu++;
}
else
{
Serial.println("Left");
menu--;
}
}
void handlePress()
{
Serial.println("#4.1 Pressed");
executeAction();
}
void handlePressRelease()
{
Serial.println("#5 Press released");
executeAction();
}