Tag Archives: Switch Debouncing

Switch Debouncing Tutorial

Switch Debouncing Tutorial Pt/2

 

In this switch debouncing tutorial part 2 C code debounce algorithms will be looked at further, and their effectiveness.  All the software solutions shown will be demonstrated on the MSP430G Launchpad.  However the basic principle of operation shown in the examples, can be applied to all microcontrollers, particularly the last example which is based on some code found at Jack Ganssle tutorial, this can be easily implemented on any system using the C language.

MSP430 Single Switch Debounce WatchDog

The first debounce algorithm example is based on some Arduino code, which uses the millis() function.  In this case the millis second count is generated by the watchdog timer on the MSP430.  The launchpad switch connected to GPIO P1.3 is used in this test code.

The while loop on line 1 is inside the main function, line 5 AND’s port 1 with BIT3 as this is the only GPIO pin of interested.  Lines 6 to 9 will set the variable reading to a 1 if the value on pin P1.3 is a 1 i.e. not pressed, and 0 if the switch is pressed.  Lines 11 and 12 check to see if the switch has changed from it’s previous stored state, if this is true then the time when the switch was pressed is saved to the variable lastDebounceTime.  Lines 14 and 15 determine if the switches state hasn’t changed for a time equal to the variable debounceDelay, this then means that it is the current stable state of the push switch.  The stable state is assigned to the variable switchState, then lines 17 to 20 determine the if the LED connected to GPIO P1.0 is on or off.   The debounceDelay was set to 10, and the algorithm performed very well allowing fast presses of the single switch, without any issues.

The watchdog timer was used in this example as it was simple to set-up and generate an interrupt every 0.5mS.  Lines 36 to 33 show the interrupt handler, some basic statements inside the interrupt generate a 1mS count, which continuously increments.  The function Mils_Count() in lines 35 to 39, is used to obtain the current count value.  The watchdog timer is not meant to be used in this way, but it is so often disabled in many examples, yet is a resource that can be exploited.  If you were producing a production embedded system this would probably not be the case, but this adds a little extra functionality to some of the low end MSP430G devices.  The watchdog set-up shown will be used in some of the other debounce examples in this tutorial, and can easily be substituted with a standard timer.

MSP430 Single Switch Debounce WatchDog Example Code

The link below contains the zip file with the full example C code, there is a small advert page first via Adfly, which can be skipped and just takes a few seconds, but helps me to pay towards the hosting of the website.

MSP430 Single Switch Debounce WatchDog

I take great care when writing all the tutorials and articles, ensuring all the code is fully tested to avoid issues for my readers.  All this takes time and a great deal of work, so please support the site by using the Adfly links etc.  If you have found this useful or have any problems implementing, please feel free to leave a comment and I will do my best to help.

MSP430 Interrupt Button Control

The second example configures the GPIO pins to trigger interrupts when a change in state is detected, which is caused by a switch being pressed.  Only the interrupt handler is shown in the code snippet below, but the entire C code can be downloaded further down the page.

There are two GPIO pins set-up to generate interrupts P1.3 and P1.7.  When a switch is pressed on either of these pins, the interrupt handler is called.  The switch case statements are used here, the port 1 interrupt flag register (P1IFG) being used as the switch.  Once the correct pin interrupt has been identified, the interrupt edge select is toggled (lines 8 and 14).  Then the corresponding LED is toggled, as shown in lines 9 and 15.  Lines 10 and 16 use a delay function which basically waits for 40mS (1MHz clock).  This produced a reasonable outcome at slow to medium rates, pressing the switch at a faster rate produced indeterminate results.  The delay function is not the best method to carry out a delay as it wastes CPU time.  This technique is also not as robust a the first algorithm, especially if the switch is pressed quickly, but it does allow a whole port of switches to be used.

MSP430 Interrupt Button Control Example Code

The link below contains the zip file with the full example C code, there is a small advert page first via Adfly, which can be skipped and just takes a few seconds, but helps me to pay towards the hosting of the website.

MSP430 Interrupt Button Control

I take great care when writing all the tutorials and articles, ensuring all the code is fully tested to avoid issues for my readers.  All this takes time and a great deal of work, so please support the site by using the Adfly links etc.  If you have found this useful or have any problems implementing, please feel free to leave a comment and I will do my best to help.

  

MSP430 Multiple Switch Debounce WatchDog

The third example has two examples of switch debounce algorithms, these are split into two individual functions which can be run from the main function, simply by commenting one of them out at a a time.  The functions incorporate aspects of the previous two examples, allowing multiple switches to be debounced.  The code snippet below shows both of the functions Press_Time() and Debounce_Buttons() residing inside a while loop, which is inside the main function.

The Press_Time() function will be looked at first.

