Servo Range Extender and Failsafe

goom

Senior Member
This project takes a signal from a hobby RC radio receiver, manipulates the signal, then outputs to a servo.
The user can set up the following by pressing a button on the board:
Neutral position
Maximum travel
Minimum travel
Failsafe position
I use it to extend servo travel by up to 180° for use as a model boat sall winch.
Code:
'Servo end point adjustor and fail-safe
'Kevin Goom, 4 April 2009
'PICAXE-08M connections are:
' Leg 1                    +5V
' Leg 2 (Serial in)     Tie to ground through 10K resistor
' Leg 3  (In4/out4/ADC4) Pulse input from radio receiver through 330 ohm resistor
' Leg 4  (In3)           Momentary push switch to 5V & 10K to ground
' Leg 5  (In2/out2/ADC2) Wiper of 10K pot, other pot legs to +5V & ground
' Leg 6 (In1/out1/ADC1) Pulse output to servo.    
' Leg 7 (Out0/Serout)  LED anode, cathode through 470 ohm to ground
' Leg 8 (Out5)      Ground
symbol PW_In=w0   'Name the input pulse width
'b2 not used
symbol PW_In_Old=b3   'Name the previous input pulse width
symbol Scale_H=b4   'Name the scale factor for positive servo rotation
symbol Scale_L=b5   'Name the scale factor for negative servo rotation
symbol Pot_ADC=b6   'Name the ADC pot reading
'b7 not used
'b8 used in 2 counter loops
symbol Flash_Times=b9  'Name the number of times to flash the indicator during setup
symbol PW_Default=b10  'Name the pulse width when signal is lost
symbol PW_Null=b11   'Name the null position input pulse width
symbol PW_Out=w6   'Name the output pulse width
setint %00001000,%00001000 'Trap setup input on In3, Leg4
eeprom 0,(150,80,80,150)  'Set default values to be used before calibration is run
read 0,PW_Null    'Read null pulse width previously stored      
read 1,Scale_H    'Read scale factor for positive servo rotation previously stored
read 2,Scale_L    'Read scale factor for negative servo rotation previously stored
read 3,PW_Default   'Read scale factor for defaultservo rotation previously stored
Main_Loop:
   pulsin 4,1,PW_In   'Measure the input pulse width
   if PW_In>75 and PW_In <225 then Input_Valid 'Exit loop & continue if valid pulse detected
   servo 1,PW_Default    'Initiate servo pulse train
 
Invalid_Loop:
   servopos 1,PW_Default  'Set servo to previously stored value on signal loss
   pulsin 4,1,PW_In   'Measure the input pulse width
   if PW_In<76 or PW_In >224 then Invalid_Loop
   Low 1      'Turn off servo command
   goto Input_Valid
Input_Valid:
   If PW_In_Old>PW_In then
      b8=PW_In_Old-PW_In
   else
      b8=PW_In-PW_In_Old
   endif
   if b8<2 then Skip   '1 unit of hysteresis to prevent servo jitter
   PW_In_Old=PW_In
   Gosub Calc
   Skip:
   pulsout 1,PW_Out
   goto Main_Loop
Calc:
   if PW_In>=PW_Null then
      PW_Out=PW_In-PW_Null*Scale_H/80+PW_Null
      PW_Out=PW_Out max 250
   else
      PW_Out=PW_Null-PW_In*Scale_L/80
      PW_Out=PW_Null-PW_Out min 40
   endif
Return
Setup:
   Pause 1000    'Pause allow time for button release
   Setup_Center:
   pulsin 4,1,PW_Null  'Measure input pulse
   pulsout 1,PW_Null
   if pin3=0 then Setup_Center'Keep reading input pulses until setup button pressed
   write 0,PW_Null   'Store the center position pulse width
   Flash_Times=1
   gosub Flash    'Indicate setup of center position has been completed
 
   Setup_max:
   pulsin 4,1,PW_In
   Readadc 2,Pot_ADC
   Scale_H=Pot_ADC*100/128
   Gosub Calc
   pulsout 1,PW_Out
   if pin3=0 then Setup_max 'Keep reading ADC until setup button pressed
   write 1,Scale_H   'Store the positive rotation scale factor
   Flash_Times=2
   gosub Flash    'Indicate setup of positive rotation has been completed
 
   Setup_min:
   pulsin 4,1,PW_In
   Readadc 2,Pot_ADC
   Scale_L=Pot_ADC*100/128
   Gosub calc
   pulsout 1,PW_Out
   if pin3=0 then Setup_min 'Keep reading ADC until setup button pressed
   write 2,Scale_L   'Store the negative rotation scale factor
   Flash_Times=3
   gosub Flash    'Indicate setup of negative rotation has been completed
 
Setup_Default:
   pulsin 4,1,PW_In
   gosub Calc
   pulsout 1,PW_Out
   if pin3=0 then Setup_Default'Keep reading pulses until setup button pressed
   PW_Default=PW_Out
   write 3,PW_Default  'Store the pulse width for loss of signal
   Flash_Times=4
   gosub Flash    'Indicate setup of signal loss default has been completed
   pause 1000
   low 0     'Turn off setup indicator
   low 1     'Turn off servo command  
Return
Flash:     'Indicate value has been read and stored
   for b8=1 to Flash_Times
      low 0
      pause 500
      high 0
      pause 500
   Next b8 
return
Interrupt:
   high 0      'Turn on setup indicator 
   gosub Setup
   setint %00001000,%00001000  'Reset interrupt 
return
Schematic and PCB layout (Visio drawn) attached.
The only problem that I have found is that the failsafe position does not exactly match the position selected during the setup procedure. Technical have confirmed that this is due to a small difference in the pulsout and servopos timings. It may be possible to calibrate this out in code.
 

Attachments

Last edited:

goom

Senior Member
I managed to get the failsafe position (which uses servopos) to be close to the user calibrated failsafe (which uses pulsout) by changing the code:
PW_Default=PW_Out
to
PW_Default=PW_Out-8
 
Top