How does this use of an undefined variable actually work?

I have been studying the following example piece of debouncing code, which comes with the Arduino IDE, to understand how it works. I am puzzled by the use of a variable with an undefined value - " int buttonState".

After declaring buttonState, the next time you see it is in the following section of code -
if (reading != buttonState) {
buttonState = reading;

If I understand correctly, buttonState could be any value the first time it is used.
I am probably being stupid here - but how does it work, please?

/*
  Debounce
  This example code is in the public domain.
  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Debounce
*/

// 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 = 13;    // 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(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);

  // set initial LED state
  digitalWrite(ledPin, ledState);
}

void loop() {
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);

  // 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 the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  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 the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // only toggle the LED if the new button state is HIGH
      if (buttonState == HIGH) {
        ledState = !ledState;
      }
    }
  }

  // set the LED:
  digitalWrite(ledPin, ledState);

  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;
}

buttonState is declared as a global variable so will have a default value of zero when declared

1 Like

Thank you UKHeliBob!

but you were right to ask because it's not great coding practice.

The default value of 0 is kind of a magical number which matches the value of LOW. This could have in other circumstances a bad consequence.

2 Likes

the code you posted doesn't return that a button has been pressed until after the debounce period.

the following code immediately returns that a button has been pressed and doesn't read the button until after the debounce period expires.

the debounce period is 500 msec

// demonstrate switch debounce

// Capitalize Constants
const int ButtonPin = 2;                    // pin number of pushbutton
const int LedPin    = 13;                   // pin number of LED

const unsigned long DebounceDelay    = 500; // debounce period in msec
      unsigned long lastDebounceTime = 0;   // timestamp

int buttonState;                            // current button state

enum { Off = LOW, On = HIGH };              // specify On/Off state

// -----------------------------------------------------------------------------
// report if button pressed, wait for debounce period to expire
bool
butPress ()
{
    if ((millis() - lastDebounceTime) < DebounceDelay)
        return false;

    byte but = digitalRead (ButtonPin);

    if (buttonState != but)  {
        buttonState      = but;         // state change
        lastDebounceTime = millis();    // reset debounce time

        return LOW == but;
    }

    return false;
}

// -----------------------------------------------------------------------------
void loop ()
{
    // toggle LED if button pressed
    if (butPress ())
        digitalWrite (LedPin, ! digitalRead (LedPin));  // toggle LED
}


// -----------------------------------------------------------------------------
void setup()
{
    Serial.begin (115200);

    pinMode(ButtonPin, INPUT_PULLUP);
    pinMode(LedPin,    OUTPUT);

    digitalWrite(LedPin, Off);
}
2 Likes

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.