Cycling 3 led with one button

Status
Not open for further replies.

urbanspaceman

Well-known member
Hi, i have searched on this forum and on other forums without success.

Project
I want to lid 3 leds with 1 button, 1 led at time in sequence

1st press = led 1 on
2nd press = led 1 off, led 2 on
3th press = led 1 off, led 2 off, led 3 on
4th press = led 1 on, led 2 off, led 3 off
... ad libitum!

In my board i have the HT16K33 that control the leds and the switch. No problem to lid the leds and read the switch, the problem is in the loop function.
When i push the button, the 3 leds blink together, when i release the button only one led is lid but random...

this is the code


Code:
void loop(){
  if (HT.readKey(Button_a1))
  {
      if((!HT.getLed(Led_a1) && !HT.getLed(Led_a2) && !HT.getLed(Led_a3)) or HT.getLed(Led_a3) ){
          HT.setLedNow(Led_a1);
          HT.clearLedNow(Led_a2);
          HT.clearLedNow(Led_a3);
      }else if(HT.getLed(Led_a1) && !HT.getLed(Led_a2) && !HT.getLed(Led_a3)){
        HT.setLedNow(Led_a2);
        HT.clearLedNow(Led_a1);
        HT.clearLedNow(Led_a3);
      }else if(!HT.getLed(Led_a1) && HT.getLed(Led_a2) && !HT.getLed(Led_a3)){
        HT.setLedNow(Led_a3);
        HT.clearLedNow(Led_a1);
        HT.clearLedNow(Led_a2);
      }

  }
 }
 
This would probably work better if you have a single 'LEDstate' variable that your button read routine increments by one, then if >max reset to 0.

Then as either a switch/case process or series of if (LEDstate==1) etc checks set your LEDs correctly.

Also if writing tight loops of code like this doing IO it can help to add delay(1); at the end of the loop to ensure that any clever non blocking code has a chance to finish up before being triggered again on a new loop.

This also means you know this loop will only fire at most 1000 times a seconds so you can have a 'doDebug' counter that you increment every loop, then when it reaches 1000 do a serial print of your variable, input and output states and then rest. This will mean that you can observe what is happening internally without drowning in serial prints.

Edit: Re reading your code suspect you have things working right, but since changes LEDs every cycle while the button is down every loop will change the lit LED so only one is lit but that changes every pass through loop. You need to trigger on falling or rising edges, not the actual button state. Lots of ways to do that, using the bounce library is easy, or you can add your own logic to check if the button was down last cycle, if it was then do not change the LED because you already did, this will have it's own bounce problems that you will need to manage but may be good enough. Ugly but simple fix is to add 'delay(1000);' at the end of your button state check so the code halts for a second (or possibly 100ms) giving time for you to release the button.
 
Last edited:
I don't know what "HT" means in your code. But if it's not a library which properly debounces the mechanical chatter from the pushbutton, I would highly recommend using the Bounce library to read the button. Mechanical chatter is really frustrating for this sort of project.
 
Status
Not open for further replies.
Back
Top