Changing frequency of blinking LED with button
akuaku
Posts: 11
Hi, I'm having a bit of difficulty programming with my BS2 stamp.
I'm trying to get a light to blink in one-second intervals when the button is pushed and held - then blink in 50-millisecond intervals the next time the button is pushed and held.
I've been trying to use subroutines to get this to work, but they seem to overlap each other (i.e. when I press the button once there is a 50-millisecond blink followed by a one-second blink).
I've copied what I have on my stamp editor below.
Does anyone have any suggestions?
Thanks
DO
DEBUG ? IN3
GOSUB blink_at_50
GOSUB blink_at_1000
LOOP
blink_at_50:
IF (IN3 = 1 ) THEN
HIGH 15
PAUSE 50
LOW 15
PAUSE 50
ELSE
PAUSE 100
ENDIF
RETURN
blink_at_1000:
IF (IN3 = 1 ) THEN
HIGH 15
PAUSE 1000
LOW 15
PAUSE 1000
ELSE
PAUSE 100
ENDIF
RETURN
I'm trying to get a light to blink in one-second intervals when the button is pushed and held - then blink in 50-millisecond intervals the next time the button is pushed and held.
I've been trying to use subroutines to get this to work, but they seem to overlap each other (i.e. when I press the button once there is a 50-millisecond blink followed by a one-second blink).
I've copied what I have on my stamp editor below.
Does anyone have any suggestions?
Thanks
DO
DEBUG ? IN3
GOSUB blink_at_50
GOSUB blink_at_1000
LOOP
blink_at_50:
IF (IN3 = 1 ) THEN
HIGH 15
PAUSE 50
LOW 15
PAUSE 50
ELSE
PAUSE 100
ENDIF
RETURN
blink_at_1000:
IF (IN3 = 1 ) THEN
HIGH 15
PAUSE 1000
LOW 15
PAUSE 1000
ELSE
PAUSE 100
ENDIF
RETURN
Comments
blink_at_50:
IF IN3=0 THEN blink_at_1000' not pushed, skip ahead
HIGH 15
PAUSE 50
LOW 15
PAUSE 50
goto blink_at_50
blink_at_1000:
IF IN3=0 THEN blink_at_50' not pressed, skip back
HIGH 15
PAUSE 1000
LOW 15
PAUSE 1000
goto blink_at_1000
IN3 = 0 pressed (pulled low )
'
This asumes a 10k pull-up resister on the input PIN 3 and a 220 ohm resister pulling the input low through the button.
'
'
Main:
'
IF IN3 = 0 THEN
HIGH 15
PAUSE 50
LOW 15
ELSE
HIGH 15
PAUSE 1000
LOW 15
ENDIF
GOTO Main
For example i will push the button and it will blink at 50 then I'll push it again and it will go at 1000 then i'll push it a third time and it will blink at 1000 again instead of returning to 50.
WMc. Yes that is the setup that I am currently using. A second pause is needed I think after the low too, but that's another interesting approach.
Thanks
Here is some button debounce code I use. It's set up for four buttons. JohnnyMac is the originator.
I think it was from one of the N&V columns, but I'm not sure which one.
akuaku: please confirm that you have the pullup resistor configuration suggested by WMc.
.
It's just an example of how to debounce buttons. It's possible that contact bounce in your switch is causing some of your problems.
If you connect your buttons to pins 0,1,2,3 (INA) and just run the code by itself you will see what it does. Less buttons will work. Oh, and the code is set up for buttons wired as active low (they connect the pin to ground when pressed).
Here is an example of two different ways to run a subroutine based on which button is pressed. Changing your blink rate could be in the subroutines. One is run from an If Then, the other from a Select Case.
Again, you can just run the code as is with nothing but the buttons hooked up to see how it works.
I was thinking... would this be easier to program with a Potentiometer (having it blink more frequently when turning the dial one way, and less frequent the other?). This could also work for what I am trying to do.
So what I did was put the blinking in two different loops, one slow and one fast, and I used TOGGLE instead of PAUSE. This lets the Stamp be checking the buttons constantly while the LED just sits there either on or off. It pretty much switches instantly from fast to slow and back again when you press the button.
I kept the debounce code, but only used one button (it can do up to 4 as is), you could probably just use the PBasic BUTTON command instead of the "Get_Buttons" subroutine, but I didn't have time to mess with that. Remember that the way this program is coded, the button needs to be active low and on pin 0, the LED needs to be on pin 15. You could change that of course.
BUT he never clarified that. akuaku? Pot or switch can be made to work, as you like.
For demo purposes this code is okay, but there's probably more efficient ways to do this, especially if you wanted to expand to more than two blinking rates. It's still early in the morning and I didn't want to stress my brain that hard just yet
I don't really program Stamps very much, so I'm not that good at it and it takes me a while to figure out how to do stuff, but I definitely learned a bit from this (i.e do not type gosub when you mean goto).
Here is the push and hold code.
I'm curious about using the potentiometer now though, so I'm going to post another topic about it.
Thanks for your help guys -
Still, if anyone knows a simple way of using the button to do this please continue to post.
You need two resistors and a normally open button wired as "active low" as in $WMc%'s diagram.
Here is a variation that is more responsive, in the sense that the latency is reduced to 50 ms.
IF dur=1 THEN dur=20 ELSE dur=1 ' in units of 50ms
Replace that with in-line code, or with a subroutine, that selects the different durations in the sequence you want. Possible hint, create an index variable or even a random variable that steps from 0 up to however many you want, and use that with the LOOKUP command to kick back the durations.