checking button hold for a period of time

Hi guys i have this another timing sketch below .. another different encounter in programming timings in arduino for me..hehe..

this is what the sketch does:

*at button press/hold

  • PROCESS1 - the ledPin will be ON for 500UL and then OFF

*when the button is released from pressing or holding
-PROCESS2 - the ledPin will be ON again for 500UL and then OFF

but what i want to happen is to check if the button is pressed or held for exactly 4s BEFORE process1 occurs , that is;

if button is held for 4s

  • do process 1
  • proceed to process2 if button is released
  • loop from the start (check again if button is held for 4s)

i'm having a hard time thinking of a way to check the presence of button hold for 4s, mind if u may help me with this one
thanks ! XD

const int ledPin =  13;      // the number of the LED pin
unsigned long startTime;        // will store last time LED was updated
const int DisplayButton = 2; 
int lastButtonState = 0; 
int ledState;
unsigned long interval = 500UL;           // interval at which to blink

void setup() 
{
  pinMode(ledPin, OUTPUT);  
  pinMode(DisplayButton, INPUT);  
}

void loop()
{ 
  int buttonState = digitalRead(DisplayButton);
  if (buttonState != lastButtonState) // on any state change...
  {
    startTime = millis();// .... reset the timer
  }
  lastButtonState = buttonState;
  
  if (millis() - startTime <= interval)
  {
    digitalWrite(ledPin, HIGH);
  }
  else
  {
    digitalWrite(ledPin, LOW);
  } 
}

You can do something like this.

const byte Led = 13;
const byte Button = 2;
unsigned long time;
bool reset = false;

void setup() 
{
  // put your setup code here, to run once:
  pinMode(Led, OUTPUT);
  pinMode(Button, INPUT);
}

void loop()
{
  // put your main code here, to run repeatedly:
  if(digitalRead(Button) && !reset) // check if button is pressed /held "HIGH" and reset is false
  {
     time = millis();
     reset = true;
  }

  if(!digitalRead(Button) && reset) //Check if button is released "LOW" and reset is true
    reset = false;
    
  if(digitalRead(Button) && (millis() - time > 3000)) // if button is HIGH and 3 seconds has passed, LED on.
  {
    digitalWrite(Led, HIGH);
  }
  else
    digitalWrite(Led, LOW); // otherwise LED off

}

that was great ! however,

say that in the sketch,if 4s has passed, the led will be lit , but it wont turn off ,not until the button is released,,,

if 4s has passed and the button is still pressed, the led must be lit on for 500UL only and then off , even if i am still holding the button ,, and the same will happen when i release the button .
tnx !

So use a second timer for when the LED goes on.

You will also need another boolean state.

1 Like

You might find it useful to read about State Machines

Nick has a tool that might help.
I have used it in a similar situation you are in.
SwitchManager
See reply #1

Download the ZIP file (library) found at the end of the thread.

LarryD:
Nick has a tool that might help.

I knew I had seen such a tool before, couldn't remember where, now bookmarked. Thanks.

how can i exactly use this
mySwitch.check (); if i would like to check for presses ?

and how can i use it to determine how long it has been when the switch has changed state ?

I collected sections out of working code to give you an idea of how you can use the SwitchManage to monitor a switch push for different times.
ex: 250ms, 1 second and 3 seconds.
When these times are met you can do what ever you have to do.

#include <SwitchManager.h>
SwitchManager modeSW;  // create the object

const byte ModeSW = 4;             //input from the Mode push button switch     

void setup ()
{
 modeSW.begin (ModeSW, modeSwitchManager);
}
//======================== END OF setup ==========================



void loop ()
{
  //check to see what's happening with the Mode switch
  modeSW.check();

//other suff

}
//======================== END OF loop ===========================




