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):
Code:
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