The image above exemplifies why you need to debounce your pushbuttons.
When people push a button, they expect one reaction per push. Due to the springy nature that pushes back at you when pressing them, buttons tend to bounce around when pressed and released, which will mess up the signal from them.
For example, let’s say we have a button that we intend to output 0V (logic 0) when pressed, and 5V (logic 1) when unpressed. If we probed the signal coming from the button during the transition from pushing it down to letting go, we would expect an immediate and clean transition from logic 0 to logic 1. What we end up seeing instead is the capture above. Before the signal settles to a flat 5V, it bounces between the two logic states many times.
Imagine if this was the signal your TV received when you pressed a button on your remote. If the signal was taken as is, and a transition from 0 to 1 meant increment the channel, you would probably have an aneurysm trying to navigate to a specific channel. This is why we need to debounce our buttons!
Debouncing attempts to ignore any intermittent jumping between logic states during an actual intended transition from 0 to 1 or 1 to 0. This can be done in hardware, with RC circuits and Schmitt trigger inverters, or in software with just the microcontroller. Let’s focus on software debouncing for now.
In this post we will first consider how to read a pushbutton input and turn on some LEDs in response. Next we will use the same hexadecimal counter circuit used in the previous post, with a pushbutton used to increment the counter, first with an undebounced implementation and then with a software debounced implementation
Reaction time is the duration of time it takes for the brain to interpret a stimulus and do something in reaction to it. The stimulus may be something visual such as a light turning on, something auditory such as a beep, or a touch cue such as a poke. The time it takes for the brain to interpret a stimulus and respond to it can be used as a basic benchmark to measure and compare mental acuity.
We will be implementing a reaction timer on an FPGA that turns on an LED after a psuedorandom period of time, and uses a pushbutton as a reaction input. There will be 3 input buttons: clear, start, and stop. The system will begin in an idle state waiting for the user to press the start button. When the start button is pressed, a random time interval will elapse before the LED turns on. When the LED turns on a reaction timer will begin counting the number of milliseconds until the user presses the stop button. When the stop button is pressed, the reaction time will be shown on a 4 digit 7-segment display in the format “0.000” seconds, up to a value of 9.999 seconds. The user can then press the clear button to reset the time display and go back to the idle state.
For this project we will be using the Basys 2 FPGA development board to implement the design, as it has the 4 digit display, pushbuttons, and LED that we need onboard.
In the previous post we learned how to blink an LED with an ATtiny85 by using a _delay_ms() function to halt the program execution after turning on and off the LED. The downside to this approach is that the _delay_ms() causes our code to hang up while the function spins in a loop up to the specified time. This is a waste of CPU clock cycles, and makes doing anything else in the event loop nearly impossible. Let’s stop the pointless spinning.
In this post I will introduce the two timer/counter hardware peripherals that are inside the ATtiny85 chip, and show how we can offload the job of blinking an LED to one of them with the added benefit of using no clock cycles on the task. This frees the CPU up to do whatever else we wish while our LED reliably blinks away. If you are coming from a typical Arduino upbringing, this sort of flexibility and power is what makes learning how to truly program a microcontroller and its peripherals worth the effort.
The ATtiny85 is a cute little AVR microcontroller that might surprise you with what it can do. We will be considering the 8 pin PDIP version shown above, since we can easily stick it in a breadboard and prototype away. In this project, we will get our toolchain up and running for the first time, and flash some code to blink an LED!
FPGA Development boards usually run on a high frequency oscillator in the tens or hundreds of Megahertz range. One way to toggle an IO line at a slower frequency is to use a counter circuit. I will show you how to write some Verilog code that divides down a high clock frequency to a more human friendly time scale, and blink some LEDs!