SOLVED- Nested Switch not working properly

Was able to find a solution, the working code is below for anyone that may need this as well

Greetings,

This is my first project, so i apologize if my code isn't as buttoned up as it could be. In the current stage of the project, i have three buttons and a LCD screen. I am trying to create two pages on a 16x2 LCD screen that houses four variables. And with a button hold I can change where the cursor blinks and depending on that location I can increase or decrease a specific variable.

button 1 (press): changes what "page" is displayed on LCD
button 1 (hold): changes the cursor location on the screen so a variable can be changed
button 2: increases variable by 1 depending on what case is in affect
button 3: decreases variable by 1 depending on what case is in affect

Through my testing I validated everything in my code works except the lcd.blink().... I am not sure why. But the machine recognizes what case I am in as I can change variables correctly, I just cannot tell where on the LCD the modifications are occurring since the space isn't blinking until a change is made. Any assistance or guidance is always appreciated :slight_smile:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display

const int btn1 = 4;       // choose the input pin (for pushbutton 1)
const int btn2 = 5;       // choose the input pin (for pushbutton 2)
const int btn3 = 6;       // choose the input pin (for pushbutton 3)
const int ledwht = A5;    // input pin for led
unsigned long tmot = 0;   // var for timeout to sleep display
int btn1State = 0;        // current state of button 1
int lastBtn1State = 0;    // previous state of button 1
int startPressed = 0;    // the time button 1 was pressed
int endPressed = 0;      // the time button 1 was released
int timeHold = 0;        // the time button 1 is hold
int var1 = 0;           // the first adjustable variable
int var2 = 0;           // second adjustable variable
int var3 = 0;           // third adjustable variable
int var4 = 0;           // fourth adjustable variable
int SwitchVar = 0;      // switch case to change blink cursor for variables
int Display = 0;        // switch case for changing the pages

void setup()
{
  lcd.begin(16, 2);
  lcd.init();
  lcd.backlight();
  lcd.clear();
  pinMode(btn1, INPUT_PULLUP);    // declare pushbutton as input
  pinMode(btn2, INPUT_PULLUP);    // declare pushbutton as input
  pinMode(btn3, INPUT_PULLUP);    // declare pushbutton as input
  pinMode(ledwht, OUTPUT); // declare led as output
}

