Switch within a loop

Hello,

I'm using a RTC module to get time and date and display it on a LCD keypad shield.

I've been building a menu, the following events occur when a button is pressed : Case upkey : display time and date Case downkey : does something else

When I press upkey, time and date display but do not refresh, it just freezes ! To have it refreshed, I have to go out and go back in this menu.

From what I understand, it doesn't refresh because it's within a switch. What can I do to make time refresh then ?

Thank you guys for helping me out !

Without seeing your code?

My bad, sorry, here’s my code :

#define DS1307_I2C_ADDRESS 0x68
#include <WProgram.h>
#include <Wire.h>
#include <DS1307.h>
#include <LiquidCrystal.h>
#include <stdio.h>



//Variables********************************************************************************************************************************************

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int second, minute, hour, dayOfWeek, dayOfMonth, month, year;

//Key message
int  adc_key_val[5] ={30, 150, 360, 535, 760 };
int NUM_KEYS = 5;
int adc_key_in;
int key=-1;
int oldkey=-1;

char sequenceMenu[4][17] = {"    Main menu   ", " White leds menu", " Blue leds menu", " Tank temp menu"};

#define rightKey 0
#define upKey 1
#define downKey 2
#define leftKey 3
#define selectKey 4

int General = 0;
int Menu = 0;


//Keypad functions **********************************************************************************************************************

// Convert ADC value to key number
int get_key(unsigned int input)
{
      int k;
    
      for (k = 0; k < NUM_KEYS; k++)
      {
            if (input < adc_key_val[k])
            {
           
    return k;
        }
      }
    
    if (k >= NUM_KEYS)
        k = -1;     // No valid key pressed
    
    return k;
}

void clearLine(int line)
{
lcd.setCursor(0,line);
lcd.print("                ");
lcd.setCursor(0,line);
}

//Date functions : set, get ********************************************************************************************************************************************

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

void setDateDs1307(int second, int minute, int hour, int dayOfWeek, int dayOfMonth, int month, int year)          
{
   Wire.beginTransmission(DS1307_I2C_ADDRESS);
   Wire.send(0);
   Wire.send(decToBcd(second));    // 0 to bit 7 starts the clock
   Wire.send(decToBcd(minute));
   Wire.send(decToBcd(hour));      // If you want 12 hour am/pm you need to set
                                   // bit 6 (also need to change readDateDs1307)
   Wire.send(decToBcd(dayOfWeek));
   Wire.send(decToBcd(dayOfMonth));
   Wire.send(decToBcd(month));
   Wire.send(decToBcd(year));
   Wire.send(0x10);
   Wire.endTransmission();
}

// Gets the date and time from the ds1307
void getDateDs1307()
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  // A few of these need masks because certain bits are control bits
  second     = bcdToDec(Wire.receive() & 0x7f);
  minute     = bcdToDec(Wire.receive());
  hour       = bcdToDec(Wire.receive() & 0x3f);  // Need to change this if 12 hour am/pm
  dayOfWeek  = bcdToDec(Wire.receive());
  dayOfMonth = bcdToDec(Wire.receive());
  month      = bcdToDec(Wire.receive());
  year       = bcdToDec(Wire.receive());
}


void displaydate() {
  lcd.setCursor(0, 0);
  if (dayOfMonth < 10) lcd.print("0");
  lcd.print(dayOfMonth);
  lcd.print("/");
  if (month < 10) lcd.print(0);
  lcd.print(month);
  lcd.print("/");
  if (year < 10) lcd.print("0");
  lcd.print(year);
  
  }
  
void displaytime() {  
  lcd.setCursor(0, 1);
  if (hour < 10) lcd.print("0");
  lcd.print(hour);
  lcd.print(":");
  if (minute < 10) lcd.print("0");
  lcd.print(minute);
  lcd.print(":");
  if (second < 10) lcd.print("0");
  lcd.print(second);
}
  

//Set up********************************************************************************************************************************************

void setup()
{
  char temp_string[10];
  char temp1_string[10];
  
  //initialize lcd
  lcd.begin(16, 2);
  lcd.clear();
  lcd.println("Reef Controller ");
  delay(5000);
  lcd.clear();
  delay(1000);
  
  //  
  Wire.begin();
  Serial.begin(9600);
  
}

