Ok, so i have managed to get my rotary encoder with my lcd to work and for testing purposes i am trying to get it to do the following:
1/ When I turn the rotary CW the count increments from 0 - 10.
2/ When I turn the rotary CCW the count decriments from 10 - 0.
3/ When I push the rotary button thhe LED 0n 13 ligts up for 1 second and resets the count to 0.
The problem i am having is this:
When the count reaches 10, and I turn the rotary CCW it leaves behind the unit "0" so it goes 10, 90, 80, 70, 60, 50, 40, 30, 20, 00.
I have been trying various ways to clear the screen if the count is 10 and going CCW but then the LCD starts flickering.
Any ideas anybody. I know this is rather a trivial project but the purpose of this is for me to get full control of the rotary actions for a future project which i have in mind.
#include <LiquidCrystal.h>
LiquidCrystal lcd (12, 11, 8, 9, 6, 7);
enum PinAssignments {
encoderPinA = 3, // right (labeled DT on our decoder, yellow wire)
encoderPinB = 2, // left (labeled CLK on our decoder, green wire)
clearButton = A0 // switch (labeled SW on our decoder, orange wire)
};
volatile int encoderPos = 0; // a counter for the dial
int lastReportedPos = 1; // change management
static boolean rotating = false; // debounce management
int UIstate = 0; //User state management
// interrupt service routine vars
boolean A_set = false;
boolean B_set = false;
void setup() {
pinMode(encoderPinA, INPUT_PULLUP); // new method of enabling pullups
pinMode(encoderPinB, INPUT_PULLUP);
pinMode(clearButton, INPUT_PULLUP);
// encoder pin on interrupt 0 (pin 2)
attachInterrupt(0, doEncoderA, CHANGE);
// encoder pin on interrupt 1 (pin 3)
attachInterrupt(1, doEncoderB, CHANGE);
lcd.begin(16, 2);
// Serial.begin(9600); // output
}
void loop()
{
UserInterface();
navigateMenu();
}
void navigateMenu()
{
//lcd.clear();
lcd.setCursor(0,0);
lcd.print("Index:");
switch (UIstate)
{
case 1:
if(UIstate == 1)
{
digitalWrite(13, HIGH); //ENTER PART using LED on 13 for testing purposes
delay(1000);
digitalWrite (13, LOW);
UIstate = 0;
lcd.setCursor(6,0);
lcd.print(encoderPos, DEC);
}
break;
case 2:
if (UIstate == 2)
{
lcd.setCursor(6,0);
lcd.print(encoderPos, DEC); //CW ROTATION print counter
}
break;
case 3:
if (UIstate == 3)
{
if (encoderPos <= 10)
{
lcd.setCursor(6,0);
lcd.print(encoderPos, DEC); //CCW ROTATION print counter
}
else if (encoderPos == 10)
{
lcd.clear();
lcd.setCursor(0,0);
// lcd.print("Index");
//// {
// lcd.setCursor(6,0);
// lcd.print(encoderPos, DEC);
// }
}
}
break;
}
}
void UserInterface()
{
rotating = true; // reset the debouncer
if (lastReportedPos != encoderPos)
{
lastReportedPos = encoderPos;
}
if (digitalRead(clearButton) == HIGH )
{
delay(20);
UIstate = 1;
encoderPos = 0; //When button is pressed reset counter to 0
}
}
void doEncoderA()
{
if ( rotating ) delay (1); //Wait a little until the bouncing is done
if ( digitalRead(encoderPinA) != A_set )
{
A_set = !A_set;
if (A_set && !B_set && encoderPos != 10)
{
encoderPos += 1;
UIstate = 2; //Increment by 1 clockwise
}
if ( A_set && !B_set && encoderPos == 10)
{
encoderPos = 10;
}
rotating = false; //No more debouncing until loop() hits again
}
}
void doEncoderB()
{
if ( rotating ) delay (1); //Wait a little until the bouncing is done
if ( digitalRead(encoderPinB) != B_set )
{
B_set = !B_set;
if ( !A_set && B_set && encoderPos != 0)
{
encoderPos -= 1;
UIstate = 3;
}
if (!A_set && B_set && encoderPos == 0)
{
encoderPos = 0;
}
rotating = false;
}
}