|
PWPS (Pulse Width Position
Servo)
This program is a modification of the SSPWM
program. The only real difference is in the way it calculates the
number of timer ticks that are required in each period. This version
can get very accurate results by simply adding uS together instead of
doing the process of converting Frequency and Dutycycle with integer math
like SSPWM.
Using Timer1 interrupts it will run in the Background of PicBasic Pro,
creating a continuous stream of pulses without the programs
intervention. You only need to update the Position as needed to cause
movement.
The range of pulses it produces is:
1.05ms to 1.95ms in 900 steps, starting at
0.
Each step represents a .1° rotation or 1us
change in pulse width. 0 is fully counterclockwise,
450 is center position 45°, 900 is Full travel
Clockwise 90° (Assuming you have a 90°
servo)
Servos can vary widely, as a
result these numbers may not reflect the way the output will work with any
given motor. Check the manufacturers data sheet to better
determine actual position angles.
Output frequency remains a constant 50 Hz.
The routine calculates PulseTicks1ms as a starting point
of 1.05ms, then calculates how many timer ticks to add to it according to
the Position value. This way it can maintain a 1us accuracy across the
entire range of pulse widths.
Position gets limited to 900 to keep things from going too
far accidentally.
This is all it takes to use it in your program.
PWPSpin var PORTB.0 ' Output Pin for PWPS
include "PWPS_Servo.INC" ' Output Pin must be Defined before Include file
Position = 450 ' Set Center Position of Servo (word) 0-900
gosub StartPWPS ' Start the PWM output | Then,
anytime you want to change the pulse width, do this:
Position = 100 ' Set Position of Servo to 10° (word) 0-900
Gosub SetPWPS ' Set new Pulse Width | If
you need to stop the PWM output:
That's
about all there is to it. Well, except for one little problem
... If you get an error when compiling that looks like this ERROR: Variable wsave3 position request 392 beyond RAM_END 255.
ERROR: Variable wsave2 position request 276 beyond RAM_END 255. Then
you are using one of the smaller Pic chips that has fewer banks of RAM.
This is where the W register would be saved if the current bank was 2 or 3
when the interrupt gets called. But since the chip doesn't have that many
banks, it causes an error. Simply comment out the line that causes
the error. If you use the program again on a larger chip,
you'll need to Un-Comment those lines again, or it can cause some very
strange bugs.
NOTE: This program uses Interrupts and
Timer1. If you are using this in an existing program that is also
using interrupts you will probably have Conflicts. -- More Info --
Thoroughly tested on 16F877 @ 4Mhz on a LAB-X2.
Thanks to Michael J. Pawlowsky, it was found that by changing 2
lines of code, the range could be extended to 0.9ms - 2.1ms in 1200 steps,
starting at 0 Each step still represents a 1us change in pulse
width. This corresponds to 120% gain setting on a transmitter.
' Change these two lines in "PWPS_Servo.INC" to extend range to 0.9ms - 2.1ms
LookUp2 y,[ 900, 1800, 2250, 2700, 3600, 4500, 5400, 5625, 7200, 7425, 9000],PulseTicks1ms
Position = Position min 1200 |
BTW, Michael may be using the routine in his AutoPilot program
for R/C Planes. Very Cool stuff.
http://www.wimac.org/projects/mpawlowsky/drone http://cvs.sourceforge.net/viewcvs.py/rcpilot/rcap/src/main.bas?rev=1.2&view=markup
|