lcd menu help

i am trying to accomplish a menu on a 20x4 lcd, the screens do change but i want the first page to have blinking text and be the default page... the button will allow me to go through the pages.. but say i click the button once.. but not again i want it to go back to the blinking text page after so much time like a delay, each page will have this delay if you know what i mean..

#include <Wire.h>
#include <hd44780.h>                       // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header

hd44780_I2Cexp lcd; // declare lcd object: auto locate & config exapander chip

// LCD geometry
const int LCD_COLS = 20;
const int LCD_ROWS = 4;

int WhichScreen = 1;  // This variable stores the current Screen number
boolean hasChanged = true;
const int buttonPin = 3;    // the number of the pushbutton pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup()
{
  int status;
  status = lcd.begin(LCD_COLS, LCD_ROWS);
  pinMode(buttonPin, INPUT);

}
void loop()
{

  if (hasChanged == true) {

    switch (WhichScreen) {
      case 1:
        {
          firstScreen();
        }
        break;

      case 2:
        {
          secondScreen();
        }
        break;

      case 3:
        {
          thirdScreen();
        }
        break;


      case 0:
        {

        }
        break;
    }
  }

  //-------------------------------
  // BEGIN of the switch debouncing code
  int reading = digitalRead(buttonPin);
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // only toggle the LED if the new button state is HIGH
      if (buttonState == HIGH) {
        hasChanged = true;
        WhichScreen++;


      }
    } else {
      hasChanged = false;
    }
  }
  lastButtonState = reading;
  // END of the switch Debouncing code
  // --------------------------------------
  if (WhichScreen > 3) {
    WhichScreen = 1;
  }
}

void firstScreen()
{
  // loop repeatedly until the button is pressed
  // return to this screen after a delay after button
  // is pressed but not pressed again within a certain amount of time
  lcd.clear();
  lcd.setCursor(0, 0); // Column, line
  lcd.print("      MY INTRO      ");
  lcd.setCursor(0, 1);
  lcd.print("      BLINKING      ");
  lcd.setCursor(0, 2);
  lcd.print("       SPLASH       ");
  lcd.setCursor(0, 3);
  lcd.print("       SCREEN       ");
}
void secondScreen()
{
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("PHRASE 1:");
  lcd.setCursor(0, 1);
  lcd.print("PHRASE 2:");
  lcd.setCursor(0, 2);
  lcd.print("PHRASE 3:");
  lcd.setCursor(0, 3);
  lcd.print("PHRASE 4:");
}
void thirdScreen()
{
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("PHRASE 1:");
  lcd.setCursor(0, 1);
  lcd.print("PHRASE 2:");
  lcd.setCursor(0, 2);
  lcd.print("PHRASE 3:");
  lcd.setCursor(0, 3);
  lcd.print("PHRASE 4:");
}

Off the cuff possibility - when the [color=blue]switch()[/color]<>0, run a timer. When the timer times out set the [color=blue]switch()[/color] = 0.

I would change each "nthScreen" function to manage its own processes. So you call the nthScreen() function every single time through the loop. It then looks at what state it's in: has it just entered that screen? Is it time for a blink? Keep a few local variables inside the function as static so that it can remember what went on before.

For example...

void firstScreen(bool hasChanged)
{
  // call this hundreds of times per second.
  //hasChanged tells us that the overall screen state has changed, so we need to re-display the whole screen
  static unsigned long localLastMillis;
  static bool blinkStatus=true;
  const unsigned long blinkInterval = 1000; //milliseconds, interval between blinks
  if(hasChanged) {
    //Draw the full screen
    lcd.clear();
    lcd.setCursor(0, 0); // Column, line
    lcd.print("      MY INTRO      ");
    lcd.setCursor(0, 2);
    lcd.print("       SPLASH       ");
    lcd.setCursor(0, 3);
    lcd.print("       SCREEN       ");
  }
  if((millis()-localLastMillis > blinkInterval && blinkStatus) || hasChanged) {
    //either the timer expired or we've just changed the screen and we need to show the blinking text
    lcd.setCursor(0, 1);
    lcd.print("      BLINKING      ");
    blinkStatus = false;
    localLastMillis = millis();
  }
  if(millis()-localLastMillis > blinkInterval && !blinkStatus) {
    //time to blink the text off
    lcd.setCursor(0, 1);
    lcd.print("                    ");
    blinkStatus = true;
    localLastMillis = millis();
  }
  
}

Since these functions are being called all the time, you may even wish to put the button-handling code inside them. That way the same button can do different things depending on what screen you are on. (Do the debounce outside the screen functions.)

ok, i shall try that thank you

Sorry, it didn't work for me.. i tried in several places in my code.. i was just more confused than what i started with. :confused:

flashing text until button is pressed.. after button is pressed go through the menu screens - each menu is on for so long if button is not pressed then go back to flashing text..

i'll just try to come up with a different way of doing this. thank you for your time tho.

If the display controller is the ubiquitous 44780 you could send display()/noDisplay() commands when at screen zero. All you'd need is a self-resetting timer and a toggle boolean.

i've decided not to go with the blinking text due to a slight project change that no longer requires it... but please continue with the topic incase someone else is interested.

but thank you all for the input.. i appreciate it.