Debounce not debouncing?!
Zeus
Posts: 79
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
Any help is appreciated.
Zeus
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
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.
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
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
De-bouncing a switch can be "simply" done with an R/C circuit:
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...
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.