View Full Version : Easy Servo driver

- 18th December 2012, 23:13
Iím trying to learn a little more about RC systems and ways to control them using PBP.
This weekend I had some time to play with and experiment different techniques to generate a signal that controls a servo motor reliably.
My main goal is to be able to receive signals from two separate RC receivers, process them and be able to select the output to control a servo motor. Depending on other external input signals I would like to beable to output one of the two individual input signals or a processed signal that will be a combination of the two.
The long term plan is to implement DTís multiple averaging methods combined with his WPS_Servo.INC that drives the servo in the background.
My experience in all above fields is limited so I started small and planning on working my way up.
In the process I came up with a ďPour manís solutionĒ to solidly drive a servo using a PIC12F683, internal oscillator, PULSIN andPAUSEUS commands. It uses a combination of DTís running average method and the AD oversampling to receive in a RC channel via PULSIN (with 10 us resolution), average and apply x10 oversampling to get a solid 1us resolution when driving aservo motor via PAUSEUS command.
I learned a lot during this exercise and I hope that some other beginners like me will find it useful.
The code (please be gentle Iím still learning) is well commented so it should be easy to follow.
I intentionally left few sections of the code commented out because this way it works best for me (I need averaging but I also need fast cutch up).
Testing the output with a scope or Hitec HFP-20 Servo tester/ programmer it is rock solid and I no longer have the famous servo wining.
When all the sections inside of the averaging routine are running there is a very nice, soft braking effect at the end of intentional fast changes in the input signal which might work out for some other applications.

Here is the working code so far:

' Uses a combination of DT's fast averaging and oversampling routines to get a
' more stable and x10 higher resolution on servo output by using PULSIN at 4MHz
' as input from a RC receiver on GPIO.3 and PAUSEUS to generate a servo motor
' pulse out on GPIO.1
' The Average routine gets Value as input and outputs ADavg to be used to
' control a servo
' Later will add DT's PWPS_Servo.INC and one more channel to monitor
' One more variable (Fraction) was added and one more user parameter (CutchUp)
' to be able to modify the routine for my application and change the speed of
' cutching up
' Verify if PULSIN and PWPS_Servo.INC are compatible.
' Add the PULSIN timeout define
' Works fine for my application with FastAvg only enabled. With RealClose and/or
' Normal enabled will have a "braking" effect at the end of Cutch Up

@ device pic12F683, intrc_osc_noclkout, wdt_on, mclr_off, protect_off

AvgCount CON 10 'Number of samples to average. To match the PULSIN @ 4MHz
FAspread CON 20 'Fast Average threshold +/- . What is best value for me?
CutchUp CON 8 'New user prameter to change Chatch up speed
Value VAR BYTE 'Only value of 100 to 200 are expected
Fraction VAR BYTE 'New variable for the averaging routine

RC_in VAR GPIO.3 'Pin 4. Add second input
Servo_out VAR GPIO.1 'Pin 6. Move on top if DT's PWPS_Servo.INC is used


ADavg = 1120 'start at most CCW permited possition. Change as needed
Goto main

Fraction = ADavg / AvgCount
IF Value = Fraction Then AVGok 'No change
' IF ABS (Value - Fraction) > FAspread OR Value < AvgCount Then FastAvg
' IF ABS (Value - Fraction) < AvgCount Then RealClose
' Normal:
' ADavg = ADavg - fraction
' ADavg = ADavg + value
' GoTo AVGok
ADavg = ADavg - (Fraction*CutchUp)
ADavg = ADavg + (Value*CutchUp)
' GoTo AVGok
' RealClose:
' ADavg = ADavg - (fraction/2)
' ADavg = ADavg + (Value/2)
PULSIN RC_in,1,Value
GOSUB Average
IF ADavg < 1120 then ADavg = 1120 'Do not go under 1120 position
HIGH Servo_out 'Replace this routine with DT PWPS_Servo
LOW Servo_out

Happy PIC-ing everyone!