How to switch variables according to button preessed time..???

I wrote a small code where pressing a button changes a variable…

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 10, 9);

int switchPin = 19;   // momentary switch on A5, other side connected to ground
int mode = 0;
int prevstate = HIGH;
int currstate;

void setup()
{
  lcd.begin(16, 2);
  pinMode(switchPin, INPUT);
  digitalWrite(switchPin, HIGH);      // turn on pullup resistor
}

void loop()
{
  currstate = digitalRead(switchPin);
  if ((currstate != prevstate) && currstate == HIGH){  
                
lcd.clear();
    mode = mode + 1;
    if(mode > 3){
      
      mode = 1;
    }
  }
 
    switch (mode) {
      case 1: {
        lcd.setCursor(0, 0);                           
        lcd.print("MODE 1");                        // first part of mode 1
        lcd.setCursor(0, 1);
        lcd.print("A");                                 // second part of mode 1
        break;
      }
        
      case 2: {
        lcd.setCursor(0, 0);
        lcd.print("MODE 2");                         // first part of mode 1
        lcd.setCursor(0, 1);
        lcd.print("A");                                 // second part of mode 1
        break;
      }
        
       case 3: {
        lcd.setCursor(0, 0);
        lcd.print("MODE 3");                           // first part of mode 1
        lcd.setCursor(0, 1);
        lcd.print("A");                                  // second part of mode 1
        break;
       }
  }
   prevstate = currstate;
}

Now I would like to include a second button to the code and do things like

if MODE is 1 or 2 or 4 and the second button is pressed short change the second part in the MODES from A to B, or B to C, or C to D

Long pressing of button 1 will blink the current second part of the MODE and then
long pressing of the second button will reset the value of the blinking part ( where all A, B, C & D has a dynamic value)

How do I do this…??

    mode = mode + 1;

Have you noticed that the language used to program the Arduino is called C++, rather than C=C+1? Have you ever wondered why? Perhaps it's time to learn about some of C's compound operators, like ++, --, +=, etc. There are descriptions on the Reference page.

Now I would like to include a second button to the code and do things like

if MODE is 1 or 2 or 4

Since your code limits mode to 1, 2, or 3, it will never be 4.

I'm not really sure what you are asking here. It is quite easy to connect a second switch (leave the buttons on the shirt where they belong). It is quite easy to read it's state. It is quite easy to modify the value of mode based on the state of the second switch, just like you do for the first switch.

It does seem, though, like all the action takes place inside if transition to pressed block, whereas what I think you want is to just change the value of mode in the if block, and then have the switch statement after the if block.

Measuring the time that a switch is pressed is easy enough. When there is a transition (currState != prevState), note the time (in nowPressed or nowReleased, as appropriate).

At any time, you can determine how long the switch has been, or was, held down. It's simply a matter of setting nowReleased to 0 when the switch is pressed, along with setting nowPressed to millis(). Then, the switch has been held down for millis() - nowPressed milliseconds, if nowReleased is 0, or was held down for newReleased - nowPressed, if newRealased is not 0.

Have you noticed that the language used to program the Arduino is called C++, rather than C=C+1?

:stuck_out_tongue: that was a silly mistake
so I converted it to

mode ++;

Since your code limits mode to 1, 2, or 3, it will never be 4.

Actually there will be 4 modes, I forgot to include mode 4 in the loop. So here is the loop with 4 modes…

