Pushing one button causes other reaction?

First-timer poster here, newish to Arduino. Have been wrestling with a simple problem and wonder if someone can help me catch whatever is causing this unexpected response.

Simplifying the problem, I'm using a few buttons, but when I push one button, sometimes I get the response that should happen, and sometimes I get the response that should happen with the other button. It's intermittent, but 'double-clicking' sometimes makes it work properly, single-clicking makes it not work as intended.

I'm using the pullup resistors, which I've read about extensively but understand only a little.

Here is a mini-sketch that includes only the pertinent info but still demonstrates my problem.

const int j1 = 9;
const int j2 = 10;
const int j3 = 11;
const int j4 = 12;
const int j5 = 13;
const int buzzer = 8;  //piezo buzzer
const int b1 = 7; 
const int b2 = 6;
const int b3 = 5;  // these are the only two buttons pertinent to my problem
const int b4 = 4;  // these are the only two buttons pertinent to my problem

void setup() {
pinMode (j1,OUTPUT);
pinMode (j2,OUTPUT);
pinMode (j3,OUTPUT);
pinMode (j4,OUTPUT);
pinMode (j5,OUTPUT);
pinMode (buzzer, OUTPUT);
pinMode (b1, INPUT_PULLUP);
pinMode (b2, INPUT_PULLUP);
pinMode (b3, INPUT_PULLUP);
pinMode (b4, INPUT_PULLUP);
}


void loop() {

  if (digitalRead(b3) == LOW) {     // "LOW" because using Pullup resistor
  while (digitalRead(b3) == LOW) {}. // wait until button is released (debounce)

     tone(buzzer, 450);    // Send 45Hz sound signal... (low)
     delay(250);
     noTone(buzzer);
     }

  if (digitalRead(b4) == LOW) {     // "LOW" because using Pullup resistor
  while (digitalRead(b4) == LOW) {}.   // wait until button is released (debounce)
  
     tone(buzzer, 800);    // Send 45Hz sound signal... (high)
     delay(250);
     noTone(buzzer);
     }
}

Most of the errors have been with the input b4 activating the code associated with b3. Why would this be happening? Big thanks to anyone who can lend some thought.

With buttons and strange behaviors, start with how the button is wired into the circuit.

Do the buttons have any de-bounce circuitry?

The example does not need debouncing.

The example works perfectly, although I had to remove the '.' after the {}.

I also added Serial.println statement in each case as I have no buzzer for the tone(), I do not think that should invalidate the essential logic or fix some really mysterious problem.

So that leaves a hardware gremlin of some kind. I assume the schematic, perhaps you have some wires crossed or something squirrely going on with you breadboard.

a7

Thank you both for your eyes on this. (I would have thanked you earlier, but... ...more bugs in my use of the forum. oops.)

So if it's a hardware bug, maybe I'll try it on a different Uno and see how that goes.

