This code is provided as an example of one way to make a 4 channel servo controller. It was developed on a PIC16F1829 but should work on any PIC that can operate at 16Mhz and has a 16-bit Timer1. The servo(s) require exclusive use of timer1. There is enough "time" available in the main loop to add 2 more servos if you need 6 channels. Or if you only need 1 or 2 channels you can remove the lines for the other servos.
Different servos have different pulse width requirements. The servos I used swing full range from 800 us to 2400 us. Some may swing full range from 1000 us to 2000 us, so the code will need to be adjusted/calibrated for the particular servos used.
I included anti-jitter code to prevent jitter due to "uncertainty" of ADC readings that can vary 1 or 2 MSB when "on the edge". ADC10 was used to provide good resolution. The servos are smooth with no jitter.
When first setting up, make sure the POTS are all at center position to prevent driving the servo into its stop and causing excessive current.
Do not attempt to drive servos from power supplied by a programmer such as Pickit 2 or Pickit 3. A separate supply for the servos is highly recommended if not necessary due to the current required. Proper grounding is critical to both good ADC readings and servo operation. The POT grounds should be tied as close to the PIC Vss Or Analog Ground Pin as possible.
I will update this code in the near future to allow stop to stop calibration of each servo. This will be in the form of defines for servo_max and servo_min. The maths for scaling/mapping the ADC to a servo pulse width will then be based upon these defines rather than fixed at 800 us to 2400 us as in this first example.
Eventually this code or something like it will be used as a starting point for a servo.h library to be included with GCB.
Your input and suggestions are encouraged.
William
Edit: Added Suggested Diagram that shows "star grounding" method to assure stable ADC.
4 Channel Servo Controller Code
This code is provided as an example of one way to make a 4 channel servo controller. It was developed on a PIC16F1829 but should work on any PIC that can operate at 16Mhz and has a 16-bit Timer1. The servo(s) require exclusive use of timer1. There is enough "time" available in the main loop to add 2 more servos if you need 6 channels. Or if you only need 1 or 2 channels you can remove the lines for the other servos.
Different servos have different pulse width requirements. The servos I used swing full range from 800 us to 2400 us. Some may swing full range from 1000 us to 2000 us, so the code will need to be adjusted/calibrated for the particular servos used.
I included anti-jitter code to prevent jitter due to "uncertainty" of ADC readings that can vary 1 or 2 MSB when "on the edge". ADC10 was used to provide good resolution. The servos are smooth with no jitter.
When first setting up, make sure the POTS are all at center position to prevent driving the servo into its stop and causing excessive current.
Do not attempt to drive servos from power supplied by a programmer such as Pickit 2 or Pickit 3. A separate supply for the servos is highly recommended if not necessary due to the current required. Proper grounding is critical to both good ADC readings and servo operation. The POT grounds should be tied as close to the PIC Vss Or Analog Ground Pin as possible.
I will update this code in the near future to allow stop to stop calibration of each servo. This will be in the form of defines for servo_max and servo_min. The maths for scaling/mapping the ADC to a servo pulse width will then be based upon these defines rather than fixed at 800 us to 2400 us as in this first example.
Eventually this code or something like it will be used as a starting point for a servo.h library to be included with GCB.
Your input and suggestions are encouraged.
William
Edit: Added Suggested Diagram that shows "star grounding" method to assure stable ADC.
Last edit: William Roth 2015-04-20
William, this is really cool. Will have to give it a whirl. would make a great include also!