void loop()
{
  btn1State = digitalRead(btn1);     // read the pushbutton input pin

  if (btn1State != lastBtn1State)
  { // button state changed
    if (btn1State == HIGH)
    { // the button was just pressed
      startPressed = millis();
    }
    else
    { // the button was just released
      endPressed = millis();
      timeHold = endPressed - startPressed;
      if (timeHold >= 000 && timeHold < 1000)
      { // button press, this is where you will change the page
        lcd.backlight();
        tmot = millis() + 10000;           // sets timeout time for button inactivity
        SwitchVar = 0;
        Display ++;
        if (Display > 2)
        {
          Display = 1;
        }
      }
      else if (timeHold >= 1000)
      { // button hold, this is where you will change the variable
        lcd.backlight();
        tmot = millis() + 10000;           // sets timeout time for button inactivity
        SwitchVar ++;
        if (SwitchVar > 2)
        {
          SwitchVar = 0;
        }
      }
    }
    lastBtn1State = btn1State;    // save the current state as the last state, for next time through the loop
    switch (Display)
    {
      case 1:
        lcd.init();
        lcd.setCursor(0, 0);
        lcd.print("PAGE:");
        lcd.setCursor(6, 0);
        lcd.print(Display);
        lcd.setCursor(9, 0);
        lcd.print("SWTC");
        lcd.setCursor(15, 0);
        lcd.print(SwitchVar);
        lcd.setCursor(0, 1);
        lcd.print("VAR1:");
        lcd.setCursor(6, 1);
        lcd.print(var1);
        lcd.setCursor(9, 1);
        lcd.print("VAR2:");
        lcd.setCursor(15, 1);
        lcd.print(var2);
        switch (SwitchVar)
        {
          case 0:
            lcd.setCursor(15, 1);
            lcd.noBlink();
            break;
          case 1:
            lcd.setCursor(6, 1);
            lcd.blink();
            break;
          case 2:
            lcd.setCursor(15, 1);
            lcd.blink();
            break;
        }
        break;
      case 2:
        lcd.init();
        lcd.setCursor(0, 0);
        lcd.print("PAGE:");
        lcd.setCursor(6, 0);
        lcd.print(Display);
        lcd.setCursor(0, 1);
        lcd.print("VAR3:");
        lcd.setCursor(6, 1);
        lcd.print(var3);
        lcd.setCursor(9, 1);
        lcd.print("VAR4:");
        lcd.setCursor(15, 1);
        lcd.print(var4);
        switch (SwitchVar)
        {
          case 0:
            lcd.setCursor(15, 1);
            lcd.noBlink();
            break;
          case 3:
            lcd.setCursor(6, 1);
            lcd.blink();
            break;
          case 4:
            lcd.setCursor(15, 1);
            lcd.blink();
            break;
        }
        break;
    }
  }
  else
  {
    if (millis() > tmot && tmot != 0)
    {
      tmot = 0;
      Display = 0;
      SwitchVar = 0;
      lcd.noBacklight();
    }
  }
  switch (SwitchVar)
  {
    case 0:
      lcd.setCursor(15, 1);
      lcd.noBlink();
      break;
    case 1:
      lcd.setCursor(6, 1);
      lcd.blink();
      if ((digitalRead(btn2) == HIGH) && (Display == 1))
      {
        delay(500);                        // delay to debounce switch
        tmot = millis() + 10000;           // sets timeout time for button inactivity
        var1++;
        if (var1 > 9)
        {
          var1 = 0;
        }
        lcd.print(var1);
      }
      else if ((digitalRead(btn2) == HIGH) && (Display == 2))
      {
        delay(500);                        // delay to debounce switch
        tmot = millis() + 10000;           // sets timeout time for button inactivity
        var3++;
        if (var3 > 9)
        {
          var3 = 0;
        }
        lcd.print(var3);
      }
      if ((digitalRead(btn3) == HIGH) && (Display == 1))
      {
        delay(500);                        // delay to debounce switch
        tmot = millis() + 10000;           // sets timeout time for button inactivity
        var1--;
        if (var1 < 0)
        {
          var1 = 0;
        }
        lcd.print(var1);
      }
      else if ((digitalRead(btn3) == HIGH) && (Display == 2))
      {
        delay(500);                        // delay to debounce switch
        tmot = millis() + 10000;           // sets timeout time for button inactivity
        var3--;
        if (var3 < 0)
        {
          var3 = 0;
        }
        lcd.print(var3);
      }
      break;
    case 2:
      lcd.setCursor(15, 1);
      lcd.blink();
      if ((digitalRead(btn2) == HIGH) && (Display == 1))
      {
        delay(500);                        // delay to debounce switch
        var2++;
        if (var2 > 9)
        {
          var2 = 0;
        }
        lcd.print(var2);
      }
      else if ((digitalRead(btn2) == HIGH) && (Display == 2))
      {
        delay(500);                        // delay to debounce switch
        var4++;
        if (var4 > 9)
        {
          var4 = 0;
        }
        lcd.print(var4);
      }
      if ((digitalRead(btn3) == HIGH) && (Display == 1))
      {
        delay(500);                        // delay to debounce switch
        var2--;
        if (var2 < 0)
        {
          var2 = 0;
        }
        lcd.print(var2);
      }
      else if ((digitalRead(btn3) == HIGH) && (Display == 2))
      {
        delay(500);                        // delay to debounce switch
        var4--;
        if (var4 < 0)
        {
          var4 = 0;
        }
        lcd.print(var4);
      }
      break;
  }
}

Please note re-formatted code,

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display

