You know Eddie, I think you might be on to something!
In both Pbasic and Mbasic, you can write variables to the eeprom. This might be a good thing to try. This could help “protect” the variable from being affected from the interrupt.
You know Eddie, I think you might be on to something!
In both Pbasic and Mbasic, you can write variables to the eeprom. This might be a good thing to try. This could help “protect” the variable from being affected from the interrupt.
What about what Eddie said about writing the variables to eeprom, could this possibly help?
You know Eddie, I think you might be on to something!
In both Pbasic and Mbasic, you can write variables to the eeprom. This might be a good thing to try. This could help “protect” the variable from being affected from the interrupt.
I am currently experimenting with the enable and disable commands. They allow you to enable and disable the interupt. Nothing good to say yet, but I am still working.
I tried disabling the interupt when the decisions are being made.
[code]main
disable WKPINT_3
if(command<>0xFF)then
’ serout S_OUT,i115200,"Address = ",hex address,13,"Command = ",hex command,13]
if (command = 0) then
servop = 4000
endif
if (command = 1) then
servop = 3000
endif
if (command = 2) then
servop = 2000
endif
Command=0xFF
endif
enable WKPINT_3
pulsout 15,servop
pause 20
goto main[/code]
But it’s still loosing interest in behaving after a while.
Have you tried mine? Instead of having it send the servo pulse to the servo, make it print it to the terminal. I think its a better method of debugging. You might also want to stick a print into the label which checks for the command.
Have you tried mine? Instead of having it send the servo pulse to the servo, make it print it to the terminal. I think its a better method of debugging. You might also want to stick a print into the label which checks for the command.
Well I didn’t think this was worth trying as it worked fine before I added the pulsout commands. However I did go back and put the terminal serial command back in. Low and behold it is getting corrupt. After working for a while it starts sending garbage to the screen…
At first it works…
Address = 1
Command = 1
Address = 1
Command = 1
Then after a while it sends this…
{Ønd = 0
Addresÿî = 0
Comý{Ønd = 0
{Ønd = 0
Addre^þ0
Com
/Ã{ö^þ0
Addre^þ0
Com
/Ã{ö^þ0
Addresÿî = 0
Comý{Ønd = 0
Addresÿî = 0
Comss{Ønd = 0
Addresÿî = 0
Comî = 0
Clicking dissconnect and then reconnect seems to fix it. But it’s just temporary…
This is with no pulsout commands. Thanks for making me go back to the beginning.
So it has to be the interupt code. This is with no pulsout commands. Thanks for making me go back to the beginning.
LOL, but it’s not all bad though, it’s interesting to “see” what was going on…
Yup, thought so. Nothing wrong with your servop stuff, had to be the commands/address it was getting.
It’s gona be a little longer before I can get back to this code. But until then…
The problem causing the data to become invalid is being caused because the IRPD is missing a pulse. When it does there is no recovering with the current code because it has no way of knowing it missed a pulse. What needs to be done is setup a TimerA interrupt that keeps track of the current pulse width. By keeping track of the time, if the pulse gets longer than a valid pulse(ie greater than 195) the sequence needs to be reset(setting lasttime = -1 will reset the sequence for the next valid pulse train from the remote).
So here’s the code(not tested and probably has bugs/typos):
ONINTERRUPT WKPINT_3,handle_irpd
ONINTERRUPT TIMERA_OVF,handle_timera
PMR5.bit3 = 1
TMA=4 ;increments on clock/256
ENABLE WKPINT_3
ENABLE TIMERA_OVF
lasttime var long
currenttime var long
datacount var byte
irpd_data var word
command var byte
address var byte
ServoP var word
currenttime=0
lasttime = -1 ;indicate next data should be a startpulse
low 15
main
pulsout 15,servop
pause 20
if(command<>0xFF)then
; serout S_OUT,i115200,"Address = ",hex address,13,"Command = ",hex command,13]
if (command = 0) then
servop = 4000
endif
if (command = 1) then
servop = 3000
endif
if (command = 2) then
servop = 2000
endif
Command=0xFF
endif
goto main
;Modified handle_irpd routine
handle_irpd
if(lasttime<0)then
datacount=0
lasttime=currenttime+TCA
else
datacount=datacount+1
lasttime=(currenttime+TCA)-lasttime
irpd_data=irpd_data>>1
if(lasttime>175 AND lasttime<195)then
irpd_data=0
elseif(lasttime>100 and lasttime<120)
irpd_data.bit10=1
elseif(lasttime>65 and lasttime<85)
irpd_data.bit10=0
else
;invalid pulse received
lasttime=-1
resume ;resume imediately
endif
if(datacount=12)then
lasttime=-1
command = irpd_data&0x7F
address = irpd_data>>7
else
lasttime = currenttime+TCA
endif
endif
resume
handle_timera
currenttime=currenttime+256
resume
That should work to handle bad pulses. I may have the wrong name for the TIMERA_OVF interrupt but the rest looks right.
Nathan