//Loop********************************************************************************************************************************************

void loop()
{
  
//detect key press 
int key = 0;
adc_key_in = analogRead(0); // read the value from the sensor
key = get_key(adc_key_in); // convert into key press
if (key != oldkey) // if keypress is detected
{
delay(50); // wait for debounce time
adc_key_in = analogRead(0); // read the value from the sensor
key = get_key(adc_key_in); // convert into key press
if (key != oldkey)
{
oldkey = key;
if (key >=0)
{

switch (General){
  
case 0: // 1st level

switch(key){
case upKey:
break;

case downKey:
break;

case rightKey:
lcd.clear();
Menu--;
if (Menu<0)
{Menu = 3;}
lcd.setCursor(0, 0);
lcd.print(sequenceMenu[Menu]);
break;

case leftKey:
lcd.clear();
Menu++;
if (Menu>3)
{Menu = 0;}
lcd.setCursor(0, 0);
lcd.print(sequenceMenu[Menu]);

break;

case selectKey:
General++;
if (Menu == 0){
lcd.clear();
getDateDs1307();
displaydate();
displaytime();}
break;
}
break;

case 1: // 2nd level

switch(Menu) {

case 0: // 2nd level "Main"
lcd.clear();
getDateDs1307();
displaydate();
displaytime();
switch(key){

case upKey:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(sequenceMenu[0]);
General--;
break;

case downKey:
break;

case rightKey:
break;

case leftKey:
break;

case selectKey:
break;
}
break;

case 1: // 2nd level "White leds"

switch(key){

case upKey:
break;

case downKey:
break;

case rightKey:
break;

case leftKey:
break;

case selectKey:
break;

}
break;

case 2: // 2nd level "Blue led"

switch(key){

case upKey:
break;

case downKey:
break;

case rightKey:
break;

case leftKey:
break;

case selectKey:
break;
}
break;

case 3: // 2nd level "Tank temp"

switch(key){

case upKey:
break;

case downKey:
break;

case rightKey:
break;

case leftKey:
break;

case selectKey:
break;
}
break;

}
}
}
}
}
}

[\code]

Thanks in advance !

Again :

#define DS1307_I2C_ADDRESS 0x68
#include <WProgram.h>
#include <Wire.h>
#include <DS1307.h>
#include <LiquidCrystal.h>
#include <stdio.h>



//Variables********************************************************************************************************************************************

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int second, minute, hour, dayOfWeek, dayOfMonth, month, year;

//Key message
int  adc_key_val[5] ={30, 150, 360, 535, 760 };
int NUM_KEYS = 5;
int adc_key_in;
int key=-1;
int oldkey=-1;

char sequenceMenu[4][17] = {"    Main menu   ", " White leds menu", " Blue leds menu", " Tank temp menu"};

#define rightKey 0
#define upKey 1
#define downKey 2
#define leftKey 3
#define selectKey 4

int General = 0;
int Menu = 0;


//Keypad functions **********************************************************************************************************************

// Convert ADC value to key number
int get_key(unsigned int input)
{
      int k;
    
      for (k = 0; k < NUM_KEYS; k++)
      {
            if (input < adc_key_val[k])
            {
           
    return k;
        }
      }
    
    if (k >= NUM_KEYS)
        k = -1;     // No valid key pressed
    
    return k;
}

void clearLine(int line)
{
lcd.setCursor(0,line);
lcd.print("                ");
lcd.setCursor(0,line);
}

//Date functions : set, get ********************************************************************************************************************************************

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

void setDateDs1307(int second, int minute, int hour, int dayOfWeek, int dayOfMonth, int month, int year)          
{
   Wire.beginTransmission(DS1307_I2C_ADDRESS);
   Wire.send(0);
   Wire.send(decToBcd(second));    // 0 to bit 7 starts the clock
   Wire.send(decToBcd(minute));
   Wire.send(decToBcd(hour));      // If you want 12 hour am/pm you need to set
                                   // bit 6 (also need to change readDateDs1307)
   Wire.send(decToBcd(dayOfWeek));
   Wire.send(decToBcd(dayOfMonth));
   Wire.send(decToBcd(month));
   Wire.send(decToBcd(year));
   Wire.send(0x10);
   Wire.endTransmission();
}

