Lab 2: Button Challenge!
Challenge (Bonus Mark)
Read the section titled More Advanced Decision Making, and try to get it work. 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 probably 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 hints explain some principles of better button reading.
Basic:
Make a sketch that uses a button or buttons to do three or more different interesting things. Be aware that if your interesting things take time because they use the delay() command, the button may seem unresponsive while the thing is happening.
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