Trouble detecting button presses

skypickle

Active member
I am using this code to monitor 5 pushbuttons

Code:
int btnPins[] = {
 19,20,21,22,23
 };  
 int btnCount = 5;         

void setup() {

for (int thisBtn = 0; thisBtn < btnCount; thisBtn++) 
  pinMode(btnPins[thisBtn], INPUT);
 }

 void loop()  {
  for (int thisBtn = 0; thisBtn < btnCount; thisBtn++)
  inputBtn = digitalRead(btnPins[thisBtn]);
 Serial.println(inputBtn);
  if (inputBtn  == HIGH) {
    Serial.println("Button is not pressed...");
  } else {
    Serial.println("Button pressed!!!");
  }
  delay(250);
 }

I am expecting to see a 'button pressed' message when I press a button. The problem is that unless the button is pressed when the loop reads it, I will not see the button pressed message. Since my teensy is doing several other things (checking 6 potentiometers) , It is missing button presses. How can I remedy this?
 
If your problem is that you may "miss" detecting a button press because the user un-pressed before the other things were done, you may need to incorporate an interrupt. Currently you are using a poling method and for most part are fast enough to detect presses. If however all your other processing takes too long, interrupts use a priority scheme. If and interrupt is pressed regardless what your code is doing, it will process the read.

Interrupts can be a real pain to debouce and get working reliably.

Also, how are you guaranteeing your button is low before a press? Is there a pulldown resistor? If not, one really needs to be included. Poling generally also needs debouncing to prevent multiple reads from the mechanical button...bouncing.
 
Thank you for your reply. The buttons are wired with a pull-up resistor. So the circuit looks like
td_tutorial_03e.jpg
except there are no LED circuits but there are 5 buttons, each with its own resistor and going to its own pin.
I thought my delay is more than adequate for debouncing. But of course that is also prob why I am missing button presses.

I dont know much about interrupts and debouncing them. But the requirement for detecting button presses seems to be a basic issue so I would have thought there is a straightforward solution. My researches however turn up rather convoluted discussions like this one

https://forum.arduino.cc/t/4-push-buttons/643517/5

which are over my head.
 
I just wired this up and I think this issue is the way your code is written, you will only be looking at the state of the last button (23) after the for loop

the line
for (thisBtn = 0; thisBtn < btnCount; thisBtn++)
inputBtn = digitalRead(btnPins[thisBtn]);

will read all buttons but nothing will be done until the for loop finishes, leaving the last assignment to inputBtn to be used for input check. I'm not a fan of loops with no {}


try this loop code, also i;m using 50 ms delay which seems fine for my tack button

void loop() {
for (int thisBtn = 0; thisBtn < btnCount; thisBtn++) {
inputBtn = digitalRead(btnPins[thisBtn]);
Serial.print(" thisBtn ");
Serial.print( thisBtn );
Serial.print(", inputBtn ");
Serial.print(inputBtn);


if (inputBtn == HIGH) {
Serial.println(", Button is not pressed...");
} else {
Serial.println(", Button pressed!!!");
}
delay(50);
}
}

also I assume you have button press will short to ground at least that how i wired up mine since you have a pullup and are looking for HIGH.
 
Indeed, not using {} braces on every control conditional or for/while is asking for trouble.

Handy Tip?: In the IDE (or as coded in the editor at hand) hit "Ctrl+T" and uniform code formatting is applied. In this case it would indent ONLY the single statement under the for() showing that everything after that is outside the control of the for().
> this is handy for finding other errors in code as typed as well like missing/extra braces and missing ';'s when the compiler gives a strange error somewhere after that

Ctrl+T is like using "CODE" / # in forum posts as it formats the code from p#5:
Code:
void loop()  {
  for (int thisBtn = 0; thisBtn < btnCount; thisBtn++) {
    inputBtn = digitalRead(btnPins[thisBtn]);
    Serial.print(" thisBtn ");
    Serial.print( thisBtn );
    Serial.print(", inputBtn ");
    Serial.print(inputBtn);


    if (inputBtn  == HIGH) {
      Serial.println(", Button is not pressed...");
    } else {
      Serial.println(", Button pressed!!!");
    }
    delay(50);
  }
}
 
2 issues - one with the missing braces, and the other is with the delay function. When the delay function is running, the digitalRead function will not be.

You could use interrupts to detect the button presses, push the event into a queue and then process the event when your code gets to it.
 
Back
Top