This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
en:examples:digi:switch_debounce [2010/02/16 11:34] – mikk.leini | en:examples:digi:switch_debounce [2015/03/05 10:26] (current) – removed raivo.sell | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Filtration of switch bounce | ||
- | //Vajalikud teadmised: [HW] [[en: | ||
- | |||
- | ===== Theory ===== | ||
- | |||
- | [{{ : | ||
- | |||
- | As in the introductory chapter about switches was said, there is a problem called debouncing when we are dealing with mechanical switches or flickering. Because contacts are made of metal, what is a bit elastic, on the moment of connecting or disconnecting contacts are bouncing and it results in quite a lot of misswitchings. The number and duration of these switchings depends on the switch, but it is usually about some milliseconds. If the switch is used to start some electrical device it is not so big issue, but if the switch is used to control some device multiple switching may be harmful. | ||
- | |||
- | |||
- | [{{ : | ||
- | |||
- | Main method to avoid flickering is filtering. Filtering can be done by electrically and with software. To filter electrically there must be a low-pass filter after switch – for example a RC filter – witch anti aliases changes of voltage and therefore the pin of micro controller does not have momentary values. //RC filter is shown on the drawing//. Filtering using software is done so that the value of the pin where the switch is connected is assessed on several moments and if this value is the same on every assessment the conclusion is made that the switch is in steady position and there is no flickering. But when filtering delay for assessing the position must be taken into account. | ||
- | |||
- | |||
- | ===== Practice ===== | ||
- | |||
- | We do not use electrical filtering on home lab’s switches, because in this case we could not practice the exercise of eliminating misswitching with software. The exercise is in two parts. The goal of the first part is to demonstrate the debouncing of digital input-output module’s switches. The following program is for this, each pressing on the button lights next LED. Misswitching causes LED to light several times and it seems that LED lights arbitrarily. | ||
- | <code c> | ||
- | // | ||
- | // The Program for demonstrating switch bounce on digital input-output module of home lab. | ||
- | // | ||
- | #include < | ||
- | |||
- | // | ||
- | // Determining pins of LED-s and buttons. | ||
- | // | ||
- | pin leds[3] = { PIN(C, 5), PIN(C, 4), PIN(C, 3) }; | ||
- | pin button | ||
- | |||
- | // | ||
- | // Main program | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | unsigned char new_value, old_value = 0; | ||
- | unsigned char index, counter = 0; | ||
- | |||
- | // Setting LED pins as output. | ||
- | for (index = 0; index < 3; index++) | ||
- | { | ||
- | pin_setup_output(leds[index]); | ||
- | } | ||
- | |||
- | // Setting button' | ||
- | pin_setup_input(button); | ||
- | |||
- | // Endless loop | ||
- | while (true) | ||
- | { | ||
- | // Reading the state of the button. | ||
- | new_value = pin_get_value(button); | ||
- | |||
- | // Control, wether the button is pushed down, | ||
- | // that means is the new state 1 and old 0. | ||
- | if ((new_value) && (!old_value)) | ||
- | { | ||
- | // Enlarging the reader and taking module 3 | ||
- | counter = (counter + 1) % 3; | ||
- | |||
- | // Lighting LED witch corresponds to the value of the reader. | ||
- | for (index = 0; index < 3; index++) | ||
- | { | ||
- | pin_set_to(leds[index], | ||
- | } | ||
- | } | ||
- | |||
- | // Remember the old state. | ||
- | old_value = new_value; | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | There are several methods to filter using software. It can be done easy way or complex way each way has advantages and defects. If the program is such that pressing the button is seldom, there may be a long pause after registering pushing the button, this excludes reaction on the switching caused by bounce. When using that solution one thing must be taken into account – if the user holds the button down for a long time, the program reacts also on misswitching caused by releasing the button. Dependable is such program witch controls the state of the switch several times after certain time periods (the more and longer time the merrier). The following is a function for reading filtered values of a button of digital input-output expansion module. | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Function for reading filtered values of a IO extension module. | ||
- | // | ||
- | unsigned char pin_get_debounced_value(pin button) | ||
- | { | ||
- | unsigned char buffer = 0xAA; | ||
- | unsigned char timeout = 100; | ||
- | |||
- | // We wait until the status of the button is celar or clearing the state expires | ||
- | while (timeout-- > 0) | ||
- | { | ||
- | // Having 8 place (bit) bufffer of state. | ||
- | // All previous states (bits) are shifted to left | ||
- | // and a new state(bit) is added to the right. | ||
- | buffer <<= 1; | ||
- | buffer |= (pin_get_value(button) ? 0x01 : 0x00); | ||
- | |||
- | // If all 8 bits are high, then the button is definitely pressed down | ||
- | if (buffer == 0xFF) | ||
- | { | ||
- | return 1; | ||
- | } | ||
- | |||
- | // If all 8 bits are low, then the button is definitely up. | ||
- | if (buffer == 0x00) | ||
- | { | ||
- | return 0; | ||
- | } | ||
- | |||
- | // 1 ms break. | ||
- | // This function can be found from the library of the home lab. | ||
- | sw_delay_ms(1); | ||
- | } | ||
- | |||
- | // If we can not examine the state, then we assume that the button was not pressed. | ||
- | return 0; | ||
- | } | ||
- | </ | ||
- | |||
- | This function generates delay using a function witch is explained in corresponding exercise. At this moment we do not need to know nothing else about that function than that it generates a 1 ms delay in the end of each cycle of reading the state of the button. If the button is in the same position on 8 readings, it returns counted position. All this procedure may take up to 100 ms if the button is unstable. This function is included in the library of pins so there is no need to add it to the program for passing the example. To try that first part of the exercise has to be changed a little | ||
- | |||
- | <code c> | ||
- | // | ||
- | // The program for filtering the debounch of buttons of digital input-output | ||
- | // module of the home lab. | ||
- | // | ||
- | #include < | ||
- | #include < | ||
- | |||
- | // | ||
- | // Determining pins of LED-s and buttons. | ||
- | // | ||
- | pin leds[3] = { PIN(C, 5), PIN(C, 4), PIN(C, 3) }; | ||
- | pin button | ||
- | |||
- | // | ||
- | // Main program | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | unsigned char new_value, old_value = 0; | ||
- | unsigned char index, counter = 0; | ||
- | |||
- | // Setting the pins of LED-s as outputs. | ||
- | for (index = 0; index < 3; index++) | ||
- | { | ||
- | pin_setup_output(leds[index]); | ||
- | } | ||
- | |||
- | // Setting the pins of button as input. | ||
- | pin_setup_input(button); | ||
- | |||
- | // Endless loop. | ||
- | while (true) | ||
- | { | ||
- | // Reading the state of the button. | ||
- | new_value = pin_get_debounced_value(button); | ||
- | |||
- | // Control whether the button was pressed down, that means, | ||
- | // is the new state 1 and the old state 0. | ||
- | if ((!new_value) && (old_value)) | ||
- | { | ||
- | // Widening the counter and taking module number 3. | ||
- | counter = (counter + 1) % 3; | ||
- | |||
- | // Lighting the LED witch corresponds to the value of the counter. | ||
- | for (index = 0; index < 3; index++) | ||
- | { | ||
- | pin_set_to(leds[index], | ||
- | } | ||
- | } | ||
- | |||
- | // Remember the old state. | ||
- | old_value = new_value; | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | If we test this program now, the LED-s are lighting exactly in this sequence as the user is pressing the switch. |