I really need someone to explain the Debounce code example to me line by line. I am getting lost in the loop and when it is kicking out of the if statements. I have posted the code I am using. I have everything set up correctly and the circuit is behaving as expected. LED light is on when the code is loaded and turns off and stays off when I press the button until I press it again. It's really the code I am struggling with understanding. Any help is appreciated.
//Debounce
/* Each time the input pin goes from LOW to high (e.g. because of a push-button press),
the output pin is toggled from LOW to HIGH or HIGH to LOW. There's a minimum delay
between toggles to debounce the circuit (i.e to ignore noise)
The Circuit:
LED attached from PIN 8 to ground through 220 ohm resistor.
Push button attached to pin 2 from +5V
10K resistor attached to pin 2 from ground
*/
//Constants won't change. They're used here to set pin numbers:
const int buttonPin = 2; //The number of the pushbutton pin.
const int ledPin = 8; //The number of the LED pin.
//Variables will change:
int ledState = HIGH; //The current state of the output pin.
int buttonState; //The current reading from the input pin.
int lastButtonState = LOW; // The previous reading from the input pin.
//The following variables are unsigned longs because the time, measured in
//milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0; //The last time the output pin was toggled.
unsigned long debounceDelay = 50; //The debounce time; increase if the output flickers
void setup()
{
pinMode(ledPin, OUTPUT); //Initialize the LED pin as an output.
pinMode(buttonPin, INPUT); //Initialize the pushbutton pin as an input.
digitalWrite(ledPin, ledState); //Set initial LED state
}
void loop()
{
int reading = digitalRead(buttonPin); //Read the state of the switch into a local variable:
//Check to see if you just pressed the button
//(i.e. the input went from LOW to HIGH), and you've waited long enough
//since the last press to ignore any noise:
if (reading != lastButtonState)
{
lastDebounceTime = millis(); //Reset the debouncing timer
}
if ((millis() - lastDebounceTime) > debounceDelay)
//Whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
{
if (reading != buttonState) //If the button state has changed:
{
buttonState = reading;
if (buttonState == HIGH) //Only toggle the LED if the new button state is high
{
ledState = !ledState;
}
}
}
digitalWrite(ledPin, ledState); //Set the LED:
lastButtonState = reading; //Save the reading. Next time through the loop, it'll be the lastButtonState:
}
You can learn what the code is doing by adding the ability to use your serial.Print() to display a line identifier and the variable values for each variable in the line of code.
Then after the line, display the results if there is a compare or function call, etc.
I tried doing that for one line of code to check it and got a result I did not understand. I assume I would need to start the serial monitor in the setup code. Would you be willing to provide a short example in the loop code to describe what you mean. In the mean time I am going to play around with the code in the manner I think you are suggesting to see what I get.
I was getting lost really bad in the if statements. I am applying Paul_KD7HB suggested methodology by using the serial monitor and I am adding delays to slow the serial monitor down so I can read it. A little clunky but getting the job done to help me understand a little better.
Yeah when I was taking a look at it ignoring the whole debounce code I felt like the code would still accomplish turning the LED on and off by pressing the button as long as I wait long enough between presses. Which I really would not have to wait that long. Correct me if I am wrong.
I kind of sort of figured it now. Yep I get the need for debounce code when it is looping so fast. Still trying to understand the debounce code. I know what it is doing just not sure how. However I will say that when I took the debounce code out and properly spaced all of the if statements I was able to follow the code a lot better. So I save the example with and without the debounce code for future reference. I really appreciate everyone's input. I am still learning and following the examples built into the IDE but for some reason I feel like the code to turn the LED on/off with the button could have been done in way fewer lines of code. Maybe I am wrong though.
void loop()
{
int reading = digitalRead(buttonPin);
if (reading != lastButtonState)
lastDebounceTime = millis();
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == HIGH)
ledState = !ledState;
}
}
digitalWrite(ledPin, ledState);
lastButtonState = reading;
}
this code seems unnecessarily complicated and may not work reliably
after recognizing a state change, a timestamp is captured
when the timer expires, it attempts to toggle ledState when the button is released. the additional check that the button state has changed, seems unnecessary
the other issue is what the button state is when pressed. buttons are typically connected between the pin and ground, the pin configured as INPUT_PULLUP to use the internal pullup resistor which pulls the pin HIGH and when pressed, the button pulls the pin LOW.
this seems a bit clearer
int reading = digitalRead(buttonPin);
if (reading != lastButtonState) {
lastButtonState = reading;
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (buttonState == LOW)
ledState = !ledState;
digitalWrite(ledPin, ledState);
}
}
but unless there's some severe real-time restriction where the code can't tolerate a 20 msec delay, why not simply
int reading = digitalRead(buttonPin);
if (reading != lastButtonState) {
lastButtonState = reading;
delay (20); // debounce
if (buttonState == LOW)
ledState = !ledState;
digitalWrite(ledPin, ledState);
}
}
This is exactly why variable names are so important.
The sketch in the OP has 3 variables tracking the various button states.
They are: reading, buttonState and lastButtonState.
I just changed them to: newButtonState, currentButtonState and previousButtonState.
I think that makes it a whole lot easier to understand whats happening. YMMV
//Debounce
/* Each time the input pin goes from LOW to high (e.g. because of a push-button press),
the output pin is toggled from LOW to HIGH or HIGH to LOW. There's a minimum delay
between toggles to debounce the circuit (i.e to ignore noise)
The Circuit:
LED attached from PIN 8 to ground through 220 ohm resistor.
Push button attached to pin 2 from +5V
10K resistor attached to pin 2 from ground
*/
//Constants won't change. They're used here to set pin numbers:
const int buttonPin = 2; //The number of the pushbutton pin.
const int ledPin = 8; //The number of the LED pin.
//Variables will change:
int ledState = HIGH; //The current state of the output pin.
int currentButtonState; //The current reading from the input pin.
int previousButtonState = LOW; // The previous reading from the input pin.
//The following variables are unsigned longs because the time, measured in
//milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0; //The last time the output pin was toggled.
unsigned long debounceDelay = 50; //The debounce time; increase if the output flickers
void setup()
{
pinMode(ledPin, OUTPUT); //Initialize the LED pin as an output.
pinMode(buttonPin, INPUT); //Initialize the pushbutton pin as an input.
digitalWrite(ledPin, ledState); //Set initial LED state
}
void loop()
{
int newButtonState = digitalRead(buttonPin); //Read the state of the switch into a local variable:
//Check to see if you just pressed the button
//(i.e. the input went from LOW to HIGH), and you've waited long enough
//since the last press to ignore any noise:
if (newButtonState != previousButtonState)
{
lastDebounceTime = millis(); //Reset the debouncing timer
}
if ((millis() - lastDebounceTime) > debounceDelay)
//Whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
{
if (newButtonState != currentButtonState) //If the button state has changed:
{
currentButtonState = newButtonState;
if (currentButtonState == HIGH) //Only toggle the LED if the new button state is high
{
ledState = !ledState;
}
}
}
digitalWrite(ledPin, ledState); //Set the LED:
previousButtonState = newButtonState; //Save the reading. Next time through the loop, it'll be the previousButtonState:
}