Basic Atom Pro / Bot Board / IRPD (remcon) Program

You know Eddie, I think you might be on to something! :laughing:

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?

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.

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. :smiley:

LOL, but it’s not all bad though, it’s interesting to “see” what was going on… :laughing:

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

I moved this to the Bipeds section.

lynxmotion.net/viewtopic.php?t=1242