Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Input Debounce


  • Please log in to reply
11 replies to this topic

#1 monewwq1

monewwq1

    Advanced Member

  • Members
  • PipPipPip
  • 104 posts

Posted 30 August 2011 - 03:34 PM

Hi, I have a wall switch connected to D4 and Ground on my Netduino Plus. I am using the internal pull-up resistor and I set the glitch filter to true. The input still bounces a lot. I also tried just using jumper wires as the switch and it is still very bouncy. My code is simple. I set an Interrupt to listen for EdgeDetectBoth and in the interrupt I am just printing the status to the debug window. Any thoughts as to why it would be so bouncy? I tried putting a .1uF capacitor across the connection and that helped, but is a cap connected across D4 to Ground an Ok method to use or will this cause problems with the Netduino? Is it better to set up a software debounce?

#2 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 30 August 2011 - 03:45 PM

The capacitor is a good solution, although the glitch filter should work. I must confess that I never tested it. At the moment I have no time 'cos I'm going shopping. I hope someone is reading your post in the meanwhile. Later I may try by myself, though. Cheers
Biggest fault of Netduino? It runs by electricity.

#3 Stefan W.

Stefan W.

    Advanced Member

  • Members
  • PipPipPip
  • 153 posts

Posted 30 August 2011 - 06:45 PM

A capacitor across the switch works, however keep in mind that this means that by pressing the switch you are shortening the capacitor, which can lead to high currents through the switch. This effect can (does not have to) lead to damaged (stuck in "on" position) switches (won't likely happen the first time you try it, however if this is something that should live a long time, you might see this), you can prevent that by putting a resistor in series to the capacitor to limit the current (100 ohm should do fine). A software filter is what i'm using - i store date of the last edge, and if the timespan between the last date or the current date is too low, i discard the event. What the glitch filter does is polling multiple times, i don't know over which time domain, maybe it's too short.
I believe that no discovery of fact, however trivial, can be wholly useless to the race, and that no trumpeting of falsehood, however virtuous in intent, can be anything but vicious.
-- H.L. Mencken, "What I Believe"

#4 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 31 August 2011 - 07:02 AM

Stefan, you are right about the current peak, but it is very very short in time. Supposing the switch equivalent resistance around 1 Ohm (it is surely lower), the capacitor will be discharged in less than one microsecond. Within this short time an overheat is not possible, so nor any switch damage. It is also valuable your tip about the software debounce filter, but I think it should be already present. Either it has been implemented and it works, or it has *NOT* been implemented and we must create our own. Anyway, post the code of your solution: it may be useful sometime. Cheers
Biggest fault of Netduino? It runs by electricity.

#5 monewwq1

monewwq1

    Advanced Member

  • Members
  • PipPipPip
  • 104 posts

Posted 31 August 2011 - 06:43 PM

Stefan, you are right about the current peak, but it is very very short in time.
Supposing the switch equivalent resistance around 1 Ohm (it is surely lower), the capacitor will be discharged in less than one microsecond.
Within this short time an overheat is not possible, so nor any switch damage.

It is also valuable your tip about the software debounce filter, but I think it should be already present. Either it has been implemented and it works, or it has *NOT* been implemented and we must create our own.
Anyway, post the code of your solution: it may be useful sometime.
Cheers


I wrote a simple software de-bouncer today and it works great. I am a little surprised that we would have to do this since the glitch filter should provide this capability. I will post my code here tonight.

#6 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 31 August 2011 - 07:11 PM

I wrote a simple software de-bouncer today and it works great. I am a little surprised that we would have to do this since the glitch filter should provide this capability.

If I remember it correctly, the current implementation of glitch filter on Netduino simply reads the input 3 or 4 times, so the period is a few microseconds (I have not measured how long takes GetPinState() function call, but my guess is somewhere around 3 µs). If you implemented the de-bouncer using polling (i.e. port.Read()), it takes tens of microseconds to execute the managed method, if you used interrupt, then hundreds of microseconds - so it would mean the button produces a lot of bouncing and the firmware glitch filter period is not long enough. For the RC filter, you'd need to calculate the appropriate value of the resistor for desired time constant (100 - 200 µs, or maybe more).

#7 Stefan W.

Stefan W.

    Advanced Member

  • Members
  • PipPipPip
  • 153 posts

Posted 31 August 2011 - 10:32 PM

In case someone is searching for this in the future, this is the very simple software glitch filter i talked about:
    public class Program
    {
        private static readonly InterruptPort Button1 = new InterruptPort(Pins.GPIO_PIN_D0, false, Port.ResistorMode.PullUp,
                                                                Port.InterruptMode.InterruptEdgeLow);
        private static DateTime Button1LastPushed;

        public static void Main()
        {
            Button1.OnInterrupt += Button1_OnInterrupt;
            // ... main loop
        }
        private static void Button1_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            // glitch filter. events within 50 milliseconds of the first event are discarded
            if (Button1LastPushed.AddMilliseconds(50) > time)
                return;
 //         Debug.Print("Button 1 Interrupt");
            Button1LastPushed = time;
            // actions on interrupt here
        }
    }

Also, Mario, i definitively did read an application note for a microswitch that strongly advised against putting a "naked" capacitor across a switch because of damaging effects. If i can turn it up again (I don't recall where I found it ...) i'll link it here.

Also for the record, if someone wants to do the hardware debouncing "cleanly" it should be probably done like in this article (german text, the schematic should be understandable though) using a RC filter with a schmitt trigger. However, as software debouncing is so easy and doesn't require additional components, i just do that :) Another useful bit of information in that (german) article is that switches usually bounce for up to 10ms, so the time constants for the debouncing (software or hardware) should be chosing according to that (and no human operates a switch 100 times a second anyway)
I believe that no discovery of fact, however trivial, can be wholly useless to the race, and that no trumpeting of falsehood, however virtuous in intent, can be anything but vicious.
-- H.L. Mencken, "What I Believe"

#8 monewwq1

monewwq1

    Advanced Member

  • Members
  • PipPipPip
  • 104 posts

Posted 01 September 2011 - 01:39 AM

I set up my software debounce like this:

	static long lastDebounceTime = DateTime.Now.Ticks;  
        static long debounceDelay = 100000;   //adjust as necessary

	public static void Main() {
		InterruptPort input = new InterruptPort(Pins.GPIO_PIN_D4, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
        	input.OnInterrupt += new NativeEventHandler(input_OnInterrupt);
	}	 

	static void input_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            if ((System.DateTime.Now.Ticks - lastDebounceTime) > debounceDelay)
            {           
                lastDebounceTime = DateTime.Now.Ticks;
		// do stuff
            }
        }


Thanks everyone for the help.

#9 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 01 September 2011 - 05:18 AM

Also, Mario, i definitively did read an application note for a microswitch that strongly advised against putting a "naked" capacitor across a switch because of damaging effects. If i can turn it up again (I don't recall where I found it ...) i'll link it here.


You weren't wrong. That's surely right for electrolytic capacitors, or relatively high capacitance (i.e. over 10uF).
Since the electrolytic caps are working chemically, and excessive current may overheat the capacitor itself.
For a cap under 0.5uF there's no need of limiting resistor.

I'll take advantage to remember some "must" about the electrolytic capacitors involving enough current:
  • never ever reverse polarity;
  • never ever apply a voltage above the marked limit;
  • never ever use for AC;
  • never ever overheat, or expose at temps higher than those marked (may be missing);
  • if you feel is warmer than the environment temp, shut immediately the circuit off;
  • if you're unsure, keep wearing the safety glasses.
Outside these conditions, the capacitor MAY EXPLODE! The metallic shield is popped off by the high pressure, and it seems a bullet.
It happened to me many times, and a friend of mine almost was losing an eye.


Also for the record, if someone wants to do the hardware debouncing "cleanly" it should be probably done like in this article (german text, the schematic should be understandable though) using a RC filter with a schmitt trigger. However, as software debouncing is so easy and doesn't require additional components, i just do that Another useful bit of information in that (german) article is that switches usually bounce for up to 10ms, so the time constants for the debouncing (software or hardware) should be chosing according to that (and no human operates a switch 100 times a second anyway)

The Schmitt-Trigger is absolutely the best choice, but it is a hardware pattern. Typically a software filter is preferred, and anyone can write it.
From my viewpoint the hardware filter would be better, because it is pretty simple to build, and frees the Netduino from heavy computations. The posted code for debouncing is good, but it takes a lot of time of CPU, compared to the basic task it has to do.

Anyway, all that was a good point to highlight.
Cheers
Biggest fault of Netduino? It runs by electricity.

#10 Nevyn

Nevyn

    Advanced Member

  • Members
  • PipPipPip
  • 1072 posts
  • LocationNorth Yorkshire, UK

Posted 01 September 2011 - 08:34 AM

The Schmitt-Trigger is absolutely the best choice, but it is a hardware pattern. Typically a software filter is preferred, and anyone can write it.
From my viewpoint the hardware filter would be better, because it is pretty simple to build, and frees the Netduino from heavy computations. The posted code for debouncing is good, but it takes a lot of time of CPU, compared to the basic task it has to do.

I'd prefer the hardware approach too - once the hardware filter is in the circuit it's there for good and a programmer can't remove it by mistake.

Regards,
Mark


Edit: corrected spelling error.

Edited by Nevyn, 01 September 2011 - 08:35 AM.

To be or not to be = 0xFF

 

Blogging about Netduino, .NET, STM8S and STM32 and generally waffling on about life

Follow @nevynuk on Twitter


#11 ColinR

ColinR

    Advanced Member

  • Members
  • PipPipPip
  • 142 posts
  • LocationCape Town, South Africa

Posted 07 June 2013 - 07:01 AM

I set up my software debounce like this:  

	static long lastDebounceTime = DateTime.Now.Ticks;          static long debounceDelay = 100000;   //adjust as necessary	public static void Main() {		InterruptPort input = new InterruptPort(Pins.GPIO_PIN_D4, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);        	input.OnInterrupt += new NativeEventHandler(input_OnInterrupt);	}	 	static void input_OnInterrupt(uint data1, uint data2, DateTime time)        {            if ((time.Ticks - lastDebounceTime) > debounceDelay)            {                           lastDebounceTime = time.Ticks;		// do stuff            }        }
Thanks everyone for the help.

 

 

Some micro optimisation :) The exact time the interrupt occured is already given, no need to call DateTime.Now.



#12 Mark Anderson

Mark Anderson

    Member

  • Members
  • PipPip
  • 25 posts
  • LocationChciago

Posted 03 January 2014 - 01:54 AM

In case someone is searching for this in the future, this is the very simple software glitch filter i talked about:

    public class Program    {        private static readonly InterruptPort Button1 = new InterruptPort(Pins.GPIO_PIN_D0, false, Port.ResistorMode.PullUp,                                                                Port.InterruptMode.InterruptEdgeLow);        private static DateTime Button1LastPushed;        public static void Main()        {            Button1.OnInterrupt += Button1_OnInterrupt;            // ... main loop        }        private static void Button1_OnInterrupt(uint data1, uint data2, DateTime time)        {            // glitch filter. events within 50 milliseconds of the first event are discarded            if (Button1LastPushed.AddMilliseconds(50) > time)                return; //         Debug.Print("Button 1 Interrupt");            Button1LastPushed = time;            // actions on interrupt here        }    }
Also, Mario, i definitively did read an application note for a microswitch that strongly advised against putting a "naked" capacitor across a switch because of damaging effects. If i can turn it up again (I don't recall where I found it ...) i'll link it here.

Also for the record, if someone wants to do the hardware debouncing "cleanly" it should be probably done like in this article (german text, the schematic should be understandable though) using a RC filter with a schmitt trigger. However, as software debouncing is so easy and doesn't require additional components, i just do that Posted Image Another useful bit of information in that (german) article is that switches usually bounce for up to 10ms, so the time constants for the debouncing (software or hardware) should be chosing according to that (and no human operates a switch 100 times a second anyway)

 

 

Thanks Stefan

 

Helped me out with my project  :D






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.