Shop OBEX P1 Docs P2 Docs Learn Events
Debounce not debouncing?! — Parallax Forums

Debounce not debouncing?!

ZeusZeus Posts: 79
edited 2013-03-30 14:34 in BASIC Stamp
Hello All,

Below is my code. My IN4 button is not debouncing and I cannot figure out why. IN0 & IN1 are laid out in a similar manner and debounce as expected.

I have put in Debug statements to track the number of IN4 bounces and it consistently delivers a value of 4 inputs despite being debounced. What am I missing?

The code essentially repeats itself as the user inputs more data, so the net result is that my code jumps the fourth data entry position, and skips the 2 & 3 positions when IN4 is pressed. (It is code to set the time and date on an alarm clock.)

I am using a BS2p
Set_Mode:

  SEROUT LCD, Baud, [22, 17, $0C]               ' "$0C" Clears LCD Display.
  SEROUT LCD, Baud, ["Enter 2 digit year"]

  IF (IN4 = 0) THEN
  BT4 = BT4 + 1
  DEBUG CR, CR, CR, CR, DEC3 BT4
  ENDIF

    DO

      BUTTON 0, 0, 250, 250, wkspc0, 1, Increment
      BUTTON 1, 0, 250, 250, wkspc1, 1, Decrement
      BUTTON 4, 0, 255, 250, wkspc4, 1, Again

     GOTO Again

      Increment:

       year = year + 1
       SEROUT LCD, Baud, [148, DEC2 year]
       GOTO Again

      Decrement:

       year = year - 1
       SEROUT LCD, Baud, [148, DEC2 year]

      Again: LOOP UNTIL (IN4 = 0)


  SEROUT LCD, Baud, [$0C, "Enter 2 digit month"]

  IF (IN4 = 0) THEN
  BT4 = BT4 + 1
  DEBUG CR, "Button 4 = ", DEC3 BT4
  ENDIF

   DO 'UNTIL (IN4 = 0)

    BUTTON 0, 0, 200, 200, wkspc1, 1, IncrementM
    BUTTON 1, 0, 200, 200, wkspc0, 1, DecrementM
    BUTTON 4, 0, 200, 200, wkspc4, 1, AgainM

  DEBUG BELL

      DEBUG HOME, ? IN0, ? IN1, ? IN4, ? month

     GOTO AgainM

      IncrementM:

       month = month + 1
       SEROUT LCD, Baud, [148, DEC2 month]
       GOTO AgainM

      DecrementM:

       month = month - 1
       SEROUT LCD, Baud, [148, DEC2 month]

      AgainM: LOOP UNTIL (IN4 = 0)


  SEROUT LCD, Baud, [$0C, "Enter 2 digit date", CR]

  IF (IN4 = 0) THEN
  BT4 = BT4 + 1
  DEBUG CR, "Button 4 = ", DEC3 BT4
  ENDIF

  DO 'UNTIL (IN4 = 0)

      BUTTON 0, 0, 200, 200, wkspc1, 1, IncrementD
      BUTTON 1, 0, 200, 200, wkspc0, 1, DecrementD
      BUTTON 4, 0, 200, 200, wkspc4, 1, AgainD

      DEBUG HOME, ? IN0, ? IN1, ? IN4, ? Date

     GOTO AgainD

      IncrementD:

       Date = Date + 1
       SEROUT LCD, Baud, [148, DEC2 Date]

      DecrementD:

       Date = Date - 1
       SEROUT LCD, Baud, [148, DEC2 Date]
       GOTO AgainD

      AgainD: LOOP UNTIL (IN4 = 0)


  SEROUT LCD, Baud, [$0C, "Enter day of week", CR, "1 = SUN... 7 = SAT", CR]

  IF (IN4 = 0) THEN
  BT4 = BT4 + 1
  DEBUG CR, "Button 4 = ", DEC3 BT4
  ENDIF

    DO UNTIL (IN4 = 0)

      BUTTON 0, 0, 200, 200, wkspc1, 1, IncrementDay
      BUTTON 1, 0, 200, 200, wkspc0, 1, DecrementDay
      BUTTON 4, 0, 200, 200, wkspc4, 1, AgainDay

      DEBUG HOME, ? IN0, ? IN1, ? IN4, DEC2 Day

     GOTO AgainDay

      IncrementDay:

       Day = Day + 1
       SEROUT LCD, Baud, [168, DEC2 Day]
       GOTO AgainDay

      DecrementDay:

       Day = Day - 1
       SEROUT LCD, Baud, [168, DEC2 Day]

      AgainDay: LOOP

    modeFlag = 0


    SEROUT LCD, Baud, [$0C, "Enter 2 digit hour,", CR, "00-23", CR]

      IF (IN4 = 0) THEN
  BT4 = BT4 + 1
  DEBUG CR, "Button 4 = ", DEC3 BT4
  ENDIF

    DO UNTIL (IN4 = 0)

      BUTTON 0, 0, 200, 200, wkspc1, 1, IncrementH
      BUTTON 1, 0, 200, 200, wkspc0, 1, DecrementH
      BUTTON 4, 0, 200, 200, wkspc4, 1, AgainH

      DEBUG HOME, ? IN0, ? IN1, ? IN4, CR, DEC2 hrs

     GOTO AgainH

      IncrementH:

       hrs = hrs + 1
       SEROUT LCD, Baud, [148, DEC2 hrs]
       GOTO AgainH

      DecrementH:

       hrs = hrs - 1
       SEROUT LCD, Baud, [148, DEC2 hrs]

      AgainH: LOOP


  SEROUT LCD, Baud, [$0C, "Enter 2 digit minutes, 00-59:", CR]

    IF (IN4 = 0) THEN
  BT4 = BT4 + 1
  DEBUG CR, "Button 4 = ", DEC3 BT4
  ENDIF

      DO UNTIL (IN4 = 0)

      BUTTON 0, 0, 200, 200, wkspc1, 1, IncrementMins
      BUTTON 1, 0, 200, 200, wkspc0, 1, DecrementMins
      BUTTON 4, 0, 200, 200, wkspc4, 1, AgainMins

      DEBUG HOME, ? IN0, ? IN1, ? IN4, CR, DEC2 Mins

     GOTO AgainMins

      IncrementMins:

       Mins = Mins + 1
       SEROUT LCD, Baud, [148, DEC2 Mins]
       GOTO AgainMins

      DecrementMins:

       Mins = Mins - 1
       SEROUT LCD, Baud, [148, DEC2 Mins]

      AgainMins: LOOP

  ' Setting clockMode to modeFlag will effectively
  ' set or clear BIT7 in the hrs variable.

  clockMode = modeFlag


  ' Setting ampm to ampmFlag will effectively set BIT5 in the
  ' hrs variable to the proper value.
  ' This must only be done when modeFlag is set (12 Hour Mode),
  ' otherwise you can destroy hours above 19 in 24 Hour Mode.

  ' IF modeFlag = 1 THEN ampm = ampmFlag



  SEROUT LCD, Baud, [$0C, "Press SNOOZE to set time", CR]
  DEBUGIN work
  RETURN                                ' Send Time/Date To DS1302