const int btn1 = 4;       // choose the input pin (for pushbutton 1)
const int btn2 = 5;       // choose the input pin (for pushbutton 2)
const int btn3 = 6;       // choose the input pin (for pushbutton 3)
const int ledwht = A5;    // input pin for led
unsigned long tmot = 0;   // var for timeout to sleep display
int btn1State = 0;        // current state of button 1
int lastBtn1State = 0;    // previous state of button 1
int startPressed = 0;    // the time button 1 was pressed
int endPressed = 0;      // the time button 1 was released
int timeHold = 0;        // the time button 1 is hold
int var1 = 0;           // the first adjustable variable
int var2 = 0;           // second adjustable variable
int var3 = 0;           // third adjustable variable
int var4 = 0;           // fourth adjustable variable
int SwitchVar = 0;      // switch case to change blink cursor for variables
int Display = 0;        // switch case for changing the pages

void setup() 
{
    lcd.begin(16, 2);
    lcd.init();
    lcd.backlight();
    lcd.clear();
    pinMode(btn1, INPUT);    // declare pushbutton as input
    digitalWrite(btn1, HIGH);      // turn on pullup resistor
    pinMode(btn2, INPUT);    // declare pushbutton as input
    digitalWrite(btn2, HIGH);      // turn on pullup resistor
    pinMode(btn3, INPUT);    // declare pushbutton as input
    digitalWrite(btn3, HIGH);      // turn on pullup resistor
    pinMode(ledwht, OUTPUT); // declare led as output
}

void loop()
{
    btn1State = digitalRead(btn1);     // read the pushbutton input pin

    if (btn1State != lastBtn1State) 
    {     // button state changed
        if (btn1State == HIGH) 
        {            // the button was just pressed
            startPressed = millis();
        } 
        else 
        {                            // the button was just released
            endPressed = millis();
            timeHold = endPressed - startPressed;
            if (timeHold >= 000 && timeHold < 1500) 
            {     // button press, this is where you will change the page
                lcd.backlight();
                tmot = millis() + 10000;           // sets timeout time for button inactivity
                Display ++;
                if(Display > 2)
                {
                    Display = 1;
                }
            }
            if (timeHold >= 1500) 
            {         // button hold, this is where you will change the variable
                lcd.backlight();
                tmot = millis() + 10000;           // sets timeout time for button inactivity
                SwitchVar ++;
                if(SwitchVar > 2)
                {
                    SwitchVar = 0;
                }
            }
        }
        lastBtn1State = btn1State;    // save the current state as the last state, for next time through the loop
    } 
    else 
    {
        if (millis() > tmot && tmot != 0)
        {
            tmot = 0;
            Display = 0;
            lcd.noBacklight();
        }
    }

    switch (Display) 
    {         
        case 1: 
            lcd.setCursor(0, 0);
            lcd.print("PAGE:");
            lcd.setCursor(6, 0);
            lcd.print(Display);
            lcd.setCursor(0, 1);
            lcd.print("VAR1:"); 
            lcd.setCursor(6, 1);
            lcd.print(var1);
            lcd.setCursor(9, 1);
            lcd.print("VAR2:");
            lcd.setCursor(15, 1);
            lcd.print(var2);
            switch (SwitchVar) 
            {
                case 0: 
                    lcd.setCursor(15, 1);
                    lcd.noBlink();
                    break;
                case 1: 
                    lcd.setCursor(6, 1);
                    lcd.blink();
                    if (digitalRead(btn2) == HIGH)
                    { 
                        delay(500);                        // delay to debounce switch
                        tmot = millis() + 10000;           // sets timeout time for button inactivity
                        var1++;
                        if(var1 > 9)
                        {
                            var1 = 0;
                        }
                        lcd.print(var1);
                    }
                    if (digitalRead(btn3) == HIGH)
                    { 
                        delay(500);                        // delay to debounce switch
                        tmot = millis() + 10000;           // sets timeout time for button inactivity
                        var1--;
                        if(var1 < 0)
                        {
                            var1 = 0;
                        }
                        lcd.print(var1);
                    }
                    break;
                case 2: 
                    lcd.setCursor(15, 1);
                    lcd.blink();
                    if (digitalRead(btn2) == HIGH)
                    { 
                        delay(500);                        // delay to debounce switch
                        var2++;
                        if(var2 > 9)
                        {
                            var2 = 0;
                        }
                        lcd.print(var2);
                    }
                    if (digitalRead(btn3) == HIGH)
                    { 
                        delay(500);                        // delay to debounce switch
                        var2--;
                        if(var2 < 0)
                        {
                            var2 = 0;
                        }
                        lcd.print(var2);
                    }
                    break;
            }
            break;
        case 2: 
            lcd.setCursor(0, 0);
            lcd.print("PAGE:");
            lcd.setCursor(6, 0);
            lcd.print(Display);
            lcd.setCursor(0, 1);
            lcd.print("VAR3:");
            lcd.setCursor(6, 1);
            lcd.print(var3);
            lcd.setCursor(9, 1);
            lcd.print("VAR4:");
            lcd.setCursor(15, 1);
            lcd.print(var4);
            switch (SwitchVar) 
            {
                case 0: 
                    lcd.setCursor(15, 1);
                    lcd.noBlink();
                    break;
                case 1: 
                    lcd.setCursor(6, 1);
                    lcd.blink();
                    if (digitalRead(btn2) == HIGH)
                    { 
                        delay(500);                        // delay to debounce switch
                        var3++;
                        if(var3 > 9)
                        {
                            var3 = 0;
                        }
                        lcd.print(var3);
                    }
                    if (digitalRead(btn3) == HIGH)
                    { 
                        delay(500);                        // delay to debounce switch
                        var3--;
                        if(var3 < 0)
                        {
                            var3 = 0;
                        }
                        lcd.print(var3);
                    }
                    break;
                case 2: 
                    lcd.setCursor(15, 1);
                    lcd.blink();
                    if (digitalRead(btn2) == HIGH)
                    { 
                        delay(500);                        // delay to debounce switch
                        var4++;
                        if(var4 > 9)
                        {
                            var4 = 0;
                        }
                        lcd.print(var4);
                    }
                    if (digitalRead(btn3) == HIGH)
                    { 
                        delay(500);                        // delay to debounce switch
                        var4--;
                        if(var4 < 0)
                        {
                            var4 = 0;
                        }
                        lcd.print(var4);
                    }
                    break;
            }
            break;
    }
}

Thank you for the response!

However, even with the above update, the lcd.blink function is still not working

The post was not an update, I simply re-formatted your code so it's easier to look at and follow the program logic.

Oh. Ok. Thank you still

One more hint. A reason it's useful to have clearly formatted code, as mentioned, is to be able to visually follow the program flow. My suggestion relative to your issue, is to look at the variable most prominent in the blink/noblink scenario. This appears to be SwitchVar. In a good editor (the IDE is not one), I use Notepad++ and there are others, you select one instance of the variable identifier and all instances are highlighted making it very easy to see where is value is being altered.

    pinMode(btn1, INPUT);    // declare pushbutton as input
    digitalWrite(btn1, HIGH);      // turn on pullup resistor
    pinMode(btn2, INPUT);    // declare pushbutton as input
    digitalWrite(btn2, HIGH);      // turn on pullup resistor
    pinMode(btn3, INPUT);    // declare pushbutton as input
    digitalWrite(btn3, HIGH);      // turn on pullup resistor

There is a reason that the mode INPUT_PULLUP was introduced.

            if (timeHold >= 000 && timeHold < 1500)
            {     // button press, this is where you will change the page
            }
            if (timeHold >= 1500)
            {         // button hold, this is where you will change the variable
            }

Ever heard of else if? Know why it exists? If only one of the conditions can be true, if/else if is more appropriate than if/if.

I can't tell if you are being snarky sounding on purpose or if I am just reading it that way.

So I'll assume it is my bad :slight_smile:

I will also assume you're post is to better the code format rather than helping me with the solution.

So thank you for the assistance on fixing how it looks :slight_smile:

I will also assume you're post is to better the code format rather than helping me with the solution.

When I look at code, I try to look beyond just the code itself, to see how easy it is to understand the code.

