2

I'm trying to have a keypad do two one of three things when a key is pressed:

  1. If the 1 is pressed I want LED 1 to blink twice then stay on
  2. If either the 2 or the 3 is pressed I want LED 2 to blink forever
  3. If the # key is pressed I want it to cancel whatever's going on with the other LEDs

How can I use millis() to blink forever? Or just blink twice then stay on? When in my blinking should I be checking for another keypress? What's frustrating me is that I know how to do all this with delay(), and I've written 70% of the code for it with delay, but if I use delay I don't think it'll be able to check for another key input, will it?

Thanks for any help.

1 Answer 1

1

How can I use millis() to blink forever?

The algorithm is essentially as follows:

if (it_is_time_to_toggle_the_led()) {
    toggle_the_led();
}

The details are thoroughly covered in the Blink Without Delay Arduino tutorial. It is essential to understand this technique: as soon as you have more than one thing to do in your program (here: blink an LED and monitor button presses), delay() is toxic because it blocks all the program. You should really ban delay() from your vocabulary, except for the simpler single-task programs.

Or just blink twice then stay on?

For this and your other questions, the canonical answer is “implement a finite state machine”. I recommend the Finite State Machine tutorial[] by Majenko.

In this particular instance, I would probably implement two FSMs, one for each LED. The first one would have three states: (OFF, BLINKING, ON), and a counter for the number of blinks. The transition rules:

  1. If button 1 is pressed and the state is not BLINKING go to the BLINKING state
  2. If it is BLINKING and it's time for it to toggle, do it
  3. If it is BLINKING and it is switching on for the third time, go to the ON state
  4. If '#' has been pressed, go to the OFF state.

Or maybe you could split the state BLINKING into BLINKING_ON and BLINKING_OFF.

The second LED would be essentially the same, except for lacking the ON state and rule number 3.

I am not writing the code, but you may want to take a look at this code for automatic door[]. It is an answer to a seemingly unrelated question, but it gives a good example on how to combine millis()-based timing with a finite state machine. Your program could be written mostly along the same lines.

3
  • Wow, I had never heard of FSMs before, really cool! Thanks for your help.
    – finlay
    Sep 29, 2016 at 13:34
  • So I've tried many different ways of doing it and the system seems to have trouble advancing through the loop. Here's my code so far. I know I'm not supposed to use delay() but it works okay for right now. The problem is that the red LED will turn on (when 4 or 5 is pressed), and stay on. There's no blinking or anything, which leads me to believe it runs through the code then waits for another keypress before running back through the loop? Does that make sense? Any more help you can offer would be greatly appreciated.
    – finlay
    Oct 2, 2016 at 21:56
  • @finlay: Your code won't compile. Oct 3, 2016 at 9:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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