short and long button presses, how?

Hey guys, new here, got an arduino board a couple weeks ago for a few projects in my head, but I'm hitting a roadblock.

I need my program to do different things depending on how long the user has pressed a button. In other words, if it's been simply pressed and released (less then a second), then do A, but if it's been held down for longer than that, do B.

I've tried a couple different ways but to no avail. In theory the best way to do this would be a while loop kinda like this:

timer = 0;
while (button = HIGH) {
  delay(100);
  timer++;
}
if (timer < 10) { //button has been pressed less than a second
  A;
else {
  B;
}

But it doesn't really work... any ideas? I'm worried it might be some interference with other parts of my code, so I'll be playing around with it some more, but would appreciate any input!

Thomas

mwahhahaha nevermind, I got it :smiley:

Used the serial monitor to get a better idea of what's going on, and realized... I need to check the button's status in the loop, or it will loop endlessly!

So here's the revised loop:

while (status_button == HIGH){
  button_delay++;
  delay(100);
    Serial.println("holding");
  status_button = digitalRead(inputPin);
}

Works flawlessly now!

Glad to see you work through the problems yourself-- it's the best way to learn.

You can either measure the WHOLE time that the button is down, and decide if it's long enough, or you can escape the loop if the user holds down the button for long enough to be considered the longest press type. Most devices I've seen will opt for the latter.

int held = 0;
while (digitalRead(button) == HIGH[glow] && held < 10[/glow])
{
    delay(100);
    held++;
}
if (held < 10)
    A;  // the button was released in less than a second
else
    B;  // a second has passed, note that the button may still be down

thanks, I actually tweaked it somewhat similarly, function B is now in the loop itself, and triggered once the timer counter reaches 10, while function A is still out of the loop:

while (status_button == HIGH){
  button_delay++;
  delay(100);
  status_button = digitalRead(inputPin);
  
  if(button_delay == 10){ //no need to wait for user to release
          B
          break;
  }        
  
}
  if(button_delay < 10) { //short press
           A
}

different means to the same end, I think!

Yes, there are a bezillion different ways to code the same idea.

Another common approach is to design your device such that the "short press A" happens regardless, and "long press B" task is done in addition. This lets you do A when the button-press is first detected, and gives the most responsive feel for a device.

yeah.. I have some background in PHP programming so I understand the core concepts quite well, but I know I'm just skimming the surface of what's possible with these little devices... be ready to hear a lot more from me :smiley:

is there no command such as millis() which could be used to do this?

I have a similar problem:
When I press a button a counter should increase by 1.

Problem is that when I press the button (even if i press them quick) the counter goes up f.e. to 25....

Is there a workaround for that kind of issue?

I have a similar problem:
When I press a button a counter should increase by 1.

Problem is that when I press the button (even if i press them quick) the counter goes up f.e. to 25....

Is there a workaround for that kind of issue?

I take it you have a loop which checks for the button press and you aren't using delay? What happens is that the arduino, which runs at 16Mhz, is so fast that it gets through the loop many times a second. So even a quick press will trigger the code a lot of times. You can use delay to delay a certain # of milliseconds. This will naturally limit the # of cycles. However, another approach would be to check for a button press and then set a button down variable. No more incrementing until a button up is detected. This clears the button down variable and the process starts over.

There's also the issue of debounce. Adding a delay before you check the button state again is one way to avoid debounce problems.

-j

Yeah, I usually debounce by taking two readings about 20-30ms apart.

Try this type of code define your switch and the variable
int varSWITCH_PIN = 0; //variable to store switch presses

if (digitalRead(SWITCH_PIN) == LOW)
{
time = millis();
delay(200); //debounce

// check if the switch is pressed for longer than 1 second.
if(digitalRead(SWITCH_PIN) == LOW && time - millis() >1000)

{
varSWITCH_PIN++; //add 1 Step to next Mode in setup
if(varSWITCH_PIN==8){varSWITCH_PIN=0;} //switch back to 0 after the required modes

// if it is a short press <1000
} else
do something

}

I'm looking building a push button start for my car. I want the following input but am having trouble wrapping my head around it.

single push = ACC on
double push = IGN on
hold = starter on