For me,
pinMode(somePin, INPUT_PULLUP);
makes it abundantly clear that the internal pullup resistor is being used, whereas

    pinMode(btn1, INPUT);    // declare pushbutton as input
    digitalWrite(btn1, HIGH);      // turn on pullup resistor

first makes me wonder why you are writing to an input pin. Then, I remember that writing to an input pin turns the internal pullup resistor on or off.

So, its about understanding without needing to study, and maintainability.

The if/if vs. if/else issue makes it clear that you want not more than one of the blocks to run. While, in this case, the difference is minimal, there are other times where evaluating the condition requires making a call to a function that is going to take a long time to complete. If you have two such functions, and only one of them needs to be called, because it returned true, your program, using if/else, will not have to call the other one, making the program faster.

I wasn't trying to be snarky. If I was, there would be no doubt in your mind.

Good to know!

Like I stated, this is my first jab at C or Arduino, so any guidance is welcomed and I am thankful for it.

I will make the adjustments to my code and do some more debugging tonight

Update!

The below code allows the lcd.blink to work! However now my increment and decrement buttons are unresponsive. Will continue to debug tomorrow or if anyone could advise potentially what made this happen that would be great!

P.S. the led is to advise if the button is responsive and it isn't

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display

const int btn1 = 4;       // choose the input pin (for pushbutton 1)
const int btn2 = 5;       // choose the input pin (for pushbutton 2)
const int btn3 = 6;       // choose the input pin (for pushbutton 3)
const int ledwht = A5;    // input pin for led
unsigned long tmot = 0;   // var for timeout to sleep display
int btn1State = 0;        // current state of button 1
int lastBtn1State = 0;    // previous state of button 1
int startPressed = 0;    // the time button 1 was pressed
int endPressed = 0;      // the time button 1 was released
int timeHold = 0;        // the time button 1 is hold
int var1 = 0;           // the first adjustable variable
int var2 = 0;           // second adjustable variable
int var3 = 0;           // third adjustable variable
int var4 = 0;           // fourth adjustable variable
int SwitchVar = 0;      // switch case to change blink cursor for variables
int Display = 0;        // switch case for changing the pages

void setup() 
{
    lcd.begin(16, 2);
    lcd.init();
    lcd.backlight();
    lcd.clear();
    pinMode(btn1, INPUT_PULLUP);    // declare pushbutton as input
    pinMode(btn2, INPUT_PULLUP);    // declare pushbutton as input
    pinMode(btn3, INPUT_PULLUP);    // declare pushbutton as input
    pinMode(ledwht, OUTPUT); // declare led as output
}

