Shop OBEX P1 Docs P2 Docs Learn Events
Anyone help me with a simple de-bounce idea? — Parallax Forums

Anyone help me with a simple de-bounce idea?

MoskogMoskog Posts: 554
edited 2011-08-16 22:33 in Propeller 1
Hello, I have a push button in a simple counter, counting one number upwards each time button is pressed and starting from 1 again after reaching 5.

Like this:
number := 1
repeat
  if ina[button] == %0
    number := (number + 1)
      if number == 6
        number := 1
waitcnt(clkfreq/100 + cnt)
But my problem is de-bounching and I would appreciate if anyone know a simple solution and will help!

Comments

  • RaymanRayman Posts: 14,876
    edited 2011-08-11 12:13
    easiest way is to move that waitcnt over so that it is inside the repeat loop...

    Actually, what I think is best is to first wait to detect the key down, then wait for the key to go up, and then wait a while after that for the bouncing to go away...
  • idbruceidbruce Posts: 6,197
    edited 2011-08-11 12:26
    Moskog

    Your waitcnt should be indented. Like so:
    number := 1
    repeat
      if ina[button] == %0
        number := (number + 1)
          if number == 6
            number := 1
      waitcnt(clkfreq/100 + cnt)
    

    Bruce
  • idbruceidbruce Posts: 6,197
    edited 2011-08-11 12:29
    And perhaps a longer waitcnt, depending on the type of pushbutton and contacts.
  • LeonLeon Posts: 7,620
    edited 2011-08-11 12:36
    A typical debounce delay is 20 ms. It varies with the type of switch, though.
  • max72max72 Posts: 1,155
    edited 2011-08-11 14:44
    I used this one with the 5 way switch from Parallax.
    It counts seconds, and performs the debounce on the 5 buttons.

    Massimo

    edit: it runs on a separate cog, stores the keypress and returns the reading in the main code when asked to.
    After reading the button you should "clear" it.
    
    CON
    onesec = 80_000_000
    
      
    VAR  
       long timer_stack[40] 
       long seconds
       long switch, rilasciato
       
    
    PUB start
    
      cognew(conta,@timer_stack) 
    
    pri conta|previous
      dira[16..20]~
      seconds:=0
      rilasciato:=0
      switch:=0
    '  repeat 
    '     waitcnt(cnt+clkfreq)
    '     seconds++
      
      previous:=cnt+clkfreq
      repeat
         if (cnt-previous)>0
             seconds:=seconds+1
             previous:=previous+clkfreq
         debounce
    
      
    
    pri  debounce|button
    
    
    
      if switch== 0
         button := (!ina[16..20])&%11111
    
         if (button==0)
            if rilasciato > 0
               rilasciato :=0
    
    
         if button>0
            if rilasciato ==0
               waitcnt(clkfreq/100+cnt)
               if button == (!ina[16..20])&%11111
                  switch:=button
                  rilasciato:=1
        
    
    pub bottoni
      return switch
    
    pub clear_bottoni
        switch:=0                  
          
    pub tempo
       return seconds
    
    
  • frank freedmanfrank freedman Posts: 1,983
    edited 2011-08-11 15:05
    idbruce wrote: »
    And perhaps a longer waitcnt, depending on the type of pushbutton and contacts.

    Additionally, you may want to have the routine after waiting for bounce to settle, make an additional delay and retest as a "Yes, the switch was really pushed" to separate accidental from deliberate presses of the switch.
  • JonnyMacJonnyMac Posts: 9,208
    edited 2011-08-12 07:45
    Here's a simple method I use from time-to-time; it let's me specify which pin to use, the state to look for (so it works with active-high and active-low), as well as the debounce duration (in milliseconds). If the pin is held in "state" for the specified period the method returns True.
    pub debounce (pin, state, ms) | t, db
    
    '' Returns True if pin is held in state (0 or 1) for ms milliseconds
    
      dira[pin] := 0                                                ' make pin an input
      db := 0                                                       ' clear debounce counter
    
      t := cnt
      repeat ms
        if (ina[pin] == state)                                      ' if button pressed
          db += 1                                                   '  increment counter
        else                                                        ' else
          db := 0                                                   '  reset counter
        waitcnt(t += clkfreq / 1_000)
    
      return (db == ms)
    

    The method always runs ms milliseconds. If you want an early exit, replace the else clause (db := 0) with quit.
  • MoskogMoskog Posts: 554
    edited 2011-08-16 22:33
    Lots of good ideas here, thanks to all for your replies!
Sign In or Register to comment.