LCD display with menues with rotary encoder

Hi! I have LCD 16x4 and rotary encoder (with a push button) hock to Arduino UNO.

I have taken two example and put them together but there is some issues, for instance is very unstable to get into the menus, also if I spin the rotary encoder more than I have cover I will not get values, is there something already done to be used here I don’t want to re invent the wheel, thanks for you help.

here is some code:

volatile int lastEncoded = 0;
volatile long encoderValue = 0;

long lastencoderValue = 0;

int lastMSB = 0;
int lastLSB = 0;

//var may not be needed
unsigned long timeSinceLastDisplay = 0;

void setup() {


  lcd.begin(16, 4);

   // print a welcome message
  lcd.clear();
  lcd.print("*** WELCOME! ***");
  lcd.setCursor(0,1);
  lcd.print("Initializing");

  
  
  
  //--------------encoder
  Serial.begin (9600);

  pinMode(encoderPin1, INPUT); 
  pinMode(encoderPin2, INPUT);
  
  pinMode(encoderSwitchPin, INPUT);

  digitalWrite(encoderPin1, HIGH); //turn pullup resistor on
  digitalWrite(encoderPin2, HIGH); //turn pullup resistor on
  
  digitalWrite(encoderSwitchPin, HIGH); //turn pullup resistor on

  attachInterrupt(0, updateEncoder, CHANGE); 
  attachInterrupt(1, updateEncoder, CHANGE);
  
}

void loop() {

  displayData();
  
  //----------encoder
    if(digitalRead(encoderSwitchPin)){
    //button is not being pushed
  }else{
    //button is being pushed
    Serial.println("We push the button");
  }

  Serial.println(encoderValue);
  delay(1000); //just here to slow down the output, and show it will work  even during a delay
}

void updateEncoder(){
  int MSB = digitalRead(encoderPin1); //MSB = most significant bit
  int LSB = digitalRead(encoderPin2); //LSB = least significant bit

  int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
  int sum  = (lastEncoded << 2) | encoded; //adding it to the previous encoded value

  if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
  if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;

  lastEncoded = encoded; //store this value for next time
}

void displayData() {
if (displayOk()) {
lcd.clear();
lcd.print("Main Menu:");
lcd.setCursor(1,1);
lcd.print("Option 1");
lcd.setCursor(1,2);
lcd.print("Option 2");


switch(encoderValue) {
case 0:
 // if (displayOk()) {
  lcd.setCursor(0,1);
lcd.write((uint8_t)126); //rigth arrow
lcd.setCursor(0,2);
lcd.write((uint8_t)165); //dot char
  break;
case 4:

  lcd.setCursor(0,2);
  lcd.write((uint8_t)126); //rigth arrow
  lcd.setCursor(0,1);
  lcd.write((uint8_t)165); //dot char

}

if(!digitalRead(encoderSwitchPin)){

    if (encoderValue == 0){
    Menu1();
    } else {
     Menu2(); 
    }
  
}  
  
}
}
boolean displayOk() {
unsigned long now = millis();
if (now - timeSinceLastDisplay >= 500) {
timeSinceLastDisplay = now;
return true;
} else return false;
}
 
 void Menu1() {
   
   while (1){
      if (displayOk()) {
     lcd.clear();
  lcd.print("Option 1 Menu");
  lcd.setCursor(1,1);
lcd.print("Option 3");
lcd.setCursor(1,2);
lcd.print("Return");
  switch(encoderValue) {
case 0:
  lcd.setCursor(0,1);
lcd.write((uint8_t)126); //rigth arrow
lcd.setCursor(0,2);
lcd.write((uint8_t)165); //dot char
  break;
case 4:
  lcd.setCursor(0,2);
  lcd.write((uint8_t)126); //rigth arrow
  lcd.setCursor(0,1);
  lcd.write((uint8_t)165); //dot char
}

  
  
  
  if(!digitalRead(encoderSwitchPin)){

       if (encoderValue == 0){
    Menu2();
    } else {
      encoderValue = 0;
     break; 
    }
}  
      }
   }
 } 
   
 
 void Menu2() {
   
   while (1){
      if (displayOk()) {
     lcd.clear();
  lcd.print("Option 2 Menu");
  if(!digitalRead(encoderSwitchPin)){
  break;
}  
   
  
  
      }
   }
 }

Hi

I also noticed, that dealing with encoders can be complicated. I put my thoughts on this page: Google Code Archive - Long-term storage for Google Code Project Hosting.. The software on this page is stable, but if rotation speed is to high, values get also lost.

Oliver