Button Challenge!
Challenge
Read the section titled More Advanced Decision Making. Try to get it to switch brightness reliably. Don't forget to add the delay to the end of the program.
The two button light switch in part 2 of this exercise worked much
better than this 1 button dimmer. I can almost imagine someone inventing
a lamp with a button for each brightness, like a blender has to select speeds.
But you know from experience that a single button can be used to reliably switch
between different modes. See if you can do it better. The
following challenges explore some principles of better button reading.
Basic:
Make a sketch that uses your buttons to do interesting things. Some examples:
- Turn the buttons into fader controls:
- pressing one button could make one LED get brighter, and the other could make it dimmer
- pressing one button could gradually turn on a series of LEDs, and the other could turn them off in reverse order.
- Use one or more buttons to select between different blinking patterns or to turn on different combinations of lights. Be aware that when you use the delay function your Arduino sketch can't do anything else. So, if your patterns take time like a Morse Code signal, the button will seem unresponsive until the code can get to a place where the button can be read and you can skip to the end.
Intermediate - Prevent Cycling
If you press and hold the button in the sample program, the brightness cycles. Neither HIGH not LOW is really the right time to turn the light on or off if you only want one change per push. Instead you want to pay
attention to whether the button is changing state — being pressed or being released — and
pick one of those to change the light. To do this remember the
button's previous state as well as its current state. Then you can
determine four different button events:
- resting — previous and current should match: HIGH - HIGH
- falling — previous and current will be different: HIGH - LOW
- held — previous and current should match : LOW - LOW
- rising — previous and current should be different: LOW - HIGH

Refer to File | Examples | Digital | StateChangeDetection to see how this might be done to simply turn a light on and off.
Advanced
- Write your code so that it doesn't block: If there is a long delay between when your program does an action and when it listens to the button, your program will miss button presses and it will seem slow to react. It would be better to able to detect button presses and switch patterns
while in the middle of a pattern. One way to do this is to use
non-blocking millis() function calls to control your
animation instead of delay() calls. You have a tight loop that checks to see if it's time for
the next step in the current pattern. If it is, great! Do it!
Regardless, loop back and check the button to see if it's time to
switch patterns.
Check out a simple millis() example in the Arduino software: File | Examples | Digital | BlinkWithoutDelay
- Use a hardware interrupt to detect button presses. This is the best way to detect buttons presses. Even if you have delay() based animations a button press will be noticed exactly when it happens and the new animation will start when the old one is over. The only problem is there are
only two hardware interrupt pins on your Arduino Uno, so the other
technique is still useful.
6. References
- Arduino Language Reference
- ARDX Experimenter's Guide for Arduino
- Lady Ada's Arduino Tutorial
- Wikipedia