//LCD Graphical User Interface Using Buttons
// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
// define some values used by the panel and buttons
int lcd_key = 0;
int adc_key_in = 0;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
byte dt = 250;
//*********************rotary encoder***************
const unsigned int ROTARY_ENC_PIN_A = 2;
const unsigned int ROTARY_ENC_PIN_B = 3;
const unsigned int ROTARY_ENC_SWITCH = A5;
#define NO_CHANGE 0
#define TURN_CW 1
#define TURN_CCW 2
//Direction ┌─ ccw ─┐ N ┌─ cw ─┐
//Index 0 1 2 3 4 5 6 7 8
byte aState[] = {3, 2, 0, 1, 3, 2, 0, 1, 3};
byte lastState = 3;
volatile int count = 0;
unsigned int index = 4;
volatile byte encoderStatus = NO_CHANGE;
void readEncoderStatus() {
byte A_Output = digitalRead(ROTARY_ENC_PIN_A);
byte B_Output = digitalRead(ROTARY_ENC_PIN_B);
byte currState = (A_Output * 2) + B_Output;
if (currState != lastState) {
if (currState == aState[index + 1]) {
index++;
if (index == 8) {
count++;
index = 4;
encoderStatus = TURN_CW;
}
}
else if (currState == aState[index - 1]) {
index--;
if (index == 0) {
count--;
index = 4;
encoderStatus = TURN_CCW;
}
}
lastState = currState;
}
}
//********************read lcd buttons**************************
// read the buttons
int read_LCD_buttons()//read buttons function
{
adc_key_in = analogRead(A0); // read the value from the sensor
// buttons when read are: 0, 100, 257, 410, 640
//add approx 50 to values and check to see if close
if (adc_key_in > 1000) return btnNONE;
// start with btnNONE so code moves faster
//since this will be normal state
//these ranges have to be in order (low to high)or (high to low)
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 150) return btnUP;
if (adc_key_in < 300) return btnDOWN;
if (adc_key_in < 460) return btnLEFT;
if (adc_key_in < 670) return btnSELECT;
return btnNONE; // return btnNONE when no buttons pressed
}
//set the pins of the LEDS
const byte LEDS[] = {10, 11, 12, 13, 15};
//set pin states
boolean LED_1_State = LOW;
boolean LED_2_State = LOW;
boolean LED_3_State = LOW;
boolean LED_4_State = LOW;
boolean LED_5_State = LOW;
//this variable adjusts the horizontl location of the cursor
int Cursor_Position_Horizontal = 1;
int Cursor_Position_Vertical = 0;
void setup() {
//*************************read rotary switch*********************
attachInterrupt(digitalPinToInterrupt(ROTARY_ENC_PIN_A), readEncoderStatus, CHANGE);
attachInterrupt(digitalPinToInterrupt(ROTARY_ENC_PIN_B), readEncoderStatus, CHANGE);
pinMode(ROTARY_ENC_SWITCH, INPUT_PULLUP);
//*******************read lcd buttons***************************
//set up serial communication
Serial.begin(9600);
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("[1][2][3][4][5]"); lcd.setCursor(0, 1);
lcd.print("[ON]");
lcd.setCursor(11, 1);
lcd.print("[OFF]");
//start the cursor on selection 1
lcd.setCursor(Cursor_Position_Horizontal, Cursor_Position_Vertical);
//Make the Cursor visible
lcd.cursor();
//blink the cursor block
lcd.blink();
//set the modes of all pins
for (int i = 0; i < 5; i++) {
pinMode(LEDS[i], OUTPUT);
}
}//close setup
void loop() {
Serial.println(adc_key_in);
//********************read encoder***************************
if (encoderStatus != NO_CHANGE) {
int tempCount;
noInterrupts();
tempCount = count;
interrupts();
Serial.print(encoderStatus == TURN_CW ? "CW " : "CCW ");
Serial.println(tempCount); // Use the saved variable
lcd.setCursor(4, 1);
lcd.print(" ");
lcd.setCursor(4, 1);
lcd.print(encoderStatus == TURN_CW ? "CW" : "CCW");
lcd.print(tempCount);
encoderStatus = NO_CHANGE;
}
/*********** Rotary Encoder Switch **************/
if (!digitalRead(ROTARY_ENC_SWITCH)) {
count = 0;
lcd.setCursor(4, 1);
lcd.print(" ");
//debounce switch press
delay(5);
while (!digitalRead(ROTARY_ENC_SWITCH));
delay(5);
}
//*******************read lcd buttons*********************
/* Serial.print("which button ");
Serial.print(read_LCD_buttons());
Serial.print(" analog: ");
Serial.println(adc_key_in);
*/
lcd_key = read_LCD_buttons(); // read the buttons
//set the cursor position
lcd.setCursor(Cursor_Position_Horizontal, Cursor_Position_Vertical);
//Scroll Cursor LEFT if the button is pressed
//if the cursor is already, all the way left - do nothing
if ((read_LCD_buttons() == 3) && (Cursor_Position_Horizontal != 1) && (Cursor_Position_Vertical == 0) ) {
Cursor_Position_Horizontal -= 3;
delay(dt);
}//close SCROLL LEFT if
else if ((read_LCD_buttons() == 3) && (Cursor_Position_Horizontal != 1) && (Cursor_Position_Vertical == 1) ) {
Cursor_Position_Horizontal -= 12;
delay(dt);
}//close SCROLL LEFT if
//Scroll Cursor RIGHT if the button is pressed
//if the cursor is all the way right - do nothing
if ((read_LCD_buttons() == 0) && (Cursor_Position_Horizontal != 13) && (Cursor_Position_Vertical == 0)) {
Cursor_Position_Horizontal += 3;
delay(dt);
}//close SCROLL RIGHT if
if ((read_LCD_buttons() == 0) && (Cursor_Position_Horizontal != 13) && (Cursor_Position_Vertical == 1)) {
Cursor_Position_Horizontal += 12;
delay(dt);
}//close SCROLL RIGHT if
//Scroll Cursor UP if the button is pressed
//if the cursor is already, all the way up - do nothing
if ((read_LCD_buttons() == 1) && (Cursor_Position_Vertical != 0) ) {
Cursor_Position_Vertical -= 1;
delay(dt);
}//close SCROLL UP if
//Scroll Cursor DOWN if the button is pressed
//if the cursor is already, all the way DOWN - do nothing
if ((read_LCD_buttons() == 2) && (Cursor_Position_Horizontal < 7) && (Cursor_Position_Vertical != 1)) {
Cursor_Position_Horizontal = 1;
Cursor_Position_Vertical += 1;
delay(dt);
}//close DOWN if
else if ((read_LCD_buttons() == 2) && (Cursor_Position_Horizontal > 6) && (Cursor_Position_Vertical != 1)) {
Cursor_Position_Horizontal = 13;
Cursor_Position_Vertical += 1;
delay(dt);
}//close else DOWN if
switch (Cursor_Position_Horizontal) {
case 1: //this is the first option
//if the select button is pressed we will switch the state of the LED
if ( (read_LCD_buttons() == 4) && (Cursor_Position_Vertical == 0)) {
//switch the state of the LED
LED_1_State = !LED_1_State;
//This delay is an easy way to debounce the button press
delay(dt);
//turn the LED either ON or OFF
digitalWrite(LEDS[0], LED_1_State);
}//close if
else if ( (read_LCD_buttons() == 4) && (Cursor_Position_Vertical == 1)) {
for (int i = 0; i < 5; i++) {
digitalWrite(LEDS[i], HIGH);
}
}
break;
case 4:
//if the select button is pressed we will switch the state of the LED
if ( (read_LCD_buttons() == 4) && (Cursor_Position_Vertical == 0)) {
//switch the state of the LED
LED_2_State = !LED_2_State;
//This delay is an easy way to debounce the button press
delay(dt);
//turn the LED either ON or OFF
digitalWrite(LEDS[1], LED_2_State);
}//close if
break;
case 7: //this is the first option
//if the select button is pressed we will switch the state of the LED
if ( (read_LCD_buttons() == 4) && (Cursor_Position_Vertical == 0)) {
//switch the state of the LED
LED_3_State = !LED_3_State;
//This delay is an easy way to debounce the button press
delay(dt);
//turn the LED either ON or OFF
digitalWrite(LEDS[2], LED_3_State);
}//close if
break;
case 10: //this is the first option
//if the select button is pressed we will switch the state of the LED
if ( (read_LCD_buttons() == 4) && (Cursor_Position_Vertical == 0)) {
//switch the state of the LED
LED_4_State = !LED_4_State;
//This delay is an easy way to debounce the button press
delay(dt);
//turn the LED either ON or OFF
digitalWrite(LEDS[3], LED_4_State);
}//close if
break;
case 13: //this is the first option
//if the select button is pressed we will switch the state of the LED
if ( (read_LCD_buttons() == 4) && (Cursor_Position_Vertical == 0)) {
//switch the state of the LED
LED_5_State = !LED_5_State;
//This delay is an easy way to debounce the button press
delay(dt);
//turn the LED either ON or OFF
//digitalWrite(LEDS[4], LED_5_State);
}//close if
else if ( (read_LCD_buttons() == 4) && (Cursor_Position_Vertical == 1)) {
for (int i = 0; i < 5; i++) {
digitalWrite(LEDS[i], LOW);
}
delay(dt);
}//close else if
break;
}//close switch case
}//close loop