How do I delay?
Danny
Posts: 56
Working on a project, as usual.
Have a tester, part of my previous posting, have found code for state machines and implemented with no problems.
Issue is how to delay sending a "heartbeat" to let me know system is alive without missing an input trigger or release.
looking for a heartbeat about once a second with continued polling of state of inputs.
If I put a pause in the heartbeat section I miss short (<1sec triggers).
Any slick sample code or hints out there????
[noparse][[/noparse]code]'{$STAMP BS2}
'Set Serial port info here
TxD CON 16
baud CON 813
pace CON 10
Cycle VAR Nib
' contact inputs To P0 To P8
x0 VAR Byte ' old state of inputs
x1 VAR Byte ' new state of inputs
xx VAR Byte ' transition state of inputs
xy VAR Byte ' transition state 0->1
x0=INL ' read states at start
waiting:
x1=INL ' read new state
xx=x1 ^ x0 ' see if there are any transitions
xy = xx & x1 ' distinguish 0->1 xitions from 1->0
x0=x1 ' update old state
Heartbeat:
SEROUT TxD, baud, pace,[noparse][[/noparse]"H", CR]' do something
GOTO checkallinputs
checkallinputs:
FOR Cycle=1 TO 65535
BRANCH NCD xx,[noparse][[/noparse]waiting,INPUT1,INPUT2,INPUT3,INPUT4,INPUT5,INPUT6,INPUT7,INPUT8]
INPUT1:
xx=xx & %11111110 ' knock down the 1st input bit
BRANCH xy.BIT0,[noparse][[/noparse]input1opened,input1closed]
input1opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"1T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input1closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"1C", CR]' do something
GOTO checkallinputs
INPUT2:
xx=xx & %11111101 ' knock down the 2nd input bit
BRANCH xy.BIT1,[noparse][[/noparse]input2opened,input2closed]
input2opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"2T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input2closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"2C", CR]' do something
GOTO checkallinputs
INPUT3:
xx=xx & %11111011 ' knock down the 3rd input bit
BRANCH xy.BIT2,[noparse][[/noparse]input3opened,input3closed]
input3opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"3T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input3closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"3C", CR]' do something
GOTO checkallinputs
INPUT4:
xx=xx & %11110111 ' knock down the 4th input bit
BRANCH xy.BIT3,[noparse][[/noparse]input4opened,input4closed]
input4opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"4T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input4closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"4C", CR]' do something
GOTO checkallinputs
INPUT5:
xx=xx & %11101111 ' knock down the 5th input bit
BRANCH xy.BIT4,[noparse][[/noparse]input5opened,input5closed]
input5opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"5T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input5closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"5C", CR]' do something
GOTO checkallinputs
INPUT6:
xx=xx & %11011111 ' knock down the 6th input bit
BRANCH xy.BIT5,[noparse][[/noparse]input6opened,input6closed]
input6opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"6T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input6closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"6C", CR]' do something
GOTO checkallinputs
INPUT7:
xx=xx & %10111111 ' knock down the 7th input bit
BRANCH xy.BIT6,[noparse][[/noparse]input7opened,input7closed]
input7opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"7T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input7closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"7C", CR]' do something
GOTO checkallinputs
INPUT8:
xx=xx & %01111111 ' knock down the 8th input bit
BRANCH xy.BIT7,[noparse][[/noparse]input8opened,input8closed]
input8opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"8T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input8closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"8C", CR]' do something
GOTO checkallinputs
NEXT
GOTO Heartbeat
P.S. also looking for samples of parsing the H, 1T, 1C, at the other end of the serial ink.
Found some examples, but having "issues" implementing.
Thanx in advance!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"Never create anything you can't control"
"The amount of intelligence on the planet is fixed... the population is growing"
Have a tester, part of my previous posting, have found code for state machines and implemented with no problems.
Issue is how to delay sending a "heartbeat" to let me know system is alive without missing an input trigger or release.
looking for a heartbeat about once a second with continued polling of state of inputs.
If I put a pause in the heartbeat section I miss short (<1sec triggers).
Any slick sample code or hints out there????
[noparse][[/noparse]code]'{$STAMP BS2}
'Set Serial port info here
TxD CON 16
baud CON 813
pace CON 10
Cycle VAR Nib
' contact inputs To P0 To P8
x0 VAR Byte ' old state of inputs
x1 VAR Byte ' new state of inputs
xx VAR Byte ' transition state of inputs
xy VAR Byte ' transition state 0->1
x0=INL ' read states at start
waiting:
x1=INL ' read new state
xx=x1 ^ x0 ' see if there are any transitions
xy = xx & x1 ' distinguish 0->1 xitions from 1->0
x0=x1 ' update old state
Heartbeat:
SEROUT TxD, baud, pace,[noparse][[/noparse]"H", CR]' do something
GOTO checkallinputs
checkallinputs:
FOR Cycle=1 TO 65535
BRANCH NCD xx,[noparse][[/noparse]waiting,INPUT1,INPUT2,INPUT3,INPUT4,INPUT5,INPUT6,INPUT7,INPUT8]
INPUT1:
xx=xx & %11111110 ' knock down the 1st input bit
BRANCH xy.BIT0,[noparse][[/noparse]input1opened,input1closed]
input1opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"1T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input1closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"1C", CR]' do something
GOTO checkallinputs
INPUT2:
xx=xx & %11111101 ' knock down the 2nd input bit
BRANCH xy.BIT1,[noparse][[/noparse]input2opened,input2closed]
input2opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"2T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input2closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"2C", CR]' do something
GOTO checkallinputs
INPUT3:
xx=xx & %11111011 ' knock down the 3rd input bit
BRANCH xy.BIT2,[noparse][[/noparse]input3opened,input3closed]
input3opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"3T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input3closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"3C", CR]' do something
GOTO checkallinputs
INPUT4:
xx=xx & %11110111 ' knock down the 4th input bit
BRANCH xy.BIT3,[noparse][[/noparse]input4opened,input4closed]
input4opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"4T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input4closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"4C", CR]' do something
GOTO checkallinputs
INPUT5:
xx=xx & %11101111 ' knock down the 5th input bit
BRANCH xy.BIT4,[noparse][[/noparse]input5opened,input5closed]
input5opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"5T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input5closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"5C", CR]' do something
GOTO checkallinputs
INPUT6:
xx=xx & %11011111 ' knock down the 6th input bit
BRANCH xy.BIT5,[noparse][[/noparse]input6opened,input6closed]
input6opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"6T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input6closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"6C", CR]' do something
GOTO checkallinputs
INPUT7:
xx=xx & %10111111 ' knock down the 7th input bit
BRANCH xy.BIT6,[noparse][[/noparse]input7opened,input7closed]
input7opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"7T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input7closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"7C", CR]' do something
GOTO checkallinputs
INPUT8:
xx=xx & %01111111 ' knock down the 8th input bit
BRANCH xy.BIT7,[noparse][[/noparse]input8opened,input8closed]
input8opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"8T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input8closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"8C", CR]' do something
GOTO checkallinputs
NEXT
GOTO Heartbeat
P.S. also looking for samples of parsing the H, 1T, 1C, at the other end of the serial ink.
Found some examples, but having "issues" implementing.
Thanx in advance!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"Never create anything you can't control"
"The amount of intelligence on the planet is fixed... the population is growing"
Comments
If necessary, it may be possible to stretch the trigger pulses (with an RC circuit).
I don't understand the purpose of the FOR-NEXT loop in the listing. The program will never reach NEXT.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
Scan_Inputs:
· newBtns = INL································ ' scan buttons
· chgBtns = newBtns ^ oldBtns·················· ' look for changes
· is1Btns = chgBtns & newBtns·················· ' mark 0->1 inputs
· oldBtns = newBtns···························· ' save current scan
Heartbeat:
· IF (timer = 0) THEN·························· ' timer expired?
··· SEROUT TxD, Baud, Pace, [noparse][[/noparse]"H", CR]·········· '· yes, send "H"
· ENDIF
· timer = timer + 1 // 250····················· ' update timer
· PAUSE 4
Process_Inputs:
· DO WHILE (chgBtns > %00000000)
··· tag = (NCD chgBtns) - 1···················· ' get active input
··· chgBtns.LOWBIT(tag) = 0···················· ' mark processed
··· status = "T" - (is1Btns.LOWBIT(tag) * 17)
··· SEROUT TxD, Baud, Pace, [noparse][[/noparse]("1" + tag), status, CR]
· LOOP
· GOTO Scan_Inputs
I'm sure it's obvious that the heartbeat timer is not going to be exactly one second --·sending the heartbeat message and processing inputs will add a little extra time.· I think, though, this does what you want.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Post Edited (Jon Williams (Parallax)) : 9/20/2005 1:54:51 PM GMT
I've tried to upload and test this and it won't work, or compile for that matter.
I understand giving me "hints" as opposed to doing the work for me, but I just don't get how you are reading inputs and sending data.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"Never create anything you can't control"
"The amount of intelligence on the planet is fixed... the population is growing"
You will probably need to add the following statement at the very beginning of your program:
' {$PBASIC 2.5}
Regards,
Bruce Bates
'{$STAMP BS2}
'Set Serial port info here
TxD CON 16
baud CON 813
pace CON 10
Cycle VAR Nib
Timer VAR Word
' contact inputs To P0 To P8
x0 VAR Byte ' old state of inputs
x1 VAR Byte ' new state of inputs
xx VAR Byte ' transition state of inputs
xy VAR Byte ' transition state 0->1
x0=INL ' read states at start
waiting:
x1=INL ' read new state
xx=x1 ^ x0 ' see if there are any transitions
xy = xx & x1 ' distinguish 0->1 xitions from 1->0
x0=x1 ' update old state
Heartbeat:
IF (timer = 500) THEN Sendheartbeat ' timer expired?
timer = timer + 1
ENDIF
GOTO checkallinputs
Sendheartbeat:
SEROUT TxD, baud, pace,[noparse][[/noparse]"H", CR]' do something
Timer = 0
checkallinputs:
BRANCH NCD xx,[noparse][[/noparse]waiting,INPUT1,INPUT2,INPUT3,INPUT4,INPUT5,INPUT6,INPUT7,INPUT8]
INPUT1:
xx=xx & %11111110 ' knock down the 1st input bit
BRANCH xy.BIT0,[noparse][[/noparse]input1opened,input1closed]
input1opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"1T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input1closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"1C", CR]' do something
GOTO checkallinputs
INPUT2:
xx=xx & %11111101 ' knock down the 2nd input bit
BRANCH xy.BIT1,[noparse][[/noparse]input2opened,input2closed]
input2opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"2T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input2closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"2C", CR]' do something
GOTO checkallinputs
INPUT3:
xx=xx & %11111011 ' knock down the 3rd input bit
BRANCH xy.BIT2,[noparse][[/noparse]input3opened,input3closed]
input3opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"3T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input3closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"3C", CR]' do something
GOTO checkallinputs
INPUT4:
xx=xx & %11110111 ' knock down the 4th input bit
BRANCH xy.BIT3,[noparse][[/noparse]input4opened,input4closed]
input4opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"4T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input4closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"4C", CR]' do something
GOTO checkallinputs
INPUT5:
xx=xx & %11101111 ' knock down the 5th input bit
BRANCH xy.BIT4,[noparse][[/noparse]input5opened,input5closed]
input5opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"5T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input5closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"5C", CR]' do something
GOTO checkallinputs
INPUT6:
xx=xx & %11011111 ' knock down the 6th input bit
BRANCH xy.BIT5,[noparse][[/noparse]input6opened,input6closed]
input6opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"6T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input6closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"6C", CR]' do something
GOTO checkallinputs
INPUT7:
xx=xx & %10111111 ' knock down the 7th input bit
BRANCH xy.BIT6,[noparse][[/noparse]input7opened,input7closed]
input7opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"7T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input7closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"7C", CR]' do something
GOTO checkallinputs
INPUT8:
xx=xx & %01111111 ' knock down the 8th input bit
BRANCH xy.BIT7,[noparse][[/noparse]input8opened,input8closed]
input8opened:
SEROUT TxD, baud, pace,[noparse][[/noparse]"8T", CR]' do something
GOTO checkallinputs ' back to test other inputs
input8closed:
SEROUT TxD, baud, pace,[noparse][[/noparse]"8C", CR]' do something
GOTO Heartbeat
Now to work on parsing the serial string at the other end making things happen!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"Never create anything you can't control"
"The amount of intelligence on the planet is fixed... the population is growing"
Here are the details on the tricky bits:
··· idx = (NCD chgdIns) - 1
NCD normally returns a value of 1 to 8 (for a byte) to point to the highest set bit.· I subtract one to use it as a bit index, so idx will hold 0 to 7, depending on the input (IN0 - IN7) that's being processed.
··· chgdIns.LOWBIT(idx) = 0
This clears the bit that is being processed.· LOWBIT is an array of bits for the variable it's attached to.
··· status = "T" - (to1Ins.LOWBIT(idx) * 17)
This is the same as:
··· IF (to1Ins.LOWBIT(idx) = 0) THEN
····· status = "T"
··· ELSE
······status = "C"
····ENDIF
... it's just a slimmer approach.· This works because "T" - 17 = "C".
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Goes with being a jack of all trades and master of none. Thanks for attaching your program, now I can actually step through it a line at a time and figure it out!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"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
http://groups.yahoo.com/group/basicstamps/message/9070
http://groups.yahoo.com/group/basicstamps/message/9109
There, the implication was that very different types of actions might have to be taken in response to each trigger, thus, the redundant code present there is a framework to hold the different ad hoc or brute force actions. The code is also posted at
http://emesystems.com/BS2fsm.htm#doors
The program came before PBASIC 2.5 and before DO-WHILE-LOOP syntax. Anyway, at the time I was pleased with the zippy BRANCH on NCD construct that reiterates on itself to loop and also to process trigger events that might occasionally be simultaneous.
Jon's compact version and PBASIC style improvements are possible thanks to PBASIC 2.5 syntax and also due to the regular pattern here in the actions to be taken in response to each trigger. The action is simply to send the letter and the trigger number via a SEROUT. Jon, I have mixed feelings about fancy variable names. I guess I think of xx and xy are descriptive mnemonics and would probably be using Greek letters if I could! To my mind, doing so, keeping the variable names abstract, makes the structure of the logic stand out and makes it more portable to different situations. But I do agree, the comments have to get into the code to document it somehow or other.
It looks to me like the added timer should work just fine, so long as the trigger inputs do not come too fast and furious. If need be, Danny, you could alternatively use an external RC or precision timer on a Stamp pin to enforce the one second heartbeat. For example, attach a 1.5 Mohm resistor in parallel with a 1uf capacitor from additional trigger pin p8 to ground. At the top of the loop, charge up that capacitor to +5 volts with HIGH 8, then make the pin an INPUT 8. The capacitor will discharge through the resistor with a time constant of about one second, and pin p8 can be detected going from high to low at that time. That detection could be accomplished within the framework of the trigger scanning that you have, and treated just like the other triggers. Once detected, refresh the high level for the next go round.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Another question for you Jon, and anyone else interested.
Obviously I have a transmitter and receiver set up here, I can transmit the input and trigger or clear message with no problem.
On SERIN, I am trying to match the string coming from the transmit side and do actions.
I am receiving the 1T, 1C, etc. and H meassages, and putting them in a variable word for evaluation.
Since I know exactly what I am sending, and this is a closed system, there is no problem with having to add checksums or error correction.
When I do a match using IF INVAR="1T" THEN dothis, I get an error message highlighting the T expecting a variable.
I went back to the transmit program and changed to 1 letter/number signals and the error went away and I have both sides working now (thanks again).
But, I program several types of control systems and they have very simple serial string matching, where I can list a string and the system will provide a digital output on a match and do nothing on a miss. It will match any ascii string I can throw at it. I don't expect a stamp to do this, but is there a way to macth a short mixed string easily?
I really have to see about visiting you guys when i get out to SFO again, I drive past you at least once a month, but I figure you won't sell me anymore product if I do that!
Thanx, Danny
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"Never create anything you can't control"
"The amount of intelligence on the planet is fixed... the population is growing"
Main:
· SERIN RxD, Baud, [noparse][[/noparse]chan, status]
· IF (chan = "H") THEN
··· ' process heartbeat
··ELSE
·· ·chan = chan - "0"····················· ' convert ASCII to digit
·· ·IF (status = "T") THEN
·· ·· ' do something for "chan"·for "T"
·· ·ELSE
·· ·· ' do something for "chan" for "C"
·· ·ENDIF
· ENDIF
· GOTO·Main
What you have to keep in mind is that SERIN and SEROUT only work with bytes, and the BASIC Stamp doesn't support strings the way you were attempting to·do in your·code.· The example above expects two bytes; if the first is an "H" then we have a heartbeat·output and you can reset a watchdog or whatever else you need to do with the heartbeat.
If not "H" then chan will hold the channel number as an ASCII character·so a bit of math is used to extract that.· Finally, you look at the·status character·and do the appropriate processing.
·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
In any case, a header byte can help keep things in sync. Preface every pair of bytes with a single character that is always the same and does not otherwise appear in the message. Say letter "A". Then on the receiving end use a WAIT modifier, [noparse][[/noparse]WAIT ("A"),chan,status].
In this setup, it doesn't seem that you really need two bytes. The message could be contained in the two nibbles of one byte. $1C to $8C, $1B to $8B, and $AA for heartbeat.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com