Any help is appreciated.

Zeus

Comments

  • Tracy AllenTracy Allen Posts: 6,664
    edited 2013-03-27 09:10
    Hi Zeus,

    The program has gotten a bit more complicated!

    The problem I see is that it is testing in4 both with a BUTTON command and with direct tests of state. If you're going to use the BUTTON command, stick to it.
    [SIZE=1][FONT=courier new]  SEROUT LCD, Baud, [ "Enter 2 digit year"]
      DO
        BUTTON 0, 0, 250, 250, wkspc0, 1, Increment
        BUTTON 1, 0, 250, 250, wkspc1, 1, Decrement
        BUTTON 4, 0, 255, 0, wkspc4, 1, Done
      GOTO Again
    Done:
      EXIT  '  move on to the month
    Increment:
      year = year + 1
      SEROUT LCD, Baud, [ 148, DEC2 year]
      GOTO Again
    Decrement:
      year = year - 1
      SEROUT LCD, Baud, [ 148, DEC2 year]
    Again: LOOP[/FONT][/SIZE]
    
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2013-03-28 09:07
    I agree with Tracy...in looking at this code you have a DO...LOOP that has a conditional LOOP UNTIL (IN4 = 0), so each pass through the loop this is being evaluated and, when true will exit the loop with your BUTTON command never having been executed.

    I'd also suggest that when posting this much code, just attach the entire program (as an attachment). In order to really see your code I pasted it into the BASIC Stamp Editor and quickly realized it wouldn't compile due to missing directives and code blocks. This makes it more difficult to see what the code is doing.

    Finally, when testing multiple buttons, I wouldn't even use the BUTTON command myself. There is an example of debouncing multiple inputs in the StampWorks Manual, which can be downloaded free in PDF format from the following link.

    http://www.parallax.com/StoreSearchResults/tabid/768/txtSearch/stampworks/List/0/SortField/4/ProductID/144/Default.aspx
  • ZeusZeus Posts: 79
    edited 2013-03-30 08:25
    Thanks for the posts guy, sorry about the delayed reply.

    Tracy - Good point, I was making it more complicated that it needs to be. I was able to get it to work with the code I posted however you way is cleaner. Also, are you ever going to write a book about PBasic coding? If not please consider it.

    Chris - I will look over the manual again. I either missed it the first time or it was not straight forward enough for where I was at the time coding wise. I didn't post all of my code because I thought it was too much as it was, sorry if there was any confusion. (I am actually trying to adapt your DS1302 Demo code.)

    Thank you both,

    Zeus
  • davejamesdavejames Posts: 4,047
    edited 2013-03-30 10:58
    Hi Zeus - jumping in after the fact so if this tidbit isn't applicable, feel free to ignore.

    De-bouncing a switch can be "simply" done with an R/C circuit:

    image_1.png


    The time constant is chosen such that it's longer than the switch bounce. Yes, to properly pick the values of R & C, it would be advantageous to 'scope the signal.

    I had the opportunity to pick between the BUTTON command and this hardware approach. I picked H/W.

    There's a little bit more information here:
    http://forums.parallax.com/entry.php/178-Of-Things-Buttons-amp-Latches...
    135 x 133 - 2K
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2013-03-30 14:34
    Zeus, your choice to use BUTTON in this case is justified, because you want to use the auto-repeat functionality on in0 and in1. It is possible to do that with code you write yourself, but BUTTON takes care of all the messy details for you. That is really the only case under which I would use BUTTON.

    There are two meanings of debouncing. One that Dave mentioned rejects the rapid on and off conditions that happen when a mechanical pushbutton bounces as it first makes/breaks contact. The second is usually in the form of code that makes sure a button has gone to a high state before it can again take an action that happens on on the high to low transition. The BUTTON command with the 255 argument takes care of this last type of debounce, and it sort of takes care of the mechanical bounce by virtue of the 10s of milliseconds between times it samples the inputs as the program goes around its loop. A slow bounce or a noise pulse can fool the code, so it is nice to have both types of debouncing for added security.

    It is easy enough to make code, without using the BUTTON command, that will execute only on a high to low transition. It needs only one extra bit variable and less overhead than BUTTON. That could be done for your in4 variable, because it does not call for autorepeat.

    Thanks for the suggestion about writing PBASIC book. I'm much too slow about writing for something like that, with no definite audience in mind, and I'm a slow learner -- The time for it is past. I do enjoy helping with specific issues as they come up here on the forum. That helps me focus too. These days I find myself doing more coding with the Propeller than with the BASIC Stamp. But the Stamp remains a great tool.
Sign In or Register to comment.