0

I am trying to make a 24 button board that assigns different methods to each button. When a button is pressed, it should interrupt the method of the previous button and begin the new method. Currently, the button has to be held down in order to work. I'm not sure why since the methods should continue without being held down. All 24 methods are similar to the one posted below.

loop(){
  if (digitalRead(inPin(5)) == HIGH){
    fifthButtonTheatreChaseRedSlow(strip.Color(127,   0,   0), 100); // Red
  }

void fifthButtonTheatreChaseRedSlow(uint32_t c, uint8_t wait) {
  for (int j=0; j<100; j++) {  //do 100 cycles of chasing
    for (int q=0; q < 3; q++) {
      for (int i=0; i < strip.numPixels(); i=i+3)
      {
        strip.setPixelColor(i+q, c);    //turn every third pixel on
      }
      strip.show();
      delay(wait);

      // give up if switches pressed
      if (digitalRead (inPin(1)) == HIGH || 
             digitalRead (inPin(2)) == HIGH ||
             digitalRead (inPin(3)) == HIGH ||
             digitalRead (inPin(4)) == HIGH || 
             digitalRead (inPin(6)) == HIGH ||
             digitalRead (inPin(7)) == HIGH || 
             digitalRead (inPin(8)) == HIGH ||
             digitalRead (inPin(9)) == HIGH || 
             digitalRead (inPin(10)) == HIGH ||
             digitalRead (inPin(11)) == HIGH || 
             digitalRead (inPin(12)) == HIGH ||
             digitalRead (inPin(13)) == HIGH || 
             digitalRead (inPin(14)) == HIGH ||
             digitalRead (inPin(15)) == HIGH || 
             digitalRead (inPin(16)) == HIGH ||
             digitalRead (inPin(17)) == HIGH || 
             digitalRead (inPin(18)) == HIGH ||
             digitalRead (inPin(19)) == HIGH || 
             digitalRead (inPin(20)) == HIGH ||
             digitalRead (inPin(21)) == HIGH ||
             digitalRead (inPin(22)) == HIGH || 
             digitalRead (inPin(23)) == HIGH ||
             digitalRead (inPin(24)) == HIGH)
               return;

      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

Not sure if it's a hardware issue or a software issue.

1

It's a software issue. You are basically saying "If this button is currently pressed down then run this sequence once", rather than "If this button has transitioned from OFF to ON then set my current sequence to X"

You need to learn about the Finite State Machine and about switching from one state to another (or one selected sequence to another) when a button changes state not when it is in a state.

So basically the whole logic of your program is flawed and needs re-working.

1

Related to Multiple buttons activating different methods for an LED strip

 // give up if switches pressed
  if (digitalRead (inPin(1)) == HIGH || 
         digitalRead (inPin(2)) == HIGH ||
         digitalRead (inPin(3)) == HIGH ||
         digitalRead (inPin(4)) == HIGH || 
         digitalRead (inPin(6)) == HIGH ||
         digitalRead (inPin(7)) == HIGH || 
         digitalRead (inPin(8)) == HIGH ||
         digitalRead (inPin(9)) == HIGH || 
         digitalRead (inPin(10)) == HIGH ||
         digitalRead (inPin(11)) == HIGH || 
         digitalRead (inPin(12)) == HIGH ||
         digitalRead (inPin(13)) == HIGH || 
         digitalRead (inPin(14)) == HIGH ||
         digitalRead (inPin(15)) == HIGH || 
         digitalRead (inPin(16)) == HIGH ||
         digitalRead (inPin(17)) == HIGH || 
         digitalRead (inPin(18)) == HIGH ||
         digitalRead (inPin(19)) == HIGH || 
         digitalRead (inPin(20)) == HIGH ||
         digitalRead (inPin(21)) == HIGH ||
         digitalRead (inPin(22)) == HIGH || 
         digitalRead (inPin(23)) == HIGH ||
         digitalRead (inPin(24)) == HIGH)
           return;

Time to learn about loops, buddy. How about:

for (int i = 1; i <= 24; i++)
  if (digitalRead (inPin (i)) == HIGH)
    return;

My guess about this particular problem is that you are not debouncing. You enter the function, one of the bounces is detected, and you leave the function. I mentioned debouncing in your other, closely-related, thread.


Let me show you what a switch bounce looks like. Using a normal switch from my parts drawer, this is what you see when you press it:

Switch bounce

See that? It looks to the (fast) Arduino that you pressed the switch 20 or 30 times. That is the physical metal bouncing back and forwards. So if you test for one press, and then stop when you get another, your chances of it working are rather slim. That's why a simple delay of (say) 10 ms after detecting a change in state of the switch can help debounce it.

See: Switches tutorial

  • Could also be a chance for the OP to learn about switch cases. – bladepanthera Aug 19 '15 at 10:20
  • One thing you're missing there, mate - he's entering the function on button 5, but he's not checking button 5 as a reason for terminating the function - so it can't be debouncing that's causing it - button 5 only enters, it never causes it to leave. So a loop would break that functionality and then bouncing would then become a problem. As it is, the problem is caused by the if (digitalRead(inPin(5)) == HIGH) { ... } in the main loop (which equates to "while input 5 is high ... "). – Majenko Aug 19 '15 at 10:53
  • Thank you for your responses. It turns out the bread board was not working. Changed it out and everything is fine now. I replaced the if statements with a switch. However, your suggestion for the alteration for the for loop isn't working. I need to skip a single value in the loop. My understanding of for loops, however, would make each of the ((inPin(i) == HIGH)) statements an AND statement, not an OR statement. I need it to be an OR statement to work. Do you have a suggestion for how to get around this? – Jet Propelled Insectivore Aug 19 '15 at 12:06
  • @JetPropelledInsectivore Personally I would have a single function which reads all the buttons and sets each bit in a 32-bit unsigned integer as a bit-field representing which buttons are pressed. You can then mask out the button you want to ignore and see if the result is anything other than 0. – Majenko Aug 19 '15 at 12:28
  • @Majenko - but he's not checking button 5 as a reason for terminating the function - Not really. He is saying he needs to hold the button down for it to be noticed. The function is already written to only do 100 iterations. So you could count that as a debounce. My proposed code exits on any button press, so it can go back and test for other buttons immediately. – Nick Gammon Sep 4 '15 at 6:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.