DUE not always registering first button press

Background
I made a quiz buzzer system based off of I like to make stuff's system. I wanted to add sound to an 8 buzzer system so I switched to a DUE from an UNO.

Issue description:
I have everything working save one problem: It doesn't always recognize the first press of the button and sometimes takes 2-3 presses of the button to get it to register and sometimes it'll work on the first press many times in a row before ignoring the first or second press. This behavior is on the reset button as well as the player buttons.

Other
I'm still pretty new to programming. I can understand how to modify different aspects of code and somehow managed to jam the code to make the tone command work on the Due into the original code but that's about the limit of my abilities at the moment. Also, if there are any optimizations I can do, any suggestions would be much appreciated

What I've tried:
I've tried switching from using pins in the 22-53 bank for the the switches to pins 2-10 and no change (in hope that the 22-53 bank had higher latency or something like that).

I was thinking it may be the code to set up the clock for the tone command (found elsewhere in these forums), but after commenting out all the code pertaining to that (reverting back to just the light for feedback) the issue persisted.

I've also attached a picture of the wiring for the reset button and one player button as well as the internal of the player (remote) button. if any other info is needed please let me know.

Thanks in advance for your help.

Due to the length of the code, I have attached it

8buzzer_DUE.ino (16.9 KB)

DueTone.h (2.23 KB)

You have so much repeated code in here. Time to learn about arrays.

For example

int buttonPins[8];

void setup()
{
  for(int i = 0; i < 8; i++)
  {
    buttonPins[i] = i + 2;
    pinMode(buttonPins[i], INPUT);
  }
}

void loop()
{
  //read buttons
  for(int i = 0; i < 8; i++)
  {
    buttonState[i] = digitalRead(buttonPins[i]);
  }
}

This will create an array which holds the button pin numbers and also set those pins as inputs.

The way you have it coded, you seem to be polling for a LOW on the button. This should be the case if you have the button pins set as INPUT_PULLUP. If you want to use the logic as it is, you need pulldown resistors and poll for a HIGH on the button pins.

Also, I see

boolean pollingForPresses = 1;

Booleans have values of either true or false.

Thanks. I'm going to do some homework on Arrays so I understand how to manipulate them (what the different variables are and how to initialize multiple arrays i.e. button, led, speaker)

Do you think that using arrays will help solve the problem or is there likely something else?

Is there any disadvantage to declaring the pin numbers vs using an integer equation like in your example?

I have physical pull-up resistors on a breadboard I soldered so that all works fine (followed the wiring that was on the linked website).

Is there any disadvantage to declaring the pin numbers vs using an integer equation like in your example?

None at all.

I can't make any sense of your wiring diagram. It is MUCH easier to wire a switch, though. Connect one leg to ground. Connect the other leg to a digital pin. Use INPUT_PULLUP as the mode for that pin.

Then, HIGH means not pressed and LOW means pressed.

You need to know only the current state, read from the pin, and the previous state, to know that a switch changed state. You do NOT need three variables.

Thanks for pointing out the switch wiring. I've redone the wiring so the buttons use the Due's internal PULLUP and changed the code accordingly.

After watching some youtube videos and lots of using the compile button to show me where I messed up the code formatting, I think I've gotten the setup figured out but I'm caught up on the reading the switches' status. I was able to compile without errors but it doesn't register button presses when I press the button. In my mind it seems like it should work, but obviously I'm missing something and I have no idea what it is.

Thanks again for your help.

I've attached my updated code (only programmed for one player button and the reset button so far just to figure out how to get things working) and updated wiring.

Buzzer_code_v2.ino (4.44 KB)

When nothing seems to work, back to basics !

Did you try the example sketch provided in:

Examples>Digitals>DigitalInputPullup ?

I think setting up the buttons on INPUT_PULLUP was probably one of the easiest parts. The place that I'm having trouble with now is the loop for reading the status of the buttons and giving the feedback (LED on/play sound).

You have arrays of pin numbers for the switches and a boat load of scalar variables for current and previous states. Why? If you can figure out arrays for the pins, you can figure out arrays for the states.

  for (int i; i < 9; i++)

Starting with i containing some random value, while i is less than 9, set the mode of one pin. Then, increment i and compare again.

That hardly seems like what you want to do. int i = 0 IS, and is no more work to type.

You are STILL using 3 variables to keep track of the current and previous state of one pin. STOP THAT.

byte currState[9];
byte prevState[9];

