BS1 One minute timer with a button — Parallax Forums

# BS1 One minute timer with a button

Posts: 156

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!

• Posts: 23,065

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.

• Posts: 156
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!

• Posts: 7,913
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.

• Posts: 156

@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.