Shop OBEX P1 Docs P2 Docs Learn Events
Simple pushbutton counter — Parallax Forums

Simple pushbutton counter

rickrockerrickrocker Posts: 7
edited 2008-04-22 19:12 in BASIC Stamp
Hi..

I am trying a very simple experiment: I want to use the pushbutton switches as counters to store a value of the number of times the pushbutton was pressed.

So for example: If I connect a pushbutton switch in the active high state circuit (pressed down denotes a state 1) then it should add a count to a variable, say "result" every time I push the button down. Therefore if I push the pushbutton like 5 times..the variable "result" should display the value of 5 etc etc.

I was playing around with the syntax COUNT [noparse][[/noparse]pin,duration,variable] but I did not get success since the value displayed in the variable is not always the no. of times I pushed the pushbutton ???

I'm suspecting this has something to do with the debounce of the pushbutton or something...could someone clarify!

This is the code I used:

number VAR word

init CON 0

DO

COUNT 0,3000,number

DEBUG CR,CR, "Count is:",DEC number

number = init

LOOP

AND THE RESULTS I'M GETTING ARE RANGING ALL THE WAY FROM 0 - 65535 WHEN I JUST PUSH THE BUTTON LIKE 2 -3 TIMES IN A 3000ms period.

ANY HELP WOULD BE GREATLY APPRECIATED!

thanks

Comments

  • FranklinFranklin Posts: 4,747
    edited 2008-04-20 14:31
    You are correct in the fact that your problem is bounce. You could check to see if the button is pressed and then released and then pressed again at a slower rate than count does. like 10 times a second or so.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - Stephen
  • ercoerco Posts: 20,260
    edited 2008-04-20 17:28
    Definitely a bounce problem. I'd avoid the count command here. Try something simpler like this and modify as appropriate:


    for counter=0 to 255' 255=upper counter limit based on byte variable
    DEBUG CR,CR, "Count is:",DEC counter
    waithigh:if in0=0 then waithigh' wait until pin 0 goes high via button press
    pause 100' wait 100 ms
    waitlow:if in0=1 then waitlow' wait until pin 0 goes low via button release
    pause 100
    next

    Those pauses limit how quickly you can press the button, about 5 times per second here with two 100 ms pauses per buttonpress.
    For the BS1, change in0 to pin0.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·"If you build it, they will come."
  • Tracy AllenTracy Allen Posts: 6,666
    edited 2008-04-20 23:21
    If your pushbutton has a pullup or pulldown resistor, try adding a capacitor in parallel. That can help to surpress the bounce. Suppose the pulldown resistor is 10 kohms. Try a capacitor of 0.1uF. You should also put a resistor of about 200 to 300 ohms out to the switch. The purpose of that is twofold: 1) to protect the stamp against static 2) to protect the switch from excess current.

                10k          220   PB
    Vss --o--/\/\--o---/\/\---O^O----Vdd
            |          |
            |          |
            '---||---o----Stamp p0
              0.1 uF
    




    With hardware debounce like that, you can use the COUNT command. It is useful for something like an anemometer or tachometer, where you really need to count pulses for a fixed amount of time. For button presses, there is often some other purpose and you need to do something when the count reaches a set number, rather than counting for a fixed time.

    Here is another routine similar to erco's, and this should work even without a capacitor. It double checks the status of the switch:

    DO
      DO
        DO:LOOP WHILE in0  ' stays here until pin goes low
      PAUSE 32
      LOOP WHILE in0   ' second check that the pin is really low
      DO
        DO:LOOP UNTIL in0  ' stays here until pin goes high
      PAUSE 30
      LOOP UNTIL in0  ' check it twice
      counter=counter+1
      DEBUG CR,"the count is:",DEC counter
    LOOP
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • jmalaysiajmalaysia Posts: 97
    edited 2008-04-21 00:10
    I'm not sure I agree that switch bounce could add up to 65535 in 3 seconds, but I'll leave that one alone!

    I don't want to over-complicate the simple experiment, but it is bad practice to use active high switching. Noise very easily causes false switching, especially if you wind up switching inductive loads. With a inactive high state noise only adds to the existing high state, but it's still a high. When your switch is active low you can go to solid ground, which again limits the possibility of noise interference.
  • rickrockerrickrocker Posts: 7
    edited 2008-04-22 19:03
    Thanks guys for the helpful advice!
  • rickrockerrickrocker Posts: 7
    edited 2008-04-22 19:12
    10k 220 PB
    Vss --o--/\/\--o---/\/\---O^O----Vdd
    | |
    | |
    '---||---o----Stamp p0
    0.1 uF

    DO
    DO
    DO:LOOP WHILE in0 ' stays here until pin goes low
    PAUSE 32
    LOOP WHILE in0 ' second check that the pin is really low
    DO
    DO:LOOP UNTIL in0 ' stays here until pin goes high
    PAUSE 30
    LOOP UNTIL in0 ' check it twice
    counter=counter+1
    DEBUG CR,"the count is:",DEC counter
    LOOP

    Had a question about this code - How do I put this in a subroutine which accepts a user input value of 1 through 6 and then exits the loop. I was thinking if it would be necessary for it to wait for a small period of time to exit the loop with the recorded value (eg: value = 3 and wait for like 1500ms to exit) or should I add a 2nd pushbutton to confirm the value and then exit the loop?

    Thanks.
Sign In or Register to comment.