//                M O D E   S W I T C H   M A N A G E R
//****************************************************************
// function looks after the Mode switch functions
void modeSwitchManager (const byte newState, const unsigned long interval)
{
  if (newState == HIGH)  //in this case ignor a switch release
  {
    return;
  }

  //newSatate must be LOW

  //Are we switching to a new mode?
  if (interval <= 250)  //has it been < 1/4 second since the last push?
  {
    modeNumber++;
    if (modeNumber > 6)  //only modes 0-6 are allowed in ths sketch
    {
      modeNumber = 0;
    }

    //Udate to the new display mode
    switch (modeNumber)
    {
      //------------------------------------------------------------
    case 0:           //In put pulse counter   displays CXXXXXXX
      //start out at zero so it takes 3 pushes reset the Prescaler
      resetCounter = 0;

      break;

      //------------------------------------------------------------
    case 1:          //Frequency counter       displays FXXXXXXX
      flag = true;
      i = 0;

      break;

      //------------------------------------------------------------
    case 2:          //High Pulse Width        displays HXXXXXXX
      prepareForInterrupts ();   

      break;

      //------------------------------------------------------------
    case 3:          //Low Pulse Width         displays LXXXXXXX
      prepareForInterrupts ();   

      break;

      //------------------------------------------------------------
    case 4:          //Auto range voltmeter    displays EXXXXXXX
      //
      break;

      //------------------------------------------------------------
    case 5:          //Pulse output 1X         displays P1_XXXXX
      clear7219();
      configure (modeNumber);
      //start out at zero
      pulsesSent = 0UL;
      break;

      //------------------------------------------------------------
    case 6:          //Pulse output 10X        displays P10XXXXX
      clear7219();
      configure (modeNumber);
      //start out at zero
      pulsesSent = 0UL;
      break;

      //------------------------------------------------------------

    } //  END of switch(mode)

    return;
  }

  //Check to see if we want to reset the 4040 Hardware Prescaler
  //modeNumber 0, this is input pulse counting mode 
  if (modeNumber == 0 && interval >=1000)
  {
    resetCounter++;        //if we ever get up to 2 then we are going to reset the Prescaler

    if (resetCounter >= 2)
    {
      resetCounter = 0;

      //do it
      //Initailize the Prescaler
      digitalWrite(RST,HIGH);  //reset the Prescaler, i.e. a HIGH resets a LOW enables  
      digitalWrite(RST,LOW);   //enable the Prescaler
      topPScounter = 0UL;      //reset the overflow register
    }
    return;
  }

  //*****************
  //Check to see if we want to send one pulse out on the pulse probe
  //modeNumber 5, this is pulse output X1 mode  
  //Have to wait initially 3 seconds then 1 sec there after 
  if (modeNumber == 5 && interval >=3000)
  {
    pulsesSent++;
    pulseOutput(1);
    return;  
  }  

  else if (modeNumber == 5 && pulsesSent > 0 && interval >=1000)
  {
    pulsesSent++;
    pulseOutput(1);
    return;  
  }  

  //Check to see if we want to send 10 pulses out on the pulse probe
  //modeNumber 6, this is pulse output X10 mode
  //Have to wait initially 3 seconds then 1 sec there after
  else if (modeNumber == 6 && interval >=3000)
  {
    pulsesSent += 10;
    pulseOutput(10);
    return;    
  }
  else if (modeNumber == 6 && pulsesSent > 0 && interval >=1000)
  {
    pulsesSent += 10;
    pulseOutput(10);
    return;  
  }  
  //*****************

  return;

}  //                  END of modeSwitchManager()

A bit cleaner version maybe?

#include <SwitchManager.h>
SwitchManager modeSW;  // create the object

const byte ModeSW = 4;             //input from the Mode push button switch     

void setup ()
{
  modeSW.begin (ModeSW, modeSwitchManager);
}
//======================== END OF setup ==========================



void loop ()
{
  //check to see what's happening with the Mode switch
  modeSW.check();

  //other suff

}
//======================== END OF loop ===========================




//                M O D E   S W I T C H   M A N A G E R
//****************************************************************
// function looks after the Mode switch functions
void modeSwitchManager (const byte newState, const unsigned long interval)
{
  if (newState == HIGH)  //in this case ignor a switch release
  {
    return;
  }

  //the newSatate must be LOW

  //-----------------------------------
  if (interval >=3000)
  {
    //do stuff for 3 seconds
    return;  
  }  

  //-----------------------------------
  if (interval >=1000)
  {
    //do stuff for 1 second
    return;
  }

  //-----------------------------------

  if (interval <= 250)  
  {
    //do your stuff for < 1/4 second push
    return;
  }

  return;

}  //                  END of modeSwitchManager()

sorry for this (awkward, i think) question but i want to ask,

if the process goes to
" return; "
where does it go ?

if the process goes to
" return; "
where does it go ?

Back to finish whatever is left in the loop() function.

When the loop() function finishes it's last instruction, execution starts at the top of the loop() function once again and things repeat over and over. . . .

Tnx ! it WORKED !

Thanks to Nick Gammon!
:sleeping:
Night time