Starting with line 3, the if statement is used to ensure that the switches connected to BIT3 or BIT7 have been pressed, if not the statement is considered false.  Line 5 assigns the variable state with the AND’ed value of port 1 (P1IN) with hex value 0x88 or binary 10001000.  Line 7 assigns the current Mils_Count() value to the variable Reaction_Count.  The switch case statements are used here with the variable state being used as the switch.  If the switch on P1.7 is pressed then the case statement on line 14 will be selected.  A while loop is then entered, which waits until the current Mils_Count() minus the variable Reaction_Count is greater than the variable Button_Reaction_Delay.  This allows a tunable delay to be entered with ease, for testing a delay of 100-150mS was found to produce satisfactory results.  This method produced better results than the interrupt method, but will suffer with increased switching speed.

The second function Debounce_Buttons() is basically a copy of the first example.  The variables are just doubled up and surrounded by a if statement so the code is only executed when a switch is pressed.

This works well as per the first example but with two switches, however the code is very inefficient, due to the large number if statements that are executed each time a switch is pressed.

MSP430 Multiple Switch Debounce WatchDog Example Code

The link below contains the zip file with the full example C code, there is a small advert page first via Adfly, which can be skipped and just takes a few seconds, but helps me to pay towards the hosting of the website.

MSP430 Multiple Switch Debounce WatchDog

I take great care when writing all the tutorials and articles, ensuring all the code is fully tested to avoid issues for my readers.  All this takes time and a great deal of work, so please support the site by using the Adfly links etc.  If you have found this useful or have any problems implementing, please feel free to leave a comment and I will do my best to help.

MSP430 Ganssle Switch Debounce Multiple Switches

This fourth and final example is based on sample code provided by Jack Ganssle, he has an excellent tutorial located here.  The code is based on his third example, there is also a good description of the code operation with his article.  The code snippet below shows the main body of the algorithm, I have made some modifications adding a compound bitwise AND operator, as well as adding some of his considerations regarding OR’ing the final debounced port value.

Line 6 shows a function call for rawPortData(), this function simply returns the current state of port 1 and can be seen below in the next code snippet.

The debounceSwitch() function returns the debouncedORd value, and is called in the following way.

The checkButtons() function uses switch case statements to interpret which switch or GPIO pin has changed, the nice part about this code is the debouncedORd value makes the code very intuitive.

This last example is easy to port to other microcontrollers, just by changing the code in functions checkButtons() and rawPortDate().  Needless to say this code works very well and produces excellent results with the PCB tac switches used, under fast or slow switching.

MSP430 Ganssle Switch Debounce Multiple Switches Example Code

The link below contains the zip file with the full example C code, there is a small advert page first via Adfly, which can be skipped and just takes a few seconds, but helps me to pay towards the hosting of the website.

MSP430 Ganssle Switch Debounce Multiple Switches

I take great care when writing all the tutorials and articles, ensuring all the code is fully tested to avoid issues for my readers.  All this takes time and a great deal of work, so please support the site by using the Adfly links etc.  If you have found this useful or have any problems implementing, please feel free to leave a comment and I will do my best to help.

Switch Debouncing Tutorial

Switch Debouncing Tutorial Pt/1

 

In this switch debouncing tutorial part 1 the cause and effect of switch bounce will be explained and demonstrated, then a cost effective hardware debouncing solution will be discussed, with oscilloscope captures to demonstrate the results.  The last section of part 1 will show a simple program based on the MSP430 , this can be used to see the effects of a particular switch connected to the GPIO.  Switch deboucing tutorial part 2 of this tutorial will look at further C code debounce algorithms and their effectiveness.

All the software solutions shown will be demonstrated on the MSP430G Launchpad.  However the basic principle of operation shown in the examples, can be applied to all microcontrollers, particularly the last example which is based on some code found on Jack Ganssle tutorial, this can be easily implemented on any system using the C language.

Switch Contact Bounce

Switch contact bounce is a common issue for all mechanical switches, this includes mechanical relays.  The contact bounce occurs when the metal contacts of the switch are forced together, the property of the metals used causes the contacts to bounce apart.  How often the contacts bounce apart before finally latching shut depends on the contact type and the property of the switch.  The bouncing effect can causes multiple high frequency pulses, as opposed to a clean transition at the output.  If we take an example of a microcontroller with a switch connected to one of it’s GPIO pins, the microcontroller is able to read these high frequency pulses, misinterpreting them as legitimate presses, resulting in an undesired action.

The image below shows a basic circuit used to test switch contact bounce.

Switch Debouncing Tutorial switch circuit without debounce

With the circuit constructed on some breadboard, an oscilloscope was connected to the GPIO pin header and set to trigger when the switch was pressed, the resultant capture can be seen below.

