#include <Encoder.h>
#include <LiquidCrystal_I2C.h>
/*defining encoder pins */
#define encCLK 2
#define encDT 3
#define encSW 4
/*******************User variables******************************/
int scrollStepCount=4; //number of minimum encoder pulses to do one scroll. Increase for a slower response
int sysStatus=0; //system status variable. 0=stopped, 1=connected, 2=running
//String Array of program names
String progNames[4]={"ID_MS_PEAK_01","ID_SS_PEAK_02","ID_MP_PEAK_01", "ID_SP_PEAK_01"};
int endPosX=200, endPosY=250, endPosZ=300; //default X,Y,Z end position values
/***************************************************************/
Encoder myEnc(encCLK, encDT); //defining the encoder instance
LiquidCrystal_I2C lcd(0x27,20,4); //defining the 20x4 LCD at adress 0x27
long oldPosition = 0;//position of encoder before scrolling
int scrollUp=0, scrollDown=0, click=0; //variables used for encoder functions
int screenNum=1, screenIndex=0; //screenNum is the number of the active screen, screenIndex is the pointer location in the screen
int editX=0, editY=0, editZ=0; //variables to allow edit permissions to X,Y,Z endpoint values
String selectedProgName=""; int selectedProgIndex=-1;
String line1="";
unsigned long scrollStartTime=0;
void setup() {
lcd.init();// initialize the lcd
lcd.backlight();
pinMode(encSW, INPUT_PULLUP);
Serial.begin(9600);
}
void loop() {
getPosition(); //calling position function to read the encoder
/*calling functions to display each screen based on "screen Number" variable.
ScreenNum is updated in the program, and it keeps track of the active screen*/
if(screenNum==1) E1();
if(screenNum==2) E2();
if(screenNum==3) E3();
if(screenNum==4) E4Start();
if(screenNum==5) E4Adjust();
}
/******Function for Screen 1(E1) - Home screen *******/
void E1(){
/*creating the first line to be displayed */
lcd.setCursor(0,0);lcd.print("Status: "); //prefix for displaying status
if(sysStatus==0) lcd.print("Stopped"); //displaying status according to sysStatus variable
else if(sysStatus==1) lcd.print("Connected");
else if(sysStatus==2) lcd.print("Executing");
/*displaying the second line on LCD, for entering program selection menu*/
lcd.setCursor(0,1);
lcd.print("> ");
lcd.print("Select program");
/*action on encoder button click is defined here */
if(click) {
screenNum=2;//setting the next screen number to 2
lcd.clear();
click=0;
}
}
/******Function for Screen 2(E2) - Program selection screen *******/
void E2(){
lcd.setCursor(0,0); lcd.print("Select Program");//displaying the heading line
/*Displaying first 3 programs */
if(screenIndex<=3){
lcd.setCursor(1,1); lcd.print(progNames[0]);
lcd.setCursor(1,2); lcd.print(progNames[1]);
lcd.setCursor(1,3); lcd.print(progNames[2]);
}
/*Displaying fithe nextrst 3 programs */
else if(screenIndex==4){
lcd.setCursor(1,1); lcd.print(progNames[1]);
lcd.setCursor(1,2); lcd.print(progNames[2]);
lcd.setCursor(1,3); lcd.print(progNames[3]);
}
/*Displaying last 2 programs and Back button*/
else if(screenIndex==5){
lcd.setCursor(1,1); lcd.print(progNames[2]);
lcd.setCursor(1,2); lcd.print(progNames[3]);
lcd.setCursor(1,3); lcd.print("Back");
}
/*Displaying the menu pointer */
if(screenIndex<1) screenIndex=1; //limiting screen index to 1, avoiding it reaching the first line(heading)
if(screenIndex<=3) lcd.setCursor(0,screenIndex); //placing pointer at correct program location
else if(screenIndex>3) lcd.setCursor(0,3); //placing the pointer on back button if reached last row
lcd.print(">"); //displaying the pointer
/*encoder button click event */
if(click) {
if(screenIndex<=4){
selectedProgName= progNames[screenIndex-1];
selectedProgIndex= screenIndex-1;
screenNum=3;
}
else if(screenIndex==5) screenNum=1;
lcd.clear();
click=0;
screenIndex=0;
}
/*encoder screoll up event */
if(scrollUp) {
if(screenIndex<5) screenIndex++;
lcd.clear();
scrollUp=0;
}
/*encoder scroll down event */
if(scrollDown) {
if(screenIndex>0) screenIndex--;
lcd.clear();
scrollDown=0;
}
}
/******Function for Screen 3(E3) - Program action selection screen *******/
void E3(){
lcd.setCursor(0,0); lcd.print("Prog: "); lcd.print(progNames[selectedProgIndex]);
lcd.setCursor(1,1); lcd.print("Start Program");
lcd.setCursor(1,2); lcd.print("Adjust program");
lcd.setCursor(1,3); lcd.print("Back");
if(screenIndex==0) screenIndex=1;
lcd.setCursor(0,screenIndex); lcd.print(">");
if(click) {
if(screenIndex==1) { //start program
screenNum=4;
sysStatus=2;
}
else if(screenIndex==2) screenNum=5; //adjust program
else if(screenIndex==3) screenNum=2; //back
lcd.clear();
click=0;
screenIndex=0;
line1= " End positions for " + progNames[selectedProgIndex] + " ";
scrollStartTime=millis();
}
if(scrollUp) {
if(screenIndex<3) screenIndex++;
lcd.clear();
scrollUp=0;
}
if(scrollDown) {
if(screenIndex>0) screenIndex--;
lcd.clear();
scrollDown=0;
}
}
/******Function for Screen 4(E4Start) - Program start screen *******/
void E4Start(){
lcd.setCursor(0,0); lcd.print("Prog: "); lcd.print(progNames[selectedProgIndex]);
lcd.setCursor(0,1);lcd.print("Status: ");
if(sysStatus==0) lcd.print("Stopped");
else if(sysStatus==1) lcd.print("Connected");
else if(sysStatus==2) lcd.print("Executing");
lcd.setCursor(1,2);lcd.print("Exit");
lcd.setCursor(1,3);lcd.print("Back");
if(screenIndex<2) screenIndex=2;
lcd.setCursor(0,screenIndex); lcd.print(">");
if(click) {
if(screenIndex==2) sysStatus=0;
else if(screenIndex==3) screenNum=3;
screenIndex=0;
lcd.clear();
click=0;
}
if(scrollUp) {
if(screenIndex<3) screenIndex++;
lcd.clear();
scrollUp=0;
}
if(scrollDown) {
if(screenIndex>0) screenIndex--;
lcd.clear();
scrollDown=0;
}
}
/******Function for Screen 5(E4Adjust) - Program Adjust screen *******/
void E4Adjust(){
String line1_20ch=line1.substring(0,20);
if(millis()-scrollStartTime >= 400) {
char tempChar=line1[0];
line1.remove(0,1);
line1+=tempChar;
line1_20ch=line1.substring(0,20);
scrollStartTime=millis();
}
lcd.setCursor(0,0); lcd.print(line1_20ch);
if(screenIndex<4){
lcd.setCursor(1,1); lcd.print("X: "); lcd.print(endPosX);
lcd.setCursor(1,2); lcd.print("Y: "); lcd.print(endPosY);
lcd.setCursor(1,3); lcd.print("Z: "); lcd.print(endPosZ);
}
else if(screenIndex>=4){
lcd.setCursor(1,1); lcd.print("Y: "); lcd.print(endPosY);
lcd.setCursor(1,2); lcd.print("Z: "); lcd.print(endPosZ);
lcd.setCursor(1,3); lcd.print("Back");
}
if(screenIndex<1) screenIndex=1;
if(screenIndex<=3) lcd.setCursor(0,screenIndex);
else lcd.setCursor(0,3);
lcd.print(">");
if(click) {
if(screenIndex==1 ) editX= !editX;
else if(screenIndex==2 ) editY= !editY;
else if(screenIndex==3) editZ= !editZ;
else if(screenIndex==4) {
screenNum=3;
screenIndex=0;
editX=0;
editY=0;
editZ=0;
}
delay(10);
lcd.clear();
click=0;
}
if(scrollUp) {
if(editX) endPosX--;
else if(editY) endPosY--;
else if(editZ) endPosZ--;
else if(screenIndex<4) screenIndex++;
lcd.clear();
scrollUp=0;
}
if(scrollDown) {
if(editX) endPosX++;
else if(editY) endPosY++;
else if(editZ) endPosZ++;
else if(screenIndex>1) screenIndex--;
lcd.clear();
scrollDown=0;
}
}
/******Function for reading the encoder *******/
void getPosition(){
long newPosition = myEnc.read(); //reading the current encoder position
if ((newPosition - oldPosition>=scrollStepCount)&& (screenNum !=1)) { //detecting a downward scroll
oldPosition = newPosition;
scrollDown=1; //setting the scroll down flag bit
}
if ((newPosition - oldPosition<=-scrollStepCount) && (screenNum !=1)) { //detecting an upward scroll
oldPosition = newPosition;
scrollUp=1; //setting the scroll up flag bit
}
if(digitalRead(encSW)==0) { //detecting the click on encoder button
click=1; //setting up the click flag bit
while(digitalRead(encSW)==0) delay(50); //debouncing delay for encoder button
}
}