one shot
Danny
Posts: 56
I've been searching the forums for a way have a switch or button ONLY trigger a routine once for each press of the button.
I have purchased several BS2's and NX-1000 and printed or purchased most of your manuals, I have found that I learn best by example, but
haven't found any examples of what I am trying to do, and you guys have sooooo much information available I'm getting yelled at by my
wife for reading in bed.
I'm working on an interface to a lighting control system, where motion detectors will trigger a serial string to the lighting controller.
The issue is that the motion detectors will provide a closure for as long as they are triggered, so I will be recieving a contact closure
lasting anywhere from 1 second to minutes, depending on how long someone is in the sensing range of the detectors.
I have the 232 strings set up and tested, but I am getting multiple sends, from one trigger.
I have tried two versions of a program for a BS2, but both behave in the same way, this is a device that I am planning to market if I can get the
multiple signal issue resolved (especially since the super carrier board is so inexpensive now!).
I'm attaching the two programs below, any help would be greatly appreciated!
[noparse][[/noparse]code]'{$STAMP BS2}
'{$PBASIC 2.5}
'Program description here
'This program is designed TO interface radio receivers TO
'a Crestron STCOM module
'Declare Variables Here
workvariable VAR Byte
delay VAR Byte
rate VAR Byte
downstate VAR Byte
workvariable = 0
delay = 0
rate = 255
downstate = 1
'Serial info here
TxD CON 16
baud CON 16468
pace CON 10
'Main program here
Reloop: BUTTON 0,downstate,delay,rate,workvariable,1,Next1
DEBUG "button 1",CR
SEROUT TxD, baud, pace,[noparse][[/noparse]"1", CR]
Next1: BUTTON 1,downstate,delay,rate,workvariable,1,Next2
DEBUG "button 2",CR
SEROUT TxD, baud, pace, [noparse][[/noparse]"2", CR]
Next2: BUTTON 2,downstate,delay,rate,workvariable,1,Next3
DEBUG "button 3",CR
SEROUT TxD, baud, pace, [noparse][[/noparse]"3", CR]
Next3: BUTTON 3,downstate,delay,rate,workvariable,1,Next4
DEBUG "button 4",CR
SEROUT TxD, baud, pace, [noparse][[/noparse]"4", CR]
Next4: BUTTON 4,downstate,delay,rate,workvariable,1,RePoll
DEBUG "button 5",CR
SEROUT TxD, baud, pace, [noparse][[/noparse]"5", CR]
RePoll: PAUSE 100
GOTO Reloop
Second version
' {$STAMP BS2}
' {$PBASIC 2.5}
'Program description here
'This program is designed TO interface radio receivers TO
'a Crestron STCOM module
'Declare Variables Here
'Serial info here
TxD CON 16
baud CON 16468
pace CON 10
'Main program here
MainLoop: IF IN0=1 THEN Next1
DEBUG "button 1",CR
SEROUT TxD, baud, pace,[noparse][[/noparse]"1", CR]
GOTO Next1
Next1: IF IN1=1 THEN Next2
DEBUG "button 2",CR
SEROUT TxD, baud, pace, [noparse][[/noparse]"2", CR]
GOTO Next2
Next2: IF IN2=1 THEN Next3
DEBUG "button 3",CR
SEROUT TxD, baud, pace, [noparse][[/noparse]"3", CR]
GOTO Next3
Next3: IF IN3=1 THEN Next4
DEBUG "button 4",CR
SEROUT TxD, baud, pace, [noparse][[/noparse]"4", CR]
GOTO Next4
Next4: IF IN4=1 THEN Repoll
DEBUG "button 5",CR
SEROUT TxD, baud, pace, [noparse][[/noparse]"5", CR]
GOTO Repoll
Repoll: PAUSE 100
GOTO MainLoop
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"Never create anything you can't control"
"The amount of intelligence on the planet is fixed... the population is growing"
I have purchased several BS2's and NX-1000 and printed or purchased most of your manuals, I have found that I learn best by example, but
haven't found any examples of what I am trying to do, and you guys have sooooo much information available I'm getting yelled at by my
wife for reading in bed.
I'm working on an interface to a lighting control system, where motion detectors will trigger a serial string to the lighting controller.
The issue is that the motion detectors will provide a closure for as long as they are triggered, so I will be recieving a contact closure
lasting anywhere from 1 second to minutes, depending on how long someone is in the sensing range of the detectors.
I have the 232 strings set up and tested, but I am getting multiple sends, from one trigger.
I have tried two versions of a program for a BS2, but both behave in the same way, this is a device that I am planning to market if I can get the
multiple signal issue resolved (especially since the super carrier board is so inexpensive now!).
I'm attaching the two programs below, any help would be greatly appreciated!
[noparse][[/noparse]code]'{$STAMP BS2}
'{$PBASIC 2.5}
'Program description here
'This program is designed TO interface radio receivers TO
'a Crestron STCOM module
'Declare Variables Here
workvariable VAR Byte
delay VAR Byte
rate VAR Byte
downstate VAR Byte
workvariable = 0
delay = 0
rate = 255
downstate = 1
'Serial info here
TxD CON 16
baud CON 16468
pace CON 10
'Main program here
Reloop: BUTTON 0,downstate,delay,rate,workvariable,1,Next1
DEBUG "button 1",CR
SEROUT TxD, baud, pace,[noparse][[/noparse]"1", CR]
Next1: BUTTON 1,downstate,delay,rate,workvariable,1,Next2
DEBUG "button 2",CR
SEROUT TxD, baud, pace, [noparse][[/noparse]"2", CR]
Next2: BUTTON 2,downstate,delay,rate,workvariable,1,Next3
DEBUG "button 3",CR
SEROUT TxD, baud, pace, [noparse][[/noparse]"3", CR]
Next3: BUTTON 3,downstate,delay,rate,workvariable,1,Next4
DEBUG "button 4",CR
SEROUT TxD, baud, pace, [noparse][[/noparse]"4", CR]
Next4: BUTTON 4,downstate,delay,rate,workvariable,1,RePoll
DEBUG "button 5",CR
SEROUT TxD, baud, pace, [noparse][[/noparse]"5", CR]
RePoll: PAUSE 100
GOTO Reloop
Second version
' {$STAMP BS2}
' {$PBASIC 2.5}
'Program description here
'This program is designed TO interface radio receivers TO
'a Crestron STCOM module
'Declare Variables Here
'Serial info here
TxD CON 16
baud CON 16468
pace CON 10
'Main program here
MainLoop: IF IN0=1 THEN Next1
DEBUG "button 1",CR
SEROUT TxD, baud, pace,[noparse][[/noparse]"1", CR]
GOTO Next1
Next1: IF IN1=1 THEN Next2
DEBUG "button 2",CR
SEROUT TxD, baud, pace, [noparse][[/noparse]"2", CR]
GOTO Next2
Next2: IF IN2=1 THEN Next3
DEBUG "button 3",CR
SEROUT TxD, baud, pace, [noparse][[/noparse]"3", CR]
GOTO Next3
Next3: IF IN3=1 THEN Next4
DEBUG "button 4",CR
SEROUT TxD, baud, pace, [noparse][[/noparse]"4", CR]
GOTO Next4
Next4: IF IN4=1 THEN Repoll
DEBUG "button 5",CR
SEROUT TxD, baud, pace, [noparse][[/noparse]"5", CR]
GOTO Repoll
Repoll: PAUSE 100
GOTO MainLoop
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"Never create anything you can't control"
"The amount of intelligence on the planet is fixed... the population is growing"
Comments
Get_Buttons:
· btns = %00011111
· FOR idx = 1 TO·10
··· btns = btns & INL
··· PAUSE·5
· NEXT
· RETURN
This routine debounces the button inputs for about 50 ms, scanning 10 times·during the process to make sure that a button was not released and pressed again (contact bounce).· The advantage of using a subroutine like this is that all buttons are scanned at the same time, and the value is held (in the variable btns) until you call the subroutine again.
On your question about doing something just once on·the press of a button,·on way to handle this is:
··GOSUB·Get_Buttons
· IF (btns.BIT0 = 1) THEN
····' do something
····DO
····· GOSUB Get_Buttons
··· LOOP UNTIL (btns.BIT0 = 0)
··ENDIF
If you want to do this kind of thing for multiple simultaneous events, then you'll need a different strategy: you'll have to have a set of flags that keeps track of the state of all the buttons such that a process is blocked until that button has been released then repressed.
·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Dallas, TX· USA
Post Edited (Jon Williams) : 5/20/2005 6:56:42 PM GMT
·· The GOTO in each section to the next section is not needed.· The routine you are going to is right below it, so the program will go there anyway.· The extra GOTOs will simply take up extra memory and add a small delay (loading time) to the loop.··
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Tech Support
csavage@parallax.com
Main:
· DO
····GOSUB Get_Buttons···················· ' scan buttons
··· FOR chan = 0 TO 4···················· ' loop through all channels
····· IF (timer(chan) = 0) THEN···········' check channel timer
······· IF (btns.LOWBIT(chan) = 1) THEN·· ' input active?
········· GOSUB Send_Msg··················' -- send message for this channel·
········· timer(chan) = 600·············· ' -- reload timer with one minute
······· ENDIF
····· ELSE
······· timer(chan) = timer(chan) - 1···· ' update·running timer
····· ENDIF
··· NEXT
··· PAUSE 100···························· ' loop pad (0.1 sec)
· LOOP
· END
The Send_Msg subroutine would use the variable chan to send the appropriate message.· This example uses the same timer value for all channels, but you could update it by embedding default timer values into a DATA statement.· To keep it easy, enter the timing in seconds (1 to 255) and change...
······· timer(chan) = 600·············· ' -- reload timer with one minute
to...
········READ DfltTime + chan, timer(chan) ' read default seconds
······· timer(chan) = timer(chan)·* 10····' convert to tenths
Of course, you'd need to add this to your program as well:
DfltTime··· DATA··· 60, 60, 90, 30, 60
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Dallas, TX· USA
Post Edited (Jon Williams) : 5/20/2005 7:02:13 PM GMT
I'll be trying all of these to see how they work and to apply them to my project.
BTW, I'll be watching 16 motion detectors with each of these units, so being able to use the onboard serial port for communications is a serious bonus!!
Thanx Again!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"Never create anything you can't control"
"The amount of intelligence on the planet is fixed... the population is growing"
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Dallas, TX· USA
THanx again for the help and have a great weekend!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"Never create anything you can't control"
"The amount of intelligence on the planet is fixed... the population is growing"
I highly recommend using a "state machine" written in PBASIC for this kind of thing. You want to detect and take action when a key changes state from 1 to 0, only at the transition. The secret is to harness logic operators, AND (& in Stampese) and XOR (^ in stampese.) Those operators compare the present state of a key with its prior state. Consider the following logic statement, where all the variables are bits:
The message prints out only when you press the key, and you have to release it before it can print again. The XOR operator detects the change between past and present state. The AND operator imposes the condition that the past state was 1.
The beauty of this comes when you need to scan lots of keys, because you can do them all in parallel with exactly the same number of lines of code. See, here is the same code scanning all 16 keys at once:
In your application, you'd let bits in the xKey variable trigger the messages to your lighting controller. It can easily handle the condition where two or more keys happen to activate at once.
I have other tutorials on State machines at this URL
www.emesystems.com/BS2fsm.htm
I agree with Jon, the BUTTON command is not too useful for things like this.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
In experimenting I came upon the following after reading the industrial controls manual.
It seems to work perfectly, I'm planning on extending it to all 16 inputs, with all but the last module pointing to the one after it so the
stamp will poll all 16 inputs.
Do you forsee any issues with this program??
' {$STAMP BS2}
' {$PBASIC 2.5}
'Program description here
'Declare I/O Here
INPUT 0
INPUT 1
INPUT 2
INPUT 3
INPUT 4
INPUT 5
'Declare Variables Here
PB1 VAR IN0
PB2 VAR IN1
PB3 VAR IN2
PB4 VAR IN3
PB5 VAR IN4
Flag1 VAR Bit
Flag2 VAR Bit
Flag3 VAR Bit
Flag4 VAR Bit
Flag5 VAR Bit
'Declare Constants Here
'Set Serial port info here
'Main program here
Flag1 = 0
Flag2 = 0
Start:
'DEBUG "I'm Alive", CR
PAUSE 10
Check1: IF PB1 = 0 THEN Do1
Flag1 = 0
GOTO Start
Do1: IF Flag1 = 1 THEN Start
'Put task here
DEBUG "Button Pressed", CR
TOGGLE 10
Flag1 = 1
GOTO Start
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"Never create anything you can't control"
"The amount of intelligence on the planet is fixed... the population is growing"
All BASIC Stamp pins are made inputs on reset, so you don't need to declare them as you're doing at the top of your program -- this just consumes space. And in your program you're using TOGGLE but the state of the pin was not preset on start-up; this can lead to unexpected results (see TOGGLE in the manual or help file for an explanation). Let me suggest you use the OUTS and DIRS variables to preset everything before your operational code gets started. The NCD operator will also be helpful in your application; use it with BRANCH to streamline multipe inputs/code segments.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
For some reason I tought OUTS and DIRS only applied to the BS1.
Will have to read up on NCD and BRANCH, more time reading in bed and less sleep for me!!!
Thanx!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"Never create anything you can't control"
"The amount of intelligence on the planet is fixed... the population is growing"