// Gets the date and time from the ds1307
void getDateDs1307()
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  // A few of these need masks because certain bits are control bits
  second     = bcdToDec(Wire.receive() & 0x7f);
  minute     = bcdToDec(Wire.receive());
  hour       = bcdToDec(Wire.receive() & 0x3f);  // Need to change this if 12 hour am/pm
  dayOfWeek  = bcdToDec(Wire.receive());
  dayOfMonth = bcdToDec(Wire.receive());
  month      = bcdToDec(Wire.receive());
  year       = bcdToDec(Wire.receive());
}


void displaydate() {
  lcd.setCursor(0, 0);
  if (dayOfMonth < 10) lcd.print("0");
  lcd.print(dayOfMonth);
  lcd.print("/");
  if (month < 10) lcd.print(0);
  lcd.print(month);
  lcd.print("/");
  if (year < 10) lcd.print("0");
  lcd.print(year);
  
  }
  
void displaytime() {  
  lcd.setCursor(0, 1);
  if (hour < 10) lcd.print("0");
  lcd.print(hour);
  lcd.print(":");
  if (minute < 10) lcd.print("0");
  lcd.print(minute);
  lcd.print(":");
  if (second < 10) lcd.print("0");
  lcd.print(second);
}
  

//Set up********************************************************************************************************************************************

void setup()
{
  char temp_string[10];
  char temp1_string[10];
  
  //initialize lcd
  lcd.begin(16, 2);
  lcd.clear();
  lcd.println("Reef Controller ");
  delay(5000);
  lcd.clear();
  delay(1000);
  
  //  
  Wire.begin();
  Serial.begin(9600);
  
}

//Loop********************************************************************************************************************************************

void loop()
{
  
//detect key press 
int key = 0;
adc_key_in = analogRead(0); // read the value from the sensor
key = get_key(adc_key_in); // convert into key press
if (key != oldkey) // if keypress is detected
{
delay(50); // wait for debounce time
adc_key_in = analogRead(0); // read the value from the sensor
key = get_key(adc_key_in); // convert into key press
if (key != oldkey)
{
oldkey = key;
if (key >=0)
{

switch (General){
  
case 0: // 1st level

switch(key){
case upKey:
break;

case downKey:
break;

case rightKey:
lcd.clear();
Menu--;
if (Menu<0)
{Menu = 3;}
lcd.setCursor(0, 0);
lcd.print(sequenceMenu[Menu]);
break;

case leftKey:
lcd.clear();
Menu++;
if (Menu>3)
{Menu = 0;}
lcd.setCursor(0, 0);
lcd.print(sequenceMenu[Menu]);

break;

case selectKey:
General++;
if (Menu == 0){
lcd.clear();
getDateDs1307();
displaydate();
displaytime();}
break;
}
break;

case 1: // 2nd level

switch(Menu) {

case 0: // 2nd level "Main"
lcd.clear();
getDateDs1307();
displaydate();
displaytime();
switch(key){

case upKey:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(sequenceMenu[0]);
General--;
break;

case downKey:
break;

case rightKey:
break;

case leftKey:
break;

case selectKey:
break;
}
break;

case 1: // 2nd level "White leds"

switch(key){

case upKey:
break;

case downKey:
break;

case rightKey:
break;

case leftKey:
break;

case selectKey:
break;

}
break;

case 2: // 2nd level "Blue led"

switch(key){

case upKey:
break;

case downKey:
break;

case rightKey:
break;

case leftKey:
break;

case selectKey:
break;
}
break;

case 3: // 2nd level "Tank temp"

switch(key){

case upKey:
break;

case downKey:
break;

case rightKey:
break;

case leftKey:
break;

case selectKey:
break;
}
break;

}
}
}
}
}
}

Is your space bar broken? Use the space bar to line up the code better, please.

