WAITPEQ with a time limit?
doggiedoc
Posts: 2,250
I am trying to figure out how to control a process with a switch and WAITPEQ is the obvious solution. I need a failsafe approach such as a time limit that the routine will wait but at the moment I'm at a loss as to how to structure it. Any chance this is possible?
Here's the method so far (no failsafe yet.)
Here's the method so far (no failsafe yet.)
PUB OpenDoor
OUTA [RELAY_PIN] := ON
pause(250)
HB25.SetMotorS(1840,1500)
'pause(2910)
waitpeq(%1,|<UPPER_SWTCH_PIN,0)
HB25.SetMotorS(1500,1500)
pause(250)
doorState := OPEN
OUTA [RELAY_PIN] := OFF

Comments
You are going to have to pole that by reading INA and testing for the pins state, and reading CNT and testing for the time limit, in a repeat loop. Which ever one happens first sets some status and gets you out of the loop.
Provided that is fast enough for your application the only downside is that WAITxxx consumes a lot less power whist it is waiting than a polling loop.
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 VAR long stack[1000] byte flag long timercog Pub init dira[0] := 0 dira[14] := 1 switchcheck Pub switchcheck cognew(timer,@stack[200]) 'start timer flag := 0 repeat if ina[0] := 1 'if switch is on, turn on relay outa[14] := 1 timerReset 'reset the timer if ina[0] := 0 'if switch is off turn off relay outa[14] := 0 timerReset 'reset timer if flag == 1 'if timer has timed out turn off relay outa[14] := 0 Pub timer timercog := cogid 'if timer is allowed to run out, set flag to 1 flag := 0 repeat 60 waitcnt(clkfreq*10+cnt) flag := 1 pub timerReset cogstop(timercog) cognew(timer,@stack[200]) 'restart the timerV.What about this:
PUB OpenDoor OUTA [RELAY_PIN] := ON pause(250) HB25.SetMotorS(1840,1500) 'turns on motor for door repeat 400 pause(10) if UPPER_SWTCH_PIN == 1 'tests for switch engagement by door HB25.SetMotorS(1500,1500) 'and turns off if so doorState := OPEN OUTA [RELAY_PIN] := OFF abort 'exits method HB25.SetMotorS(1500,1500) 'otherwise times out after about 4 seconds doorState := OPEN OUTA [RELAY_PIN] := OFFThe loop has a finite delay of about 4 seconds built in and checks pin state each pass, if high turns off motor and relay, sets the doorState parameter and aborts the method.
Think that will work? I can't test it from here.
Yes indeed. As you say it uses up a pin. And a counter. That might be quite acceptable in many cases.
Another way would be to start a COG with the code that waits on pins. Then after a time out kill the COG. Seriously wasteful of hardware resources.
And we thought interrupts were bad.
cheers,
rich
What we want to write in a high level language in this case is something like:
wait pins = someState: // Do whatever we should do // when that happens time = someTime: // Do whatever we should so // if it does not happen in timeNo interrupts there. (Yes interrupts may be there under the hood but not necessarily)
One could even throw other events in there that might need waiting on, like messages from other COGS for example.
That's before we start talking about the multi tasking that we are told we need interrupts for.
In that case what we would like to write is something like:
par someProcess someOtherProcessHere's the method:
PUB OpenDoor OUTA [RELAY_PIN] := ON pause(500) HB25.SetMotorS(1840,1500) repeat 55 if INA[UPPER_SWTCH_PIN] == 1 pause(300) HB25.SetMotorS(1500,1500) doorState := OPEN OUTA [RELAY_PIN] := OFF 'pst.Str(String("Success!! ",13)) return pause(100) HB25.SetMotorS(1500,1500) doorState := OPEN OUTA [RELAY_PIN] := OFF 'pst.Str(String("Fail ",13)) statusLED(1) 'trigger alarmOkay so if your pulse comes in during the pause(100) it would be missed by the IF INA evaluation. That is what I meant. Since nothing is happening there except a test for the state of the pin, you wouldn't want a delay in that loop.
Doc
PS - that Chris Savage guy is not all that bad :nerd: