Understanding Jeremy Blum's debounce sketch

Hi everyone, I was watching Tutorial 2 from Jeremy's Arduino series, and I'm trying to make sense of the sketch he uses for debouncing a switch. Here is the sketch:

int switchPin = 8;
int ledPin = 13;
boolean lastButton = LOW;
boolean ledOn = false;
boolean currentButton = LOW;

void setup() {
  // put your setup code here, to run once:
  pinMode(switchPin, INPUT);
  pinMode(ledPin, OUTPUT);
}

boolean debounce(boolean last)
{
  boolean current = digitalRead(switchPin);
  if (last != current)
  {
    delay(10);
    current = digitalRead(switchPin);
  }
  return current;
}

void loop() {
  currentButton = debounce(lastButton);
  // put your main code here, to run repeatedly:
  if (lastButton == LOW && currentButton == HIGH)
  {
    ledOn = !ledOn;
  }
    lastButton = currentButton;
  digitalWrite(ledPin, ledOn);
}

My question is the following: The global boolean variable 'lastButton' is initialised to low, so I can see how the conditions of the very first if loop would be satisfied. But then 'lastButton' is set to currentButton, and that marks the end of the loop. So how can 'lastButton' ever return back to LOW?

My understanding is that programs are run from the very beginning (with the initialisation of global variables in this particular sketch), then the setup function, and then continue repeating the loop (without starting from the very top of the sketch). And so after the first loop function is performed the arduino wouldn't start reading from the very top of the program again, thus precluding the possibility of 'lastButton' being reset to low. Is this understanding valid?

If so, how would the conditions of the if statement within the loop ever be satisfied after the first iteration?

Thank you!

When programs are compiled: 1. The compiler/ linker will set the global variables to the starting/default values. There is no code executed unless you are declaring classes, in which case the class constructor is executed. 2. The setup function is run once. 3. The loop function is run continuously. Conceptually, when you get to the end it starts at the top again.

Loop() program flow: A. currentButton is set to the current state of the switch (HIGH or LOW). B. if the previous state was LOW and the new state is high (ie, we have had an on to off transition), then flip the state of the LED. C. Set the last button state to the current state (HIGH or LOW).

So the transitions will look like this: last = LOW, current = LOW --> starting state last = LOW, current = HIGH --> switch has been pressed and LED state toggled last = HIGH, current = LOW --> switch has been released, do nothing last = LOW, current = LOW --> back to starting state

Ahh, the release phase! Can't believe that escaped my mind. In the future I should probably log variables onto the serial monitor, that would be pretty helpful for a noob like myself.

Thanks very much for your reply marco_c, really appreciate it :)

See tip #9: http://www.gammon.com.au/forum/?id=12153

Having the value "LOW" for a boolean, isn't very good.

Thanks for that link LarryD!

Michinyon, would you mind elaborating? In my programming experience I typically use ‘true’/‘false’ or ‘0’/‘1’, but my understanding is that’s just a matter of preference.

If you want to define a boolean variable then the proper values to assign to it, are true, or false. That's not the same as a boolean expression or a conditional expression.