void loop()
{
    btn1State = digitalRead(btn1);     // read the pushbutton input pin

    if (btn1State != lastBtn1State) 
    {     // button state changed
        if (btn1State == HIGH) 
        {            // the button was just pressed
            startPressed = millis();
        } 
        else 
        {                            // the button was just released
            endPressed = millis();
            timeHold = endPressed - startPressed;
            if (timeHold >= 000 && timeHold < 1500) 
            {     // button press, this is where you will change the page
                lcd.backlight();
                tmot = millis() + 10000;           // sets timeout time for button inactivity
				SwitchVar = 0;
                Display ++;
                if(Display > 2)
                {
                    Display = 1;
                }
            }
            else if (timeHold >= 1500) 
            {         // button hold, this is where you will change the variable
                lcd.backlight();
                tmot = millis() + 10000;           // sets timeout time for button inactivity
                SwitchVar ++;
                if(SwitchVar > 2)
                {
                    SwitchVar = 0;
                }
            }
        }
        lastBtn1State = btn1State;    // save the current state as the last state, for next time through the loop
		switch (Display) 
    {         
        case 1: 
			lcd.init();
            lcd.setCursor(0, 0);
            lcd.print("PAGE:");
            lcd.setCursor(6, 0);
            lcd.print(Display);
			lcd.setCursor(9,0);
			lcd.print("SWTC");
			lcd.setCursor(15,0);
			lcd.print(SwitchVar);
            lcd.setCursor(0, 1);
            lcd.print("VAR1:"); 
            lcd.setCursor(6, 1);
            lcd.print(var1);
            lcd.setCursor(9, 1);
            lcd.print("VAR2:");
            lcd.setCursor(15, 1);
            lcd.print(var2);
            switch (SwitchVar) 
            {
                case 0: 
                    lcd.setCursor(15, 1);
                    lcd.noBlink();
                    break;
                case 1: 
                    lcd.setCursor(6, 1);
                    lcd.blink();
                    if (digitalRead(btn2) == HIGH)
                    { 
                        delay(500);                        // delay to debounce switch
						digitalWrite(ledwht, HIGH);
                        tmot = millis() + 10000;           // sets timeout time for button inactivity
                        var1++;
                        if(var1 > 9)
                        {
                            var1 = 0;
                        }
                        lcd.print(var1);
                    }
					else
					{
						digitalWrite(ledwht, LOW);
					}
                    if (digitalRead(btn3) == HIGH)
                    { 
                        delay(500);                        // delay to debounce switch
                        tmot = millis() + 10000;           // sets timeout time for button inactivity
                        var1--;
                        if(var1 < 0)
                        {
                            var1 = 0;
                        }
                        lcd.print(var1);
                    }
                    break;
                case 2: 
                    lcd.setCursor(15, 1);
                    lcd.blink();
                    if (digitalRead(btn2) == HIGH)
                    { 
                        delay(500);                        // delay to debounce switch
                        var2++;
                        if(var2 > 9)
                        {
                            var2 = 0;
                        }
                        lcd.print(var2);
                    }
                    if (digitalRead(btn3) == HIGH)
                    { 
                        delay(500);                        // delay to debounce switch
                        var2--;
                        if(var2 < 0)
                        {
                            var2 = 0;
                        }
                        lcd.print(var2);
                    }
                    break;
            }
            break;
        case 2: 
			lcd.init();
            lcd.setCursor(0, 0);
            lcd.print("PAGE:");
            lcd.setCursor(6, 0);
            lcd.print(Display);
            lcd.setCursor(0, 1);
            lcd.print("VAR3:");
            lcd.setCursor(6, 1);
            lcd.print(var3);
            lcd.setCursor(9, 1);
            lcd.print("VAR4:");
            lcd.setCursor(15, 1);
            lcd.print(var4);
            switch (SwitchVar) 
            {
                case 0: 
                    lcd.setCursor(15, 1);
                    lcd.noBlink();
                    break;
                case 1: 
                    lcd.setCursor(6, 1);
                    lcd.blink();
                    if (digitalRead(btn2) == HIGH)
                    { 
                        delay(500);                        // delay to debounce switch
                        var3++;
                        if(var3 > 9)
                        {
                            var3 = 0;
                        }
                        lcd.print(var3);
                    }
                    if (digitalRead(btn3) == HIGH)
                    { 
                        delay(500);                        // delay to debounce switch
                        var3--;
                        if(var3 < 0)
                        {
                            var3 = 0;
                        }
                        lcd.print(var3);
                    }
                    break;
                case 2: 
                    lcd.setCursor(15, 1);
                    lcd.blink();
                    if (digitalRead(btn2) == HIGH)
                    { 
                        delay(500);                        // delay to debounce switch
                        var4++;
                        if(var4 > 9)
                        {
                            var4 = 0;
                        }
                        lcd.print(var4);
                    }
                    if (digitalRead(btn3) == HIGH)
                    { 
                        delay(500);                        // delay to debounce switch
                        var4--;
                        if(var4 < 0)
                        {
                            var4 = 0;
                        }
                        lcd.print(var4);
                    }
                    break;
            }
            break;
    }
    } 
    else 
    {
        if (millis() > tmot && tmot != 0)
        {
            tmot = 0;
            Display = 0;
			SwitchVar = 0;
            lcd.noBacklight();
        }
    }
}

I tried reading your code. I got a headache. Using Tools + Auto Format costs nothing, and stops seasickness. Use it.