Debouncing locking out the ability to count the number of button pushes.

hello all, my current project is a traffic advisor (the amber lights that tell you to move over).

basic layout,
5 buttons: left, center, right, warning, and off.
state machines control everything.

each button activates its own sub routine with the appropriate pattern using a switch case.

the warning option currently goes into a subsequent switch case and calls several smaller patterns together with another state machine timing everything.

I want the warning button to be able to swap through the patterns instead of the timer doing it but every thing i try is blocked by the debounce state machine, since that button is already on it refuses to look for another push. ive tried multiple things and i cannot get it to work. any help here would be greatly appreciated.

due to text limitations ive removed all code not related to the warning mode, but attached is the full .INO

boolean debounce_warning(boolean warning_last) {
  boolean warning_current = digitalRead(warning_button);
  if (warning_last != warning_current) {
    delay(5);
    warning_current = digitalRead(warning_button);
  }
  return warning_current;
}

void loop() {

  warning_current = debounce_warning(warning_last);
 

  if (warning_last == LOW && warning_current == HIGH)
  {
    pattern_count = 1;
  }
 
  switch (pattern_count) {
    case 0:
      pattern_off();
      break;
    case 1:
      traffic_left();
      break;
    case 2:
      traffic_center();
      break;
    case 3:
      traffic_right();
      break;
    case 4:
      traffic_warning();
      break;
  }
}

void traffic_warning() {
  unsigned long currenttimer = millis();
  if (currenttimer - lasttimer >= switch_timer) {
    lasttimer = currenttimer;
    warning_count = warning_count + 1;
    if (warning_count > 8) {
      warning_count = 1;
    }
  }
  switch (warning_count) {
    case 1:
      even_odd();
      break;
    case 2:
      two_by_two();
      break;
    case 3:
      half_half();
      break;
    case 4:
      two_by_two_parallel();
      break;
    case 5:
      out_flash();
      break;
    case 6:
      one_center();
      break;
    case 7:
      outboard();
      break;
    case 8:
      half_half_flash();
      break;
  }
}

push_button.ino (10.8 KB)

I like the fact that you are using functions but it seems to me the names you have chosen for your function and your variables is obscuring what really needs to happen.

Also, the code in your function is really a state-change detector rather than a debounce - the short delay() is the debounce part. And then you have a second piece of state-change code in loop() which seems rather unnecessary.

And it seems to me if an new button-press is detected that it should have the effect of incrementing patternCount.

I would do it like this

byte checkButton() {
   static byte buttonState = HIGH; // assumes LOW when pressed
   byte prevButtonState = buttonState;
   buttonState = digitalRead(buttonPin);
   if (buttonState == LOW and prevButtonState == HIGH) {
      return 1;
   }
   else {
     return 0;
   }
}

and in loop() I would have something like

patternCount += checkButton();

A short interval (maybe 50 millisecs) between calls to checkButton() would be a good idea to avoid bounce, but I would not necessarily put that in the checkButton() function. It may be that other actions in your program take up sufficient time.

...R

Robin2:
And it seems to me if an new button-press is detected that it should have the effect of incrementing patternCount.

your correct in this case, the pattern count does change between the different buttons. what i need to happen is for the warning count to change on every press, and the way its working now is that it only reads the presses of buttons whose states are low.

as for the code you supplied, i did google a lot and i did come across this solution but i could not get it to work for me, the code would compile fine, but the desired effect did not happen.

update:

I could not get the button to be multi purpose, so i went with a hardware solution and added another button that all it does is change the warning count and it achieved the desired effect. i was also able to condense a few pieces of the overall code when i did this.

d.raymond:
as for the code you supplied, i did google a lot and i did come across this solution but i could not get it to work for me, the code would compile fine, but the desired effect did not happen.

As you have not posted the program you tried I am not able to comment.

...R