Receiving Input From Button Click

I just received my first Arduino yesterday and have been taking some basic tutorials to get started. However I have yet to have a tutorial explain how to solve this issue. I have a button that I want to turn on and off an LED. Turn on after one click and turn off after the next click. Connecting the led and button, and controlling the input and output is not an issue. My problem is that my code checks to see if the light is off and if the button is pressed also. If this is true the light turns on. Then if it is the other way (light on and button pressed) it turns off the light. The problem is that because the program loops any one button click turns on and off the light multiple times. So to fix this I delay after each change in the LED state. I realize though that this code is not ideal because I cannot receive multiple inputs i.e(having more than one button doing other things) without the program freezing every time I receive input. So how would you make this code work without delaying. Any advise would be helpful thanks .

void ledStatus() //
{
  if(ledState == false && val[0] == LOW)
  {
    digitalWrite(led, HIGH);
    ledState = true;
    Serial.println("setting led on");
    delay(500);
    
  }
  else if(ledState == true && val[0] == LOW)
  {
    digitalWrite(led, LOW);
    ledState = false;
    Serial.println("setting led off");
    delay(500);
  }
  Serial.println(ledState);

You might want to look at the Button library. It helps deal with de-bouncing.

I will put a question about reading a button or switch using X=digitalRead(anypin); I think it related to this tread.

Question : What is the number of millisecond for de-bouncing for a switch ( SPST, SPDT, ect ) and a push-on/off switch ?

X=digitalRead(mypin);
delay(???);

What is the number of millisecond for de-bouncing for a switch ( SPST, SPDT, ect ) and a push-on/off switch ?

Forever. None of these type of switches are momentary contact switches that need debouncing.

For momentary contact switches, 10 milliseconds if generally plenty.

Forever. None of these type of switches are momentary contact switches that need debouncing.

Actually there really are SPST, SPDT, etc, momentary switches avalible and contact debouncing often can apply to any mechanical switch, not just momentary ones, depending on the application and code used.

Lefty

So 10 ms is the general standard debounce time ?

So 10 ms is the general standard debounce time ?

The actual minimum debounce time required is dependent on the specific mechanical switch contacts one it dealing with. There is no universal number that will satisfy all contacts. 10 msec is as good as any value to start with, but no guarantee.

Lefty

I measured a button a while back:

As you can see, the bouncing stopped after about 4 mS, so 10 mS should be plenty. Of course, different buttons might behave differently. YMMV in other words.

Anyway, this is surprisingly hard to get right. Try, if you don’t believe me :wink:

This seemed to work for me, I had a Uno set up so I just connected pin 7 to ground (to simulate a switch) and toggle the inbuilt LED if I did.

The code doesn’t use any delays, so you should be able to do other stuff. I would be tempted to use interrupts but I don’t want to stray too far from the original question. :stuck_out_tongue:

#define DEBOUNCE_TIME 20

unsigned long button7changed;   // when it changed states
int button7previous = HIGH;     // previous value

void setup ()
{
  pinMode (13, OUTPUT);
  digitalWrite (7, HIGH);  // enable pull-up resistor
}  // end of setup

void loop ()
{
  int button7value = digitalRead (7);
  unsigned long now = millis ();

  // look for change in switch, and allow for debounce
  if (button7value != button7previous &&
    (now - button7changed) >= DEBOUNCE_TIME)
  {
    // if low, then switch pressed (grounded)
    if (button7value == LOW)
      digitalWrite (13, !digitalRead (13));  // toggle LED

    button7previous = button7value;
    button7changed = now;

  }  // end of if button changed

}  // end of loop
1 Like

Excellent work Nick Gammon. According to your research, a mininum of 4 ms is needed for a delay after a digitalRead when a switch is use. So therefore a value of 4 to 10 should be use in a delay statment for debounce time.

example : x=digitalRead(anydigitalpin);
delay (4); // ← minimum of 4 ms

My conclusion.

PS: nice digital logic analyser Nick, I would love to buy one, but I am to poor… :stuck_out_tongue: