• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Pushbutton with long-press and short-press functionality

VanDerMax

New Member
I am trying to understand this function on the simples possible setup as attached in the image, using the internal pullup for the input pin. I tried few sketches found online but for some reason, they behaved outside of what I expected, random behavior.

The goal I'm after is simple - if I press the pushbutton it turns the internal (13) LED on, and lets say if I keep it pressed for 3 seconds, the LED starts to flash. How complex is this?
 

Attachments

throbscottle

Well-Known Member
You're not showing a pullup resistor on your drawing. Connect 10k between the input and .... I dont' know whether it should be 3.3v or 5v - whichever one is the Arduino's supply voltage. Without this the input voltage can wander about all over the place when the button isn't pressed.
 

rjenkinsgb

Well-Known Member
Most Helpful Member
Simple way:

When the button is pressed, do the first action, then zero a variable to store a count.

While it is still pressed, run a loop that does eg. a 1mS delay then increments a count variable.
Keep looping as long as the button is held in.

When the button is released, looks at the value in the count variable to see how long it was held for and take appropriate action.


Better way, but more complex, suited for things that you do not want to freeze while the button is pressed (eg. other parts of the program must keep running and doing things):

Have a timer interrupt set up in the program startup, that causes a regular interrupt at eg. 1KHz or 10KHz.
In that interrupt routine, increment a counter (or set of counter) variables to track the time.

Also in that interrupt, or in separate "pin change" interrupts, monitor the button input and save the times it is pressed and released, as well as taking action at the press and looking at the time when it is released.

That's a "real time programming" approach; nothing ever stops the program, you never use delay loops.
 

Pommie

Well-Known Member
Most Helpful Member
Here's some code to start with, it does the push button stuff and I'll let you try doing the LED stuff.
Code:
#include <stdint.h>

#define KEY A0

uint8_t key=1,previous=1;
uint16_t keyCount;
uint32_t tickKey;

void setup(){
  Serial.begin(115200);
  Serial.println("Begin.");
  pinMode(KEY,INPUT_PULLUP);
}

void loop(){
  if((millis()-tickKey)>20){          //do every 20mS
    tickKey=millis();                 //reset counter
    key=digitalRead(KEY);             //read key
    if(previous==1 && key==0){        //is it a new key press
      Serial.println("Key Pressed, light LED.");
      keyCount=2000/20;               //2 seconds delay started
    }else if(previous==0 && key==1){  //has key been released?
      Serial.println("Key released, turn LED off.");
    }
    previous=key;                     //keep copy of key
    if(key==0 && keyCount>0){         //key pressed and counter running
      if(--keyCount==0){              //count down and if zero, 2 seconds are up
        Serial.println("2 seconds up, flash LED");
      }
    }else{
      keyCount=0;
    }
  }
  //any code here will run continuously.
}
Let us know how you get on.

Mike.
Edit, note it is non blocking so any code you put at the end of the loop will run continuously.
 
Last edited:

Latest threads

EE World Online Articles

Loading
Top