Reading how long a button is held down?

I want to be able to have a pin set to high after a button is held down for 2 seconds.

How would I do that?

try looking at pulse in

http://arduino.cc/en/Reference/PulseIn

I looked into that and tested it just now, and I think I can use it... but I'm not sure how.

I need the pin to set to high as soon as it hits 2 seconds. Using pulseIn, I would need to let go of the button at 2 seconds. I want it to read how long the button is HIGH and then set the pin as HIGH as soon as it hits 2 seconds.

How would I do this lol

A combination of saving the button's state, and time of last state change (using millis()) should allow you to determine when the button has been held down for more than two seconds (or 2000 milliseconds).

How would I do that?

not tested, off the top of my head the idea goes something like …

// not tested
int del = 2000;
unsigned long oldTime;

void setup(){}

void loop()
{
  unsigned long time = millis();
  if((button == HIGH) && (time > (oldTime + del)))
  {
    // do stuff
    oldTime = time;
  }
}

edit, had a < needed a >

if((button == HIGH) && (time < (oldTime + del)))

Since time and oldTime are both longs, there is a potential (slight) for overflow to occur, with the necessity of holding the button down for about 59 days, with this code.

Changing it to:

if((button == HIGH) && ((time  - oldTime) < del))

avoids that problem.

good point

Nope.

I need to be able to check the time the button goes HIGH, and 2 seconds later it needs to write the pin.

I think the main thing I'm having problems with is setting a variable to the time when the button goes HIGH.

Post your code, then. It should be straight-forward to do what you want..

I want to be able to have a pin set to high after a button is held down for 2 seconds.

::)

;D

I know you guys have to be right, so don’t think I’m just ignoring your efforts, haha.

It’s just not working for me.
It’s setting the pin high as soon as I press the button.

Here’s my code (the stuff pertaining to this, only)

const int guide = 11;
const int power = 10;

int guidestate = LOW;
unsigned long oldTime;
int pwrtime = 2000;
unsigned long time;

void setup(){
pinMode (guide, INPUT);
pinMode (power, OUTPUT);
}

void loop(){
guidestate = digitalRead(guide);
if ((guidestate == HIGH) && ((time - oldTime) < pwrtime)){
oldTime = time;
digitalWrite(power,HIGH);
}
}

void loop(){
 guidestate = digitalRead(guide);

 time = millis(); // <<<<<<

 if ((guidestate == HIGH) && ((time - oldTime) < pwrtime)){
   oldTime = time;
   digitalWrite(power,HIGH);
 }
}

It still doesn't work =/

void loop(){
 guidestate = digitalRead(guide);
 time = millis(); 
 if ((guidestate == HIGH) && ((time - oldTime) > pwrtime)){  // <<<<<<
   oldTime = time;
   digitalWrite(power,HIGH);
 }
}

Nope, still sets the pin high as soon as I press the button.

Ok first! (yay)

I want it to read how long the button is HIGH

is one way of doing it, but a easier and more logical approach is to set the pin high and let the button pull it to ground when depressed

ie: you push a button down, when you let go it goes back up, shouldn’t your logic do the same?

bearing that in mind look at this schematic

and here’s a working example sketch for that schematic. what was holding everything up was where the oldTime was updated, now its updated every loop that the button pin reads HIGH, when pressed down to LOW the update halts and the 2 second time is dealt with.

This also has the effect of ignoring random pushes on the button < x ms

const int guide = 11;
const int power = 10;
const int pwrtime = 2000;

unsigned long time;
unsigned long oldTime;
int button;

void setup()
{
  pinMode (guide, INPUT);
  pinMode (power, OUTPUT);
  digitalWrite(guide, HIGH); // turn on pull up resistors
  // Serial.begin(9600); //DEBUG
}

void loop()
{
  button = digitalRead(guide); // read digital pin 1 = button up, 0 button down
  time = millis(); // get the time
  
  // Serial.print(time); //DEBUG
  // Serial.print(" | "); //DEBUG
  // Serial.print(oldTime); //DEBUG
  // Serial.print(" | "); //DEBUG
  // Serial.print(time - oldTime); //DEBUG
  // Serial.println(""); //DEBUG
  if(button)
  {
    oldTime = time;
  }  
  else if(!button && ((time - oldTime) >= pwrtime))
  {    
    digitalWrite(power,HIGH);
  }
  // delay(500); //DEBUG
}

btw this was actually kind of a pain in the butt, so good question.

It doesn't work with my current setup, but I'm going to rewire it (the thing that I have my arduino in is currently closed up) tomorrow afternoon.

I'll let you know how it goes.

One good thing that came of this is that now I understand more of the syntax for this.. haha. Thanks guys.

yea its 3 changes

digitalWrite(guide, HIGH); // turn on pull up resistors
//digitalWrite(guide, HIGH); // turn on pull up resistors
if(button)
if(!button)
else if(!button && ...
else if(button && ...

Shouldn't I be able to adapt this for my hardware setup? The button connects 5v to pin 11, setting it HIGH when it's pressed.

In your code, I would need my button connecting GND. Wouldn't I be able to adapt this? I changed it to write the button pin as LOW in the setup, but that doesn't help at all.

I'm probably missing something really simple, here..