void loop()
{
   for(byte i=0; i<8; i++)
   {
      currState[i] = digitalRead(buttonPins[i]); // It pains me to type buttonPins for the name
                                                                  // of the array that contains the numbers of the
                                                                  pins that SWITCHes are attached to
      if(currState[b] != prevState[b])
      {
         // The switch was just pressed or was just released
         if(currState[b] == LOW)
         {
            // It was just pressed... Call a function to make some noise
         }
      }

      prevState[b] = currState[b];
   }

   // Other stuff...
}

Getting closer. The 8 switches for the team controllers light up and make noise when you press them, but the reset switch (switchPins[8]) isn't registering and they aren't locking out after the first team buzzes in. It's amazing how much more compact the code is now and almost does what I need it to. Thanks for being patient with my ignorance.

To clarify:
Problems left to solve:

Stop reading switchPins 0-7 after one is activated until rest is activated.

Read reset switch pin (switchPins[8]) after one switch is activated and locked out other switches.

Anything ugly I have done that can be done more neatly.

New code attached.

Thanks again.

Buzzer_code_v3.ino (2.19 KB)

  if (pollingForPresses = true)

You are assigning true to pollingForPresses in the if statement, not comparing pollingForPresses to true.

    for (byte i = 0; i < 8; i++)
    {
      currState[i] = digitalRead(switchPins[i]);
      if (currState[i] != prevState[i])
      {
        if (currState[i] == LOW)
        {
          pollingForPresses = false;

You check all 8 switches, regardless of whether one has already been determined to have been pressed. Does that make sense?

    currState[9] = digitalRead(switchPins[8]);
    if (currState[9] != prevState[9])
    {
      if (currState[9] = LOW)
      {
        Serial.println("Reset switch Pressed");
        resetswitches();
      }
      prevState[9] = currState[9];
    }

currState and prevState do not have an element at position 9.

OK. I've gotten the syntax fixed (= -> ==). Having pollingForPresses = false after the LOW is detected seems to work to stop reading pins until reset. Unfortunately, the reset still is eluding me.

I realized that I forgot about zero indexing (hence no value [9]) and changed the value to [8], but it still isn't happy. The code seems to advance up to looking for the reset switch to change states but it doesn't register the change in the the switch state.

void loop()
{
  if (pollingForPresses == true)
  {
    for (byte i = 0; i < 8; i++)
    {
      currState[i] = digitalRead(switchPins[i]);
      if (currState[i] != prevState[i])
      {
        if (currState[i] == LOW)
        {
          pollingForPresses = false;
          Serial.print("Team ");
          Serial.println(i + 1);
          digitalWrite(ledPins[i], HIGH);
          digitalWrite(ledPins[8], HIGH);
          /*int melody[] = { 523, 392, 523, 659, 784, 1047, 784, 415, 523, 622, 831, 622, 831, 1047, 1254, 1661, 1245, 466, 587, 698, 932, 698, 932, 1175, 1397, 1865, 1397
                         };
            int noteDurations[] = {   16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
                                };
            for (int thisNote = 0; thisNote < 27; thisNote++) {
            int noteDuration = 1000 / noteDurations[thisNote];
            tone(spkrPins[i], melody[thisNote], noteDuration);
            int pauseBetweenNotes = noteDuration * 0.5;
            delay(pauseBetweenNotes);
            noTone(spkrPins[i]);
            }*/
        }
        prevState[i] = currState[i];
      }
    }
  }
  if (pollingForPresses == false)
  {
    currState[8] = digitalRead(switchPins[8]);
    if (currState[8] != prevState[8])
    {
      if (currState[8] = LOW)
      {
        Serial.println("Reset switch Pressed");
        resetswitches();
      }
      prevState[8] = currState[8];
    }
  }
}

(I commented out the noise code so I'm not bugging the people around me as much)

If you have an array of size 8 and you start counting at 0, what is your maximum value?

Menelaus:
OK. I've gotten the syntax fixed (= -> ==). Having pollingForPresses = false after the LOW is detected seems to work to stop reading pins until reset. Unfortunately, the reset still is eluding me.

I realized that I forgot about zero indexing (hence no value [9]) and changed the value to [8], but it still isn't happy. The code seems to advance up to looking for the reset switch to change states but it doesn't register the change in the the switch state.

void loop()

{
  if (pollingForPresses == true)
  {
    for (byte i = 0; i < 8; i++)
    {
      currState[i] = digitalRead(switchPins[i]);
      if (currState[i] != prevState[i])
      {
        if (currState[i] == LOW)
        {
          pollingForPresses = false;
          Serial.print("Team ");
          Serial.println(i + 1);
          digitalWrite(ledPins[i], HIGH);
          digitalWrite(ledPins[8], HIGH);
          /int melody[] = { 523, 392, 523, 659, 784, 1047, 784, 415, 523, 622, 831, 622, 831, 1047, 1254, 1661, 1245, 466, 587, 698, 932, 698, 932, 1175, 1397, 1865, 1397
                        };
            int noteDurations[] = {  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
                                };
            for (int thisNote = 0; thisNote < 27; thisNote++) {
            int noteDuration = 1000 / noteDurations[thisNote];
            tone(spkrPins[i], melody[thisNote], noteDuration);
            int pauseBetweenNotes = noteDuration * 0.5;
            delay(pauseBetweenNotes);
            noTone(spkrPins[i]);
            }
/
        }
        prevState[i] = currState[i];
      }
    }
  }
  if (pollingForPresses == false)
  {
    currState[8] = digitalRead(switchPins[8]);
    if (currState[8] != prevState[8])
    {
      if (currState[8] = LOW)
      {
        Serial.println("Reset switch Pressed");
        resetswitches();
      }
      prevState[8] = currState[8];
    }
  }
}




(I commented out the noise code so I'm not bugging the people around me as much)

About your Reset, How is physically connected? And for the other buttons... have you checked you resistors? And about yuor code, I think the reset part should embrace all the code...

Wiring

You can ignore any mistakes in the amp circuit. I just tried to recreate the circuit of the boards I got from amazon.

As you can see the currState and prevState go to 9, so addressing the final element should be currState[8], correct?

The reset switch is connected to pin 46 and ground, and the LED for the reset switch is pin 47 (there's a resistor attached to the LED's leg) and ground.

How would you have the reset code embrace all the loop?

Here's the setup portion of the code.

int switchPins[] = {22, 25, 28, 31, 34, 37, 40, 43, 46};
int ledPins[] = {23, 26 , 29, 32, 35, 38, 41, 44, 47};
int spkrPins[] = {24, 27, 30, 33, 36, 39, 42, 45};

byte currState[9];
byte prevState[9];

boolean pollingForPresses = true;

void setup() {
  Serial.begin(9600);
  for (int i = 0; i < 9; i++)
  {
    pinMode(switchPins[i], INPUT_PULLUP);
    pinMode(ledPins[i], OUTPUT);
  }
  for (int i = 0; i < 8; i++)
  {
    pinMode(spkrPins[i], OUTPUT);
  }
  for (int i = 0; i < 9; i++)
  {
    digitalWrite(ledPins[i], HIGH);
    delay(1000);
    digitalWrite(ledPins[i], LOW);
  }
}

Here's the resetswitches() setup

void resetswitches() {
  for (int i = 0; i < 10; i++)
  {
    digitalWrite(ledPins[i], LOW);
    digitalWrite(switchPins[i], HIGH);
  }
  for (int i = 0; i < 9; i++)
  {
    prevState[i] = currState[i];
  }
  pollingForPresses = true;
}
for (int i = 0; i < 10; i++)

This counts from 0 to 9. You stated that the max was 8. How do you suppose you fix this so you are not writing LOW to an unknown pin and HIGH to another unknown pin in the last iteration of this loop?

Not sure how I missed that one.
Changed to:

for (int i = 0; i < 9; i++);

Still not registering the reset switch. All electrical connections are sound and as addressed.

I did test at one point using a Serial.println when it should be looking for a reset switch LOW state

 if (pollingForPresses == false)
  {
    currState[8] = digitalRead(switchPins[8]);
    Serial.println(currState[8]);
    if (currState[8] != prevState[8])
    {
      if (currState[8] = LOW)

and it does show it toggling between 1 (open) and 0(closed) when I toggle the switch.

It is confirmed then, the reset is wrong connected, wether if it is to make a reset just like the on board reset, or a reset specifically for the program, but i think you want to make the last option, then try this:

Solved. I'm blind. When fixing the syntax on the pollingForPresses portion, I forgot to change the syntax on the reset read portion.

if (currState[8] = LOW)

which was writing LOW to currState[8] instead of

if (currState[8] == LOW)

Special thanks to PaulS for walking me through this process. I now understand a bit more coding than I did before.Your help was very much appreciated.