Shop OBEX P1 Docs P2 Docs Learn Events
BS1 One minute timer with a button — Parallax Forums

BS1 One minute timer with a button

Hello!
I need to run a timer for 1 minute and check if Pin 1 is high (button press). When Pin1 is high get out of the loop. Whats the best way to do this on the BS1 ????
So far I have this but is not accurate...

SYMBOL A = B2

FOR A = 0 TO 255 ' 1 minute
PAUSE 200
IF PIN1=1 THEN Routing1
NEXT

Thanks for any help!

Comments

  • 256 * 200ms = roughly 51 seconds, a little short of 1 minute. If the 1 minute is crucial to your application, make the PAUSE a little longer. If the issue is the granularity of the test for the button press (200ms), make the size of the PAUSE smaller (like 100ms) and increase the loop size (like FOR A = 0 to 511). You'll have to make variable A a word instead of a byte.

  • Luis_PLuis_P Posts: 246
    edited 2021-09-14 16:12

    @"Mike Green" said:
    256 * 200ms = roughly 51 seconds, a little short of 1 minute. If the 1 minute is crucial to your application, make the PAUSE a little longer. If the issue is the granularity of the test for the button press (200ms), make the size of the PAUSE smaller (like 100ms) and increase the loop size (like FOR A = 0 to 511). You'll have to make variable A a word instead of a byte.

    Thanks Mike!

  • JonnyMacJonnyMac Posts: 9,105
    edited 2021-09-15 20:44

    I've done lots of little industrial projects with the BS1. Note that this kind of programming

      IF PIN1=1 THEN Routing1
    

    is dangerous for two reasons.

    1) Best practice is to used named symbols. I suggest you do this instead.

    OVERRIDE = PIN7
    

    2) Debouncing inputs can eliminate problems

    True story: A professional haunted house in NYC was about to open and on their walk-through things went berserk. Why? Because any time someone keyed a radio, prop swould act as if they'd been triggered. When they showed me their code, it was looking at trigger inputs the same as you're doing. The key was to debounce the triggers. That solved the problem.

    Here's routine that will let you delay up to 255 seconds and can be aborted by pressing a button (be sure to use a pull-down on that input) for 100ms. This may look a little scary at first, but I've deployed this code many times and it works well. Call with GOSUB Delay.

    ' put delay into dlySecs
    ' put 0 in btnCnt before calling
    
    Delay:
      IF dlySecs = 0 THEN Delay_Exit                ' done?
        FOR x = 1 TO 100                            ' delay 1s
          PAUSE 10
          btnCount = btnCount + 1 * OVERRIDE        ' check button
          IF btnCount = 10 THEN Delay_Exit          ' if held 100ms, abort
        NEXT
        dlySecs = dlySecs - 1
        GOTO Delay
    
    Delay_Exit:
      RETURN
    

    There is a hidden bit of trickery in this line:

      btnCount = btnCount + 1 * OVERRIDE
    

    The BS1 does not use operator precedence; it evaluates left-to-right. This line will add one to btnCount and then multiply the updated amount by the state of the override input, which will be 0 or 1. If the button is not pressed, that line will always evaluate as 0. When the button is pressed, btnCount can increment, and when it reaches 10 (100ms of loop time), the routine will abort.

    By using the debounce code, you don't have to worry about electrical noise bouncing you out of your delay routine.

  • @JonnyMac said:
    I've done lots of little industrial projects with the BS1. Note that this kind of programming

      IF PIN1=1 THEN Routing1
    

    is dangerous for two reasons.

    1) Best practice is to used named symbols. I suggest you do this instead.

    OVERRIDE = PIN7
    

    2) Debouncing inputs can eliminate problems

    True story: A professional haunted house in NYC was about to open and on their walk-through things went berserk. Why? Because any time someone keyed a radio, prop swould act as if they'd been triggered. When they showed me their code, it was looking at trigger inputs the same as you're doing. The key was to debounce the triggers. That solved the problem.

    Here's routine that will let you delay up to 255 seconds and can be aborted by pressing a button (be sure to use a pull-down on that input) for 100ms. This may look a little scary at first, but I've deployed this code many times and it works well. Call with GOSUB Delay.

    ' put delay into dlySecs
    ' put 0 in btnCnt before calling
    
    Delay:
      IF dlySecs = 0 THEN Delay_Exit                ' done?
        FOR x = 1 TO 100                            ' delay 1s
          PAUSE 10
          btnCount = btnCount + 1 * OVERRIDE        ' check button
          IF btnCount = 10 THEN Delay_Exit          ' if held 100ms, abort
        NEXT
        dlySecs = dlySecs - 1
        GOTO Delay
    
    Delay_Exit:
      RETURN
    

    There is a hidden bit of trickery in this line:

      btnCount = btnCount + 1 * OVERRIDE
    

    The BS1 does not use operator precedence; it evaluates left-to-right. This line will add one to btnCount and then multiply the updated amount by the state of the override input, which will be 0 or 1. If the button is not pressed, that line will always evaluate as 0. When the button is pressed, btnCount can increment, and when it reaches 10 (100ms of loop time), the routine will abort.

    By using the debounce code, you don't have to worry about electrical noise bouncing you out of your delay routine.

    Jon, could you post that code with the declared variables on top of the code for me to understand what is what? I don’t think I will have any electrical noise but I will try your cose.
    Please.

    Thanks

Sign In or Register to comment.