Bit banging a contact closure input
Some projects require a microcontroller to monitor a set of mechanical contacts. These contacts can range from a simple switch, push button, or a set of mechanical relay contacts. The issue with monitoring these mechanical interfaces is they tend to be very noisy. Figure 1 shows a typical mechanical contact interface along with the contact closure signal.
Figure 1. Mechanical contact interface with resultant electrical signal
Figure 1 also shows the initial electrical contact followed by a larger "bounce." This bounce is then followed by a "spray" of impulses also known as the contact chatter. To reliably detect the mechanical contact state, we must find a way to filter the bounce and chatter into a clean and reliable signal.
Before we go on to firmware implementations, it would be beneficial to at least mention some of the hardware approaches to solving the contact closure interface problem. All of the hardware implementations usually involve some level of filtration or state machine / counters. There are a few off-the-shelf integrated circuits that work very well for debouncing a mechanical input.
Maxim MAX6818: Originally, it appears as if Maxim created the debounce circuit to interface a manual reset push button for a microcontroller application. The MAX6818 is a bit pricey however. The single quantity cost of this device is around $7.00 and change for eight (8) contact channels. The URL for the MAX6818 debouncer IC is found at the following website:
ON Semiconductor MC14490: ON Semiconductor makes a six (6) channel switch debouncer. This part was originally made by the IC division of Motorola many years ago. I can say from personal experience, this IC works extremely well. It can also be repurposed into a nifty single-bit delay line too. The single unit cost for the MC14490 is around $3.20 or so. This is not bad for a six channel part. The URL for the MC14490 IC is as follows:
Of course, there is always the discrete hardware solution. The hardware implementation for this interface is shown in Figure 2.
Figure 2. Debouncing a switch the discrete way
The debouncing filter in this case is an RC network coupled with a Schmitt trigger. The RC time constant for the high-to-low transition is 10 milliseconds. The RC time constant for the low-to-high transition is approximately 13 milliseconds. The single pole filtration along with the Schmitt trigger usually provides an adequate filtration for the contact closure inputs. Of course, the capacitor, or the resistor values can be changed to increase or decrease the time delay and filtration.
The cost of the circuit depicted in Figure 2 is primarily with the discrete components. This is because the cost of a 74CH14 Schmitt trigger is around $0.14. The component cost makes this a very attractive solution for debouncing a contact closure input.
The downside to the discrete solution is the quantity of parts that is required to debounce each channel. For example, if you needed to debounce six channels, you only need one 74HC14 IC. However, you will need six (6) times the discrete parts (resistors, capacitors, and diodes).
Table 1 show the cost summary for each hardware solution. The rough cost per channel for the integrated solution is roughly in the $0.50 to $0.88 per channel range. The rough cost per channel for the discrete solution is approximately in the $0.12 per channel range.
Table 1. Cost and description summary of each of the hardware contact closure interface solutions
The discrete solution is clearly the cost winner here. However, it may not be appropriate when a large number of channels are needed. This is due to the large number of parts that are required to affect the discrete solution.
Hardware interface: Of course, this being the Embedded Round Table, we need to bring up a method for debouncing the interface using some type of firmware technique. The hardware implementation for the software debounce interface is shown in Figure 3.
Figure 3. Interfacing a contact closure input to a microcontroller
Figure 3 shows a nearly direct interface between the contact closure and the microcontroller port pin. Of course, we have added a 1 kohm buffer resistor and some protection diodes to protect the microcontroller port. One can see that this direct interface requires very few parts and is also very easy on the cost of goods (roughly $0.03 to $0.08 per channel).
It is also important to note that one should not do a direct interface, as shown in Figure 3 to the internal interrupt. The reason for not wiring the direct interface to an interrupt is because we do not know in advance how fast the chatter will be. It can be anywhere from microseconds to milliseconds and is completely unpredictable. It is much better to simply route the contact closure input to a port pin and to sample it using a timer interrupt.
Software schema: The approach for direct filtering the switch input is based on a shift register (single bit delay line) along with a comparator. This schema is shown in Figure 4.
Figure 4. Software control schema for debouncing a contact closure input
Figure 4 shows the sequence of ones and zeros being monitored via a timer service. This sampled data is then shifted into a shift register and the resulting shift value is compared to a comparator value. If the comparator value is either all ones or all zeros, the output state will change to a 1 or 0 accordingly. The output of the comparator will hold the last state if the compared value does NOT match an all ones or an all-zero sequence.