Switch Debouncing Tutorial switch without debounce circuit poor quality switchThe oscilloscope captures shows the steady state of just over 3.3V, as the switch is pressed and released, multiple pulses are visible during this time.  The switch used for this capture was an old switch I found in a bag of spares I had, it was a small momentary touch which had a sprung button.  Many of these extra pulses would be picked up by a microcontroller, causing unexpected behaviour with your program if no debouncing was used.

The next oscilloscope capture was taken using a small PCB mounted tac switch, this was set-up in the same way as the previous test.

Switch Debouncing Tutorial switch without debounce circuit good quality

It can clearly been seen that this inexpensive PCB switch has a far superior switching action, but there is still bouncing going on, as the expanded image below shows in greater detail.

Switch Debouncing Tutorial switch without debounce circuit good quality zoomed

Hardware Solution

There are many hardware solutions to solve switch contact bounce, ranging in price from a dedicated microcontroller programmed purely to act as a debouncer, or a dedicated key encoder (MM74C923) with built in debounce, to a low end solution using just a resistor and capacitor.  This tutorial will only cover the latter option, as when combined with a suitable software algorithm, provides a cost effective solution for most small microcontroller applications.

A simple resistor capacitor switch deboucing circuit can be seen below.

Switch Debouncing Tutorial switch circuit with debounce

 

The resistor capacitor combination forms an RC circuit, which has a time constant determined by τ = R*C, therefore 47kΩ*100nF = 4.7mS.  The capacitor is considered charged after approximately 5*τ, therefore roughly 25mS.  So when the switch S2 is pressed effectively closing the switch, the voltage across the capacitor is discharged through the switch to ground.  As there is very little resistance this happens quickly, but as will be shown not instantly.  When the switch is released and becomes open, the capacitor is charged via R2 and should take approximately 25mS to charge back up to the supply voltage.  Any spikes caused by bouncing contacts are absorbed by the RC circuit, however care must be taken when selecting the values to ensure the switching action is fast enough for the project.  If the resistor or capacitor is too large the time lag may cause the system responsiveness to suffer, too small and a switch with a long bounce characteristic will still have an issue.  Capturing the switch bounce with an oscilloscope is the best way to view the problem and then take the appropriate action.  The oscilloscope capture below shows the circuit in action using the cheap PCB tac switch.

Switch Debouncing Tutorial switch with debounce

This clearly shows a huge improvement in the switching noise, the falling edge shows a clean edge, while the leading edge is curved due to C1 charging through R2.  The next image shows the falling edge of the capture on a smaller time base.

Switch Debouncing Tutorial switch with debounce falling edge

The falling edge can still be seen to show the capacitor discharge curve, this takes approximately 1uS, therefore the resistance to ground is approximately 2Ω.  The next image shows the rising edge of the capture on a smaller time base, the image clearly shows the capacitor curve levelling off around 25mS.

Switch Debouncing Tutorial switch with debounce rising edge

This circuit will work sufficiently in most situations, but it is best practice to discharge the capacitor in a more controlled fashion, especially if there are higher currents and voltages involved.  A second resistor can be used in conjunction with R2, thus ensuring C1 has a higher resistance path to ground, when the switch S2 is closed.  The image below shows a circuit using this additional resistor (R1).

Switch Debouncing Tutorial switch circuit with debounce 2nd resistor

The combination of R1 and R2 has very little impact on the original time constant, but allows a controlled discharge of the capacitor to ground.  The value of R1 would typically be less than 6.8kΩ, being dependant on the requirements of the system.  This will ultimately improve the life of the switch, as it avoids high instantaneous currents.

Before finishing part 1 of this tutorial, a basic code example is shown below which allows some of the contact bounces from a switch to be recorded on a MSP430 Launchpad.

The code snippet above is used with an external switch, connected to GPIO pin P1.0, which is configured to function with Timer0_A.  Timer0_A is set-up in capture mode and configured to trigger an interrupt on every falling edge pulse.  Every time the interrupt is triggered the variable count is incremented, therefore by running this code it is possible to determine roughly how noisy a switch is.  To see the updated count value, the code can be run then the switch pressed, the code can then be paused to check the value of Count, or a breakpoint can be set and the variable Count watched.

Test Code

The link below contains the zip file with the full example C code, there is a small advert page first via Adfly, which can be skipped and just takes a few seconds, but helps me to pay towards the hosting of the website.

MSP430 Debounce Switch Test

I take great care when writing all the tutorials and articles, ensuring all the code is fully tested to avoid issues for my readers.  All this takes time and a great deal of work, so please support the site by using the Adfly links etc.  If you have found this useful or have any problems implementing, please feel free to leave a comment and I will do my best to help.

In Part 2 debounce algorithms will shown with C examples, they will all be written to run on the MSP430 but the principle of operation can be carried over to other microcontrollers.  The last code example in particular can easily be implemented on other microcontrollers.