adc_key_in = analogRead(0); // read the value from the sensor

What kind of device are you using? An analog device? Switches are typically digital. It's either pressed or it isn't.

int key = 0;
adc_key_in = analogRead(0); // read the value from the sensor
key = get_key(adc_key_in); // convert into key press
if (key != oldkey) // if keypress is detected
{
delay(50); // wait for debounce time
adc_key_in = analogRead(0); // read the value from the sensor
key = get_key(adc_key_in); // convert into key press
if (key != oldkey)
{

We get past this code if the same key is held down for more than 50 milliseconds, and it's not the same key as oldKey. OK. Then, we save the value:

oldkey = key;

Then, it it's a valid key:

switch (General){

case 0: // 1st level

switch(key){
case upKey:
break;

This would certainly be a lot easier to follow it it looked more like this:

switch(General)
{
   case 0: // Indented
      someFunction(); // Organized
      break;
   case 1:
      someOtherFunction();
      break;
// Some more cases
} // Lined up with open }

Then, you have this:

switch(key){
case upKey:
break;

case downKey:
break;

case rightKey:
lcd.clear();

Why bother including the upKey and downKey cases when they do nothing? It would be easier to understand if you simply left these cases out.

If in the future, you intend to do something for the upKey and/or downKey cases, then put them in.

In any case, you eventually get to the point where you call displaydate and displaytime. Those functions show the last retrieved date and last retrieved time, and return.

From what I understand, it doesn't refresh because it's within a switch. What can I do to make time refresh then ?

That's not why it doesn't refresh. The date and time continually update on the real time clock. The display of the date and time don't change, because you don't ask them to.

Put the button presses collection stuff in a function. Put each switch case in a function.

In loop: - fetch the current time and date. - call the function to see is a button was pressed. If so, call the appropriate function to change state. - if the state is "showingDateAndTime", display the current date and time data.

Look in the playground for information on menus and state machines.

Ok, I’ve modified my code so it’s easier to read.

Still, I can’t get what I want.

To make it more understandable, here’s a description of the menu :

  • it has 2 levels : 1st level (called “General”) and 2nd level
  • when a left or right key press is detected, it goes all around 1st level
    menus, which are : Main Menu, White leds menu, Blue leds menu and Tank temp menu
  • when select press is detected, it goes down 2nd level of selected menu

That means that if Main menu is selected, it must display current date and time. I might be wrong but I’ve tried to use a “while” loop so refresh date and time. The condition to get out of this loop is when upkey is pressed.

Here’s my code :

void displaymain(){//this function gets date and time and displays it on LCD screen
lcd.clear();
getDateDs1307();
displaydate();
displaytime();
}


void loop()
{
  
getDateDs1307();

//detect key press
int key = 0;
adc_key_in = analogRead(0); // read the value from the sensor
key = get_key(adc_key_in); // convert into key press
if (key != oldkey) // if keypress is detected
  {
  delay(50); // wait for debounce time
  adc_key_in = analogRead(0); // read the value from the sensor
  key = get_key(adc_key_in); // convert into key press
  if (key != oldkey)
    {
      oldkey = key;
      if (key >=0)
      {

      switch (General){
  
          case 0: // 1st level

              switch(key){
                    case rightKey:
                         lcd.clear();
                         Menu--;
                         if (Menu<0)
                         {Menu = 3;}
                         lcd.clear();
                         lcd.setCursor(0, 0);
                         lcd.print(sequenceMenu[Menu]);
                         break;

                    case leftKey:
                         lcd.clear();
                         Menu++;
                         if (Menu>3){Menu = 0;}
                         lcd.clear();
                         lcd.setCursor(0, 0);
                         lcd.print(sequenceMenu[Menu]);
                         break;

                    case selectKey:
                         General++;
                         if (Menu == 0){//if "Main menu" is selected, it displays date and time until upkey is pressed
                         while (key != upKey){
                         displaymain();}}
                         else {
                             if (Menu == 1){// if "White leds menu"
                                displaywhitemaxintensity();}
                             else {if (Menu == 2){// if "Blue leds menu"
                                      displaybluemaxintensity();}
                                   else {// if "Tank temp menu"
                                       displayfanontemp();}}}
                         break;
                      
                        }
           break;

           case 1: // 2nd level

              switch(Menu) {
                     //lcd.clear();
                     
                     
                     case 0: // 2nd level "Main"
                          while (key != upKey){
                          displaymain();
                          delay(1000);}
                                                    
                              switch(key){
                                   case upKey:
                                        lcd.clear();
                                        lcd.setCursor(0, 0);
                                        lcd.print(sequenceMenu[0]);
                                        General--;
                                        break;
                                          }
                                                                             
                           break;
                           }
           break;
                       }
      }
    }
  }
}

The problem with the loop is that I can’t get out of that loop !

And if I take it off, it won’t refresh !

I’m going nuts because I don’t get it…

This code is a bit easier to read. But, you still have a ways to go to make it better. As soon as you make those improvements, you’ll see what is wrong.

Basically, what you are trying to create is a state machine. The menu’s are for changing the state.

The loop function should enter the “changing state mode” when a key is pressed. That should be handled in a function.

The particular key that is pressed defines a new state and the function ends.

Then, loop continues, with specific behavior depending on the state.

The loop function, in psuedo-code only would look something like this:

int state = 0;
void loop()
{
    // See if a key has been pressed
    if(key != oldkey)
    {
        state = ChangeState(key);
    }

    switch(state)
    {
       case 0:
          // Show date and time
          break;
       case 1:
          // Do something different
          break;
       default:
          // Do whatever needs to be done for an undefined state
          break;
    }
}

Then, create a ChangeState function:

int ChangeState(int key)
{
    int newState = 0;
    // Do whatever needs to be done to change state

    return newState;
}

I’m not positive, but it appears that what you are calling Main Menu isn’t really a menu at all. It is supposed to be the normal state (i.e. the state where you want to display the date and time).

Ok PaulS, I'm gonna try that machine state method tonight. I'll keep you inform of the results.

You're right : "Main menu" isn't really a menu but the normal display mode. Does it mean I have to take it outside the machine state or creating a case (if state = 0 then I display Main menu) is just fine ?

One of the states is "DisplayingDateAndTime". You can name them, or number them. It matters only in how you determine which state you are in.

Numbering them makes it easier, since "if(state == 3)" is much quicker to evaluate than "if(strcmp(state, "DisplayingDateAndTime") == 0)".

So, yes, you'll have a state for displaying the date and time.

Ok, thanks for the hint PaulS !

Here’s the code I’ll try tonight with the LCD hooked up with the Arduino :

void loop()
{
  
int state = 0;

 
getDateDs1307();
LED_levels_output();

detectkey();
if (key >=0)
{
state = ChangeState(key);
}
    
switch(state)
    {
       case 0:
          displaymain();
          break;  
  
         case 1:
          displaymenu();
          break;  
  
         case 2:
          displaymenuchange();
          break;
    }
}


int detectkey(){
int key = 0;
adc_key_in = analogRead(0); // read the value from the sensor
key = get_key(adc_key_in); // convert into key press
if (key != oldkey) // if keypress is detected
{
delay(50); // wait for debounce time
adc_key_in = analogRead(0); // read the value from the sensor
key = get_key(adc_key_in); // convert into key press
if (key != oldkey)
{
oldkey = key;}
}
return key;
}

int ChangeState(int key)
{
    int newState = 0;
    
    switch(key){

           case upKey:
                if (General == 1){
                General--;
                newState = 1;}
                break;

           case rightKey:
                if (General == 0){
                   Menu--;
                   if (Menu<0)
                      {Menu = 3;}
                      newState = 1;}
                if (General == 1){
                   if (Menu == 1){
                      w++;
                      if (w>20){w=20;}}
                      else {if (Menu == 2) {b++;
                                           if (b>20){b=20;}}
                               else tank_fan_on++;}
                                    newState = 2;}
                break;

           case leftKey:
                if (General == 0){
                   Menu++;
                   if (Menu>3)
                      {Menu = 0;}
                      newState = 1;}
                if (General == 1){
                   if (Menu == 1){
                      w--;
                      if (w<0){w=0;}}
                   else {if (Menu == 2) {b--;
                            if (b<0){b=0;}}
                         else tank_fan_on++;}
                 newState = 2;}
                 break;

           case selectKey:
                if (General == 0){
                    General++;
                    if (Menu != 0) {newState = 2;}
                    else newState = 0;}
                if (General == 1){
                    if (Menu == 1){whiteMaxCurrent = whiteMax[b];}
                    else {if (Menu == 2) {blueMaxCurrent = blueMax[b];}
                          else tank_fan_on_temp = tank_fan_on;}
                    newState = 2;
                                  }
                 break;
                 }

    return newState;
}

What do you guys think ? Am I getting closer to the goal ?

You’ll need to assign the return value from “detectKey” to “key”.

Ok thanks, I'll do this then :

key = detectkey();
if (key >=0)
{
state = ChangeState(key);
}

Am I good with this ?

Don't "number" your states - set the numbers up as constants with defines, then use the constants in your code - it will make things tons easier to understand, both for your current self, and your future self 5 years down the road when you decide to add a new function and you haven't looked at the code since then.

Alright...it's not working !

Time doesn't refresh. I don't know what I did wrong but it's not.

I don’t know what I did wrong but it’s not.

Maybe it’s that big blank space under your message, where the code’s supposed to go…

Here’s my code :

void loop()
{
  
int state = 0;

 
getDateDs1307();
LED_levels_output();

int key = 0;
adc_key_in = analogRead(0); // read the value from the sensor
key = get_key(adc_key_in); // convert into key press
if (key != oldkey) // if keypress is detected
{
delay(50); // wait for debounce time
adc_key_in = analogRead(0); // read the value from the sensor
key = get_key(adc_key_in); // convert into key press
if (key != oldkey)
{
oldkey = key;

if (key >=0)
{
state = ChangeState(key);

    
switch(state)
    {
       case 0:
          displaymain();
            delay(1000);
          break;  
  
         case 1:
            lcd.clear();          
            displaymenu();
          break;  
  
         case 2:
         lcd.clear();
          displaymenuchange();
          break;
    }
}
}
}
}


int ChangeState(int key)
{
    int newState = 0;
    
    switch(key){

           case upKey:
                if (General == 1){
                General--;
                newState = 1;}
                break;

           case rightKey:
                if (General == 0){
                  lcd.clear(); 
                  Menu--;
                   if (Menu<0)
                      {Menu = 3;}
                      newState = 1;}
                if (General == 1){
                   if (Menu == 1){
                      w++;
                      if (w>20){w=20;}
                    newState = 2;}
                      else {if (Menu == 2) {b++;
                                           if (b>20){b=20;}
                                         newState = 2;}
                               else { if (Menu == 3) {tank_fan_on++;
                             newState = 2;}
                                     else newState = 0;}
                                    }
                      }
                break;

           case leftKey:
                if (General == 0){
                  lcd.clear();
                   Menu++;
                   if (Menu>3)
                      {Menu = 0;}
                      newState = 1;}
                if (General == 1){
                   if (Menu == 1){
                      w--;
                      if (w<0){w=0;}
                    newState = 2;}
                   else {if (Menu == 2) {b--;
                            if (b<0){b=0;}
                          newState = 2;}
                         else {if (Menu == 3){tank_fan_on--;
                       newState = 2;}
                               else newState = 0;}
                 }
                }
                 break;

           case selectKey:
                if (General == 0){
                    General++;}
                    //if (Menu == 0) {newState = 0;}
                    //else newState = 1;}
                if (General == 1){
                    if (Menu == 1){whiteMaxCurrent = whiteMax[b];
                                   newState = 2;}
                    else {if (Menu == 2) {blueMaxCurrent = blueMax[b];
                                          newState = 2;}
                          else {if (Menu == 3){tank_fan_on_temp = tank_fan_on;
                                newState = 2;}
                                else newState = 0;}
                                  }
                }
                 break;
                 }

    return newState;
}

The switch(state) block is only being executed if a key is pressed. It needs to be executed every time through loop.