void loop()
{
  currstate = digitalRead(switchPin);
  if ((currstate != prevstate) && currstate == HIGH){  
                
lcd.clear();
    mode++;
    if(mode > 4){
      
      mode = 1;
    }
  }
 
    switch (mode) {
      case 1: {
        lcd.setCursor(0, 0);                           
        lcd.print("MODE 1");                        // first part of mode 1
        lcd.setCursor(0, 1);
        lcd.print("A");                                 // second part of mode 1
        break;
      }
        
      case 2: {
        lcd.setCursor(0, 0);
        lcd.print("MODE 2");                         // first part of mode 2
        lcd.setCursor(0, 1);
        lcd.print("A");                                 // second part of mode 2
        break;
      }
        
       case 3: {
        lcd.setCursor(0, 0);
        lcd.print("MODE 3");                           // first part of mode 3
        lcd.setCursor(0, 1);
        lcd.print("A");                                  // second part of mode 3
        break;
       }

       case 4: {
        lcd.setCursor(0, 0);
        lcd.print("MODE 4");                           // first part of mode 4
        lcd.setCursor(0, 1);
        lcd.print("A");                                  // second part of mode 4
        break;
       }
  }
   prevstate = currstate;
}

Somewhere outside loop:

bool button2State = false;
unsigned long button2Time = 0;

Somewhere inside loop:

  bool b2 = (digitalRead(button2Pin) == LOW); // pressed?
  if (b2 != button2State) {
    if (b2) {
      button2Time = millis(); // count when pressed
    }
    else {
      unsigned long timePressed = millis() - button2Time;
      if (timePressed < 800) { // short press
        ...
      }
      else { // long press
        ...
      }
    }
    button2State = b2;
  }

thank you jwatte for your hard work... but I tried your way .. it does not seem to work... :(

Here is something similar to what you are asking, it includes a button debounce as well, it may be that you were simply dealing with bounce.

boolean lastbutton;
boolean currentbutton;

unsigned long startmillis = 0;
unsigned long endmillis = 0;


void loop()
{
 //Debounce button
  currentbutton = debounce(lastbutton);

  if (lastbutton == LOW && currentbutton == HIGH)  //Check if button pressed. Count Millis until released.
  {
    startmillis = millis();    //As soon as the button is pressed, it sets the startmillis
    do
    {
      endmillis = millis();   //endmillis is updated continuously as long as the button is still pressed
    }while(digitalRead(buttonpin) == HIGH);
  }

//Now handle my button time conditions. With this method you can handle multiple times, put the longest time first and always reset your time in each one.
//This could be done in a switch case but in this instance, multiple if loops was easier for me.

 if (endmillis - startmillis > 3000)  //3 second button press
  {
    //Do some stuff
    startmillis = endmillis;  //This is critical! This will reset you difference to 0 until the next time the button is pressed.
  }  


 if (endmillis - startmillis > 300)  //.3 second button press
  {
    //Do some stuff
    startmillis = endmillis;  //This is critical! This will reset you difference to 0 until the next time the button is pressed.
  }  

 if (endmillis - startmillis > 50)  //more of a button tap
  {
    //Do some stuff
    startmillis = endmillis;  //This is critical! This will reset you difference to 0 until the next time the button is pressed.
  }  

}


//Debounce Routine
boolean debounce(boolean last)
{
  boolean current = digitalRead(buttonpin);
  if (last != current) 
  {
    delay(50);
    current = digitalRead(buttonpin);
  }
  return current;
}

Thank you Sacman

Your code seems good for me to understand… :slight_smile:

That delay which you are using in the debounce routine I do not want that as it is going to harm my other codes…

Isnt there any other ways to debounce the buttons…

Isnt there any other ways to debounce the buttons...

There are two other ways. One is to use millis() to record when a transition occurred, and ignore any transition that occurs too close to the previous one. The other is to use external components to debounce the switch with hardware.

The third way is to cut the debounce time down. 50 milliseconds is generally far longer than a switch bounces for. 20 milliseconds is a more reasonable value.

Pauls,

I tried to use a shorter time but was having other issues that I did not know about so I settled at 50 and never went back and tried shorter times. Thanks for that bit of info.

Joy,

That debounce delay is only seen when you first press the button. It is not looked at every loop since, if you use it the way I’ve coded it, you will be stuck in the while loop until you release the button. There are other ways to do that portion but for me, I didn’t need anything else to happen while the button was being pressed.