spin command equivalent to sleep ?
mikea
Posts: 283
i have a program i would like to conditionally put itself to sleep while waiting for an rfid tag "swipe" . i found "abort, return" that might posibbly work. seems like there was other ways to put prop to a low power state waiting for an i/o input to wake it up. im using multiple cogs so even if there has to be one active cog to watch for the input it might help to put the others asleep.havent yet found other options reading prop manual.are there other options?- mike
Comments
WAITPNE -- Wait Pin Not Equal
waitcnt(cnt)
This will do. The WAITCNT takes a few microseconds to execute. By then, the time CNT is well past and the WAITCNT will wait for just under 2^32 clock cycles before waking up again.
code: [ _clkmode = xtal1 + pll16x 'Standard clock mode * crystal frequency = 80 MHz
_xinfreq = 5_000_000
baud=19_200
TX_pin = 0
obj
LCD : "FullDuplexSerial.spin"
var long stack[50]
long stack1[50]
long stack2[50]
pub go
cognew(sleep,@stack2)
pub main
cognew(lcd1,@stack)
cognew(restart,@stack1)
repeat
'
dira[9]~~
dira[8]~~
dira[28]~
if ina[28]==1
repeat
outa[8]~
!outa[9]
waitcnt(clkfreq/4+cnt)
else
outa[8]~~
Pub lcd1
LCD.start(TX_PIN, TX_PIN, %1000, 19_200)
waitcnt(clkfreq / 100 + cnt) ' Pause for FullDuplexSerial.spin to initialize
LCD.tx(22) 'set diplay no cursor, no blink
LCD.tx(17) 'turn on back light
dira[28]:=0
repeat
if ina[28]==1
repeat 3
' LCD.tx(212) 'tone length
'LCD.tx(221)
' LCD.tx(220) 'note
repeat
LCD.tx(12) 'clear screen
LCD.str(string("motion detected by girls room ")) 'display messageo
waitcnt(clkfreq/2+cnt) 'slow down so screen doesnt pulse
else
LCD.tx(12) 'clear screen
LCD.str(string("house is secure.")) 'display message
waitcnt(clkfreq/2+cnt) 'slow down
pub restart
dira[2]~
repeat
if ina[2]==0
waitcnt(clkfreq+cnt) 'ina[2] is a pushputton simulating system reset/arm ...future rfid replaces pushbutton
reboot
pub sleep
dira[1]~
waitpeq(%00000 , |<5 ,0)
main
]
Waitcnt(cnt) This waits for a certain amount of time, example: waitcnt(clkfreq/X+cnt). X is the devision of seconds - so if x was "2" then it would wait 500ms, because 500 is half (1/2) of 1000ms (1 second). Or waitcnt(clkfreq*X+cnt). Where it would wait the number of seconds defined by "X". So if "X" was 3, then it would wait 3 seconds.
Although that might not be what you want, its a tiny snippet about waiting in SPIN.
-John
The bootloader transfers control (calls) to the first method in the program, "go" in your case. The first thing that does is to start another cog with a call to "sleep", then it stops itself because "go" exits which does a COGSTOP. Similarly the IF in "sleep" probably doesn't succeed the first time it's executed, so "sleep" ends up exiting without doing the WAITPEQ or call to "main" and that does a COGSTOP.
It looks like you need to understand what's going on before you unnecessarily complicate your program. Don't worry about power consumption. If you want to understand how cogs work and how WAITxxx statements work, use a simple test program, as simple as possible. Make sure you understand it at each step. You can experiment with the WAITxxx stuff without starting any new cog and you can experiment with multiple cogs without using the WAITxxx statements. I'd recommend the Propeller Education Kit labs for an introduction.
The last parameter of the WAITPxx statements specifies whether the I/O pins are in the first bank of I/O pins (0-31) or the second bank of I/O pins (32-63) which don't exist in the current Propeller. It's ignored in the current Propeller.
If the baud rate isn't too high (it probably isn't for a RFID reader) you can use something like Simple_Serial written in Spin to wait for the start bit of the first character via WAITPEQ, then clock in the message and act on it before going back to sleep. One cog, nearly all of its time spent sleeping, overall power consumption under a milliamp.
The BASIC Stamp SLEEP command takes the current down to less than 50 µA, that is, assuming an efficient voltage regulator. To achieve that level or better on the Prop, the main trick is to drop the clock frequency down to its RCslow setting of 20kHz, where it can still watch for transitions on inputs pins and then wake up to the higher frequency when need be. It is not hard to do that. The program can leave the fullDuplexSerial cog running, because at 20kHz each cog adds only about 4 µA to the operating current. The total operating current with a good low Iq regulator can be around 20µA. When waking up, there has to be a delay of about 10ms to let the crystal come up to speed, and after that (but NOT during sleep) fullDuplexSerial will be ready to send and receive. The waitxxx commands by themselves can get down to the milliamp floor, but it takes the change to RCslow to really get down to the basement. Here is a little demo program of how to change the clock frequency in response to a transition on WAKE_PIN, although I set up this program to sleep for 2 seconds.