Hi! I am new here so I hope that you guys can help me with a problem. The following code turns on and off the Pin 13 LED via a button connected to Pin 2.
int val = 0;
int old_val = 0;
int stateOfLED = 0;
void setup(){
pinMode(2, INPUT);
pinMode(13, OUTPUT);
}
void loop(){
val = digitalRead(2); // HIGH if not pressed. LOW if pressed.
if ((val == LOW) && (old_val == HIGH)){
stateOfLED = 1 - stateOfLED; // Changes stateOfLED to OFF when it's ON, and vice versa.
delay(50);
}
old_val = val;
if (stateOfLED == 1){ // Uses stateOfLED to decide if LED 13 is HIGH or LOW.
digitalWrite(13, HIGH);
}
else
{digitalWrite(13, LOW);
}
}
Usually, when the button is pressed, the LED behaves correctly and switches from on to off and vice versa. However, for a few occasions where the LED is off and the button is pushed, the LED will just blink. It remains off when the button is released. This happens too when the LED is on.
I have read that this is due to an effect called bouncing(?) and adding the 50ms delay is supposed to solved this problem. However, the LED behaves the same without the delay too. Am I doing something wrong in the sketch? Thanks.
Debouncing should be done in a while() slope and not by only reading the input once. I remember that I once used delay(125) for good results.
More remarks:
Why don't u use pinMode(2, INPUT_PULLUP) you need only the button between pin and ground (assumed you used an external resistor to 5V), so you use the internal one
A construct like (val == LOW) && (old_val == HIGH) works, but could be done (val != old_val) in a smarter way, couldn't it? When you will be able to write more complex programs, you will like more "readable" code
Try to use digitalWrite(13, (stateOfLED == 1)) instead of that if ... else construct
For more ideas study the lower part of constants - Arduino Reference
You need to think about what problem you are trying to solve with debouncing.
One possibility is that a single button press produces a series of separate ON/OFF events because the contacts don't close or open cleanly. If the Arduino repeats the digitalRead() very quickly it can capture those unwanted events.
If this is the problem then all you need to do is act on the first keypress and then ignore any others for a short time - perhaps a few millisecs. Or perhaps you can disable reading the key until whatever it started has finished (assuming you don't want to use the same key to interrupt the activity)
Another possibility is that spurious key presses are detected even though the key is not touched. Usually this is because the input is floating (i.e. not tied to GND or 5v). But it could happen due to inteference picked up by (say) a long cable.
In that case the phantom key press is probably very short and the simplest way to weed it out is to ignore a key press unless it is held ON for some minimum time - again, perhaps, a few millisecs.