Besides saying "Thank you" - *what's the customary way to appreciate good people like yourself who help noobs like me? *

  if (digitalRead(b4) == LOW) {     // "LOW" because using Pullup resistor
  while (digitalRead(b4) == LOW) {}.   // wait until button is released (debounce)

This is not a debounce. Assume b4 becomes LOW and passes the if condition. Because of switch bounce, the very next read of b4 can easily be a HIGH. So there is no wait because the while condition fails, and therefore there can't be any debounce.

Your only hope for this, is if the rest of your loop() is so slow, that the switch won't be polled again until after the switch contacts settle down.

Bouncing doesn't enter into it. The OP stated that one button caused the other button's function to fire:

"sometimes I get the response that should happen with the other button. "

The logic that looks like denouncing is not good, but there is no software explanation of all the observed (mis)behaviour.

The switch bounce can be addressed after each button can fire, however bouncingly, only its intended response.

Or the OP was late and it was getting tired and the report of symptoms is in error.

a7

Oh, yes, it's fairly common to find more than one problem with a posted project.

BTW, ALWAYS:

Show us a good schematic of your circuit.
Show us a good image of your ‘actual’ wiring.
Give links to components.
Posting images:
https://forum.arduino.cc/index.php?topic=519037.0

Suggest you only use while() ‘after’ you have written more than 100 working sketches.

And while :wink: we are at it, never use delay()

He is effectively debouncing the button. He subsequently goes into a 250ms delay() call. Does tone work during delay()?

-jim lee

Yes, it does. Like I said in #4, if the main process is really sluggish, debouncing isn't required. But that is nothing to celebrate.

Thanks everyone.

  • I'm convinced that my use of WHILE as a poor-man's denounce was not a good idea, but immaterial to my root question
  • I'm fascinated that "while" is considered an advanced maneuver, not to be used by noobs like me, but duly noted.
  • I'm still baffled why one button causes the next one to fire; trying to get my hands on a different Uno to determine if that's the problem.

I really appreciate everyone's attention on this. You are wonderful people.

I never heard of “while” being called any kind of advanced maneuver. As long as you understand how it works, which isn’t rocket science.

The most common error I see around here is failure to appreciate that if nothing in the body of a while statement changes the calculation of the condition, the body will repeat indefinitely.

Coupled with an often seen misconception that somehow a variable can be bound to a sensor reading or switch and will magically be updated should the sensor or switch change value.

[With the exception of interrupts and the break statement, either of which could more defensibly be called “advanced”.]

And your 3 is definitely the intriguing matter, again it would be good to share just how you are connecting you switches… like if you are using a breadboard or using uninsulated wire.

I see you are using the internal pull-ups, this might have been something.

a7

‘ "while" is considered an advanced maneuver’

No.

Poorly constructed while() code can result in blocking code.

‘while’ should be used in a way that allows code execution to proceed, not stall.

while (digitalRead(b4) == LOW) {} // this just sits here as long as the button is pressed (LOW).

You might want to look at ‘switch change’ instead of ‘switch level’ :wink:


Show us a good schematic of your circuit.
Show us a good image of your ‘actual’ wiring.
Give links to components.
Posting images:
https://forum.arduino.cc/index.php?topic=519037.0

alto777:
I see you are using the internal pull-ups, this might have been something.

Yes, I am using internal pull ups. I thought it was easier than wiring in individual resistors to all four buttons. (But then I wondered if a single resistor could be shared among the four buttons, which caused me to go the simpleton route and use the internal pull-ups.
As for sharing a schematic, I got a little scared when I read that photos are discouraged and that Fritzing is preferred. Not ready to tackle that juuuuust yet.
But I have to say, I'm overwhelmed by the support you all have offered me. <-- understatement.

rusharound:
As for sharing a schematic, I got a little scared when I read that photos are discouraged and that Fritzing is preferred. Not ready to tackle that juuuuust yet.

That's simply not true. Whiles a fritznuts thingy is ok when there is nothing else, I'd rather see a hand drawn image of a schemo ( a picture) and a picture of the setup.

I got a little scared when I read that photos are discouraged and that Fritzing is preferred.

Where did you read that ?

Thank you all for your encouragement. I have attached my writing diagram.

Background: I'm trying to make a device that will attach to a kids' wagon that will spray water on the sidewalk to spell out words and sentences. I have five 12v automobile injectors, connected to relays, that work like a dot-matrix printer, spraying water out the back.

The four buttons:

  • Speed up the pace/timing (buzzer to confirm setting number)
  • Slow down the pace/timing (buzzer to confirm setting number)
  • Activate all jets (for purging air out of system.
  • Spell saved phrase

The weird part is that the buttons seem to switch identities, even when I take out the buttons and use a jumper wire to activate them.

  • Rush

P.S. *In addition to the button concerns discussed in this thread, I'm worried the Arduino won't have the power to activate all the relays simultaneously, so I might have to look up a more robust approach to power those. (I smoked a buck converter already.) But that's probably a separate thread/separate problem. *

If this project interests anyone, please repost or get in touch!. I'm a little out of my league, but I'm motivated to learn what this project can teach me.

Well, that's not a bad overview, but the "button bank" part doesn't have enough detail to begin analyzing any problems with it. It's just a mysterious box.

Things that I would try:

  1. swap button input pins at the Arduino (discern software vs. button hardware problem)
  2. write a simple test sketch that does absolutely nothing but read buttons and report via serial
  3. photographing the hardware and posting it here (although I've never been that stuck because by the time I would do that, I've realized what the problem is).

Also, has it been mentioned that your button code is unconventional? Why not just ditch it and use code from an example sketch from the "Digital" section?

What is this button bank thingy ?

We are getting there !

The injectors will need kickback diodes.

LEDs need a series dropping resistor.


One final ‘time’.

Show us a good image of your 'actual' wiring.

Yeah, it's not great that the one thing that is causing you the most trouble, has the least information posted about it. Great idea, by the way... :slight_smile: