While Loop Loops 1 Too Many Times

I have a while loop that turns the pin 13 LED on and off, and then repeats the flashing until a switch is opened.

The switch is connected between pin 2 and ground.
If the switch is open when the sketch starts, the LED never flashes. This is what I expect to happen.

If the switch is closed when the sketch starts the while loop flashes the LED until the switch is opened.

The problem is the following: If the sketch starts with the switch closed, and I open the switch as soon as I see the LED illuminate, the sketch completes the loop and goes through it one more time, even though the switch status is checked at the bottom of the loop. The on and off states of the LED last for 2000 ms each, so there is plenty of time to me to release the switch, I would think, before the switch status is updated at the bottom of the loop.

This problem was first seen with a motor controller shield. I've recreated the problem with the LED to simply the situation.

The loop is in the setup() portion of the sketch by design.

What am I missing?

#include <Bounce2.h>

//  autoManPin - HIGH (default) = auto mode, LOW = manual/stop mode
const int autoManPin = 2;

//  set debounce interval
const uint16_t dbTime = 5;

//  create debounced switch object
Bounce autoManLine = Bounce();

const int LED_PIN = 13;

//  =============== SETUP ===============
void setup() {
  pinMode(LED_PIN, OUTPUT);


  //  connect internal pull-up resistors on switch lines
  //  N.B. pull-up must be set before pin assignment to function properly
  //  attach debounce switches to pins, debounce time interval

  //  MANUAL-STOP/AUTO switch line
  pinMode(autoManPin, INPUT_PULLUP);
  autoManLine.attach(autoManPin);
  autoManLine.interval(dbTime);
 
  //  update autoManLine switch
  autoManLine.update();
  int autoManLineValue = autoManLine.read();
  
  //  WHILE SWITCH SET TO MANUAL (LOW value)
  while (autoManLineValue == LOW) {
    
    digitalWrite(LED_PIN, HIGH);
    delay(2000);

    digitalWrite(LED_PIN, LOW);
    delay(2000);
    
    //  UPDATE SWITCH POSTION BEFORE LOOPING
    autoManLine.update();
    autoManLineValue = autoManLine.read();
  }
    
}

//  ==========  LOOP  ==========
void loop() {
}

dfitterman:
even though the switch status is checked at the bottom of the loop.

Not with a while loop. That would only be true of a do-while loop.

I'm not exactly sure what you are suggesting.
I am not using a DO-WHILE loop as I want to complete the flashing action at least once, repeating until the switch is opened.

The hardware always completes the current flash plus one more, even when switch is opened while the LED is illuminated. The switch status is read after the LED off state ends.

By switch status, do you mean "autoManLineValue"? It is checked at the top of the loop, as I said.

aarg:
By switch status, do you mean "autoManLineValue"? It is checked at the top of the loop, as I said.

Yes, autoManLineValue is the switch status, either HIGH for open or LOW for closed.

dfitterman:
Yes, autoManLineValue is the switch status, either HIGH for open or LOW for closed.

You claimed that it was checked at the end of the loop. I dispute that. That could affect your exit conditions, you did complain about too many iterations...

It's not "checked" at the end, it's assigned at the end. Big difference.

dfitterman:
...even though the switch status is checked at the bottom of the loop.

I would strongly suggest you Google how a while loop actually works in c, rather than just make (incorrect) assumptions based on how you'd like it to work...
Regards,
Ray L.

The .update() method of the Bounce2 library calls a debounce routine. The default method requires a stable reading of at least the debounce interval between calls to .update(). If you want the flashing to stop when the switch is opened when seeing the led on, you need another call to .update() in the while loop.

while (autoManLineValue == LOW) {
    digitalWrite(LED_PIN, HIGH);
    delay(2000);
    autoManLine.update();//add another call
    digitalWrite(LED_PIN, LOW);
    delay(2000);
    
    //UPDATE SWITCH POSTION BEFORE LOOPING
    autoManLine.update();
    autoManLineValue = autoManLine.read();
  }

Alternatively, you can modify Bounce2.h to use a different debounce methodology

// Uncomment the following line for "BOUNCE_WITH_PROMPT_DETECTION" debounce method
//#define BOUNCE_WITH_PROMPT_DETECTION