My brain hurts. Please help

You haven't read far or wide or deep. We can and do run out of patience. :expressionless:

But as long as there is effort and progress and we see listening and heeding, it lasts.

I took @Delta_G's code and changed it a bit to suit my own habits.

The major difference is the debounce timing. I move that to the first thing the function checks. "is it too soon to even look at the (possibly bouncing) button again?".

Try it here:

Wokwi_badge UA Single Button Reference Sketch


// https://wokwi.com/projects/402305903980081153
// https://forum.arduino.cc/t/my-brain-hurts-please-help/1277379

bool animation1Playing;
uint32_t currentMillis;

const int button1Pin = 6;
const int theLED = 7;

void setup() {
  pinMode(button1Pin, INPUT_PULLUP);
  pinMode(theLED, OUTPUT);
}

void loop() {
  currentMillis = millis();

  buttons();

  if (animation1Playing) digitalWrite(theLED, HIGH);

  if (!animation1Playing) digitalWrite(theLED, LOW);
}


# define PRESST LOW  // for switches puuled up and wired to ground

void buttons() {
  static uint32_t lastMillis;
  const uint32_t debounceTime = 20;
  static bool lastButton1State;

// too soon to even look?
  if (currentMillis - lastMillis < debounceTime) return;

  bool currentButton1State = digitalRead(button1Pin) == PRESST;  // true is pressed

  if (lastButton1State != currentButton1State) {

    if (currentButton1State) {
      animation1Playing = !animation1Playing;
    }

    lastButton1State = currentButton1State;
    lastMillis = currentMillis;   // so we don't even look again until
  } 
}

In @Delta_G's code, this edge handling got changed, I believe it is flawed and will follow the button state, not the button change:

      if (currentButton1State == button1Pressed) {
        animation1Playing = true;                      
      } else {
        animation1Playing = false;
        lastMillis = currentMillis;
      }

I think lastMillis needs to be advanced when animation1Playing is set true as well as when set false - debounce both edges.

Compare to this, which toggles on the rising edge and ignores the falling edge:

  if (lastButton1State != currentButton1State) {

    if (currentButton1State) {
      animation1Playing = !animation1Playing;
    }

    lastButton1State = currentButton1State;
    lastMillis = currentMillis;   // so we don't even look again until
  } 

I will say I had mucho trouble getting this right, feeling my inner Joe Biden I guess, and may well not have yet. It is a bitch, for something that has rolled off my fingers too many times. I think I get in trouble working from other ppl's code - the pattern can look correct, at a glance, and familiar, but if all the parts aren't just right, you sunk.

Having said all we have, and while I think it is important to code this kind of thing for one's self at least once, and I can't believe I am caving, but...

The ezButton library doesn't suck and is, in fact, EZ to use. I'll post the wokwi simulation I have that shows the least one needs to know about it, and say aloud there is no shame in using it, and spending the energy on the real problems.

a7