Ignoring a digital output with push button + latching [SOLVED]

I'm trying to use a push button to enable and disable a buzzer for a data logger and diagnostics device I'm creating. I only have pins A6 and A7 to use (I'm aware I cannot use DPIO on these pins), which has made it a lot more confusing, however, I'm wondering if you can completely ignore a digital output pin, even if the code puts the output as high later in the program? Here is the code I have for the button latching:

#define buzzerToggle A6   //abbreviation BT

int BTstate = 0;
int newBTstate;
int oldBTstate = 1;

void setup() {

  Serial.begin(115200);
  pinMode(buzzerToggle, INPUT);
}

void loop() {

  newBTstate = analogRead(buzzerToggle) < 500 ? 1 : 0;

  if (oldBTstate == 0 && newBTstate == 1) {
    if (BTstate == 0) {
      Serial.println("BUZZER TOGGLE HIGH");
      BTstate = 1;
    } else {
      Serial.println("BUZZER TOGGLE LOW");
      BTstate = 0;
    }
  }
  oldBTstate = newBTstate;
}

That is just a short sketch I've made. Here is a part of the buzzer code for the device (I haven't pasted the whole code as it is 500 lines and most of it is irrelevant to the problem):

 else {
    
    unsigned long NBtime = millis();

    if(NBtime - NBinterval >= 500) {

     NBinterval = NBtime;
     digitalWrite(RED, HIGH);
      digitalWrite(GREEN, HIGH);
      digitalWrite(BLUE, HIGH);
      tone(buzzer, 1500, 50);
    }

    else {
  
      digitalWrite(RED, LOW);
      digitalWrite(GREEN, LOW);
      digitalWrite(BLUE, LOW);
      digitalWrite(buzzer, LOW);
    }
  }

NB time and NB interval is just non blocking to switch the buzzer and RGB LED on and off. Is there a way to disable the buzzer tone function completely if the push button is e.g. high?

Of course you can but I am not sure how that relates to the sketch that you posted

I posted the code to latch the push button to ON or OFF, and the next sketch is an example of where the buzzer has been used in the datalogging/diagnostics code.

 Serial.println("BUZZER TOGGLE HIGH");
  ...
      Serial.println("BUZZER TOGGLE LOW");

is an example of the buzzer being toggled.

I missed that question originally

The answer is, of course, yes. How will you know that the button state is currently HIGH ? Is there perhaps a variable holding its state that you can test or maybe a function that you could call to get its current state ?

I can't confirm my suspicion that the sketch toggling BYstate won't will exhibit behaviour consistent with contact bouncing.

A cheap way to debounce is to just throttle the loop with a 15 or 20 millisecond delay. If the rest of your sketch can tolerate running at 50 Hz or so.

Otherwise, debounce the reading you develop from the analog pin exactly the same way you debounce a pushbutton on a digital input.

For suppressing the buzzer on the state of the pushbutton, why can you not

   if (newBYstate == 0)       tone(buzzer, 1500, 50);

just don't buzz if the condition is not met. You may want == 1 there, but you get the idea.

a7

the BUZZER TOGGLE HIGH and BUZZER TOGGLE LOW part of the code. The whole 1st sketch is the push button state.

So use BYstate in the same manner.

a7

You can test the value of BTstate and take the appropriate action, ie activate the buzzer or not

It was more simple than I thought, all I did was just shove an if statement over every buzzer tone function. Thanks for the help!

The LCD screen shows the state of the button, and I'm trying to get the code as fast as possible, therefore I can't use a delay, but there isn't much need for a debounce as it is a toggle state that is being displayed as only ON or OFF

@chrisd79 I have confirmed that the logic is faulty.

Inserting some measurement and printing code, youe origianl sketch with a 50 millisecond delay to throttle the loop produces

               0
BUZZER TOGGLE HIGH
               1
                      debounced button down 
BUZZER TOGGLE LOW
               0
                      debounced button down 
BUZZER TOGGLE HIGH
               1
                      debounced button down 
BUZZER TOGGLE LOW
               0
                      debounced button down 

One toggle per real debounced button down event.

Running without the throttle, the output is

               0
BUZZER TOGGLE HIGH
               1
BUZZER TOGGLE LOW
               0
BUZZER TOGGLE HIGH
               1
                      debounced button down 
BUZZER TOGGLE LOW
               0
BUZZER TOGGLE HIGH
               1
BUZZER TOGGLE LOW
               0
BUZZER TOGGLE HIGH
               1
BUZZER TOGGLE LOW
               0
                      debounced button down 
BUZZER TOGGLE HIGH
               1
BUZZER TOGGLE LOW
               0
BUZZER TOGGLE HIGH
               1

where we see the toggle logic engaged more than once as the bouncing happens.

Which would be OK, except that it doesn't always do an odd number of toggles, therefor would be unreliable to, say, turn on and off an attached LED.

If it works for you, I can't argue with success. But if you find that you are having problems that could in any way be explained by the fact that you have no debouncing logic present, please remember the simple trick of throttling the loop (poor man's debounce!) and check that first to see if it has, in fact, become a problem.

a7

Thank you for explaining more, I heard about button debouncing before but didn't read into it at all beforehand. The button bouncing doesn't really matter in my circumstance, as all it is doing is disabling the buzzer and the screen shows the current state of the buzzer as ON or OFF; if there is a way I could debounce the button without using a delay then I'll probably use it just for optimisation

Right. You are just using the fact that the button is down or not to gat the tones. And if the tones were very briefly on and off and on and off, you would never notice.

It is when you expect the toggling, like press to hear tones, press again when you want to turn them off, that you would need debouncing.

When/if you need to toggle something using a pushbutton no matter how you are reading it, be assured that there are quite a number of ways to do, none of which would involve delay(). At all.

a7

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