|
JoyStick Controller of Servo Motors with PIC12F629

Excellent for a remote camera or provides "left-right-up-down" action for a crane or an animation on your model layout. The project also tests servo motors.
The Circuit
The input from the Joy Stick has been separated into two sections to make detection easy and this requires 2 inputs. A pot is connected to another input line and 2 more lines are required for the servos. Pin 8 is connected to 0v and pin 1 is connected to the supply. The only unused pin is GP3 (Input ONLY). Most of the work is done by the micro. It uses a technique of charging a capacitor via a resistor and determining how long it takes to charge, to work out which switch is pressed or the position of the pot. It then outputs a 1mS or 2mS pulse to one of the servo motors to create clockwise or anticlockwise rotation of the output shaft and the speed of rotation can be set by adjusting the pot. The two LEDs on the output pins let you see the pulses being delivered to the servos when the project is used to test these devices.
The JoyStick
There are 7 different (actually more) combinations of positions for the joystick and we need to decode them and work out what to do with the result. This is too many resistance-values for a single input so we have used two inputs with 3 resistance-values for each plus the possibility of all switches being pushed at the same time. The resistance values we have used are 22k and 47k. When 2 switches are pressed, the resistors are in parallel to produce 15k, but only 22k and 47k are detected in this program. The program creates a loop that detects up to 19k, to produce an output of loop=1, then up to 38k for a value of loop=2 and higher than 38k for a value of loop=3. But if the program keeps looping for 10 loops, it determines that no button is pressed and creates a value of 4. The change-points are mid-way between the resistance values we have used and thus any tolerances on the capacitors and resistors can be accommodated. This means a resistance of 15k produces a value of 1, 22k produces a value of 2 and 47k produces a value of 3. This is most important as we don't want the cut-off points to be on the border as the program may produce an output of 1 instead of 2. The project is fairly voltage sensitive and if the right-hand buttons are not detected, the battery voltage is low.
The Servo
A servo module consists of a motor and gearbox, with a PC board containing the electronics to drive the motor in a clockwise and anticlockwise direction. The electronics also detects the width of the incoming pulse to drive the motor to mid-position and also other positions, but this feature is not used in this project. The motor is connected to the positive rail of the supply via a bridge of transistors within the servo and the red and black wires from the module are taken to the positive and negative of a battery to provide the current to drive the motor. The third lead (white) is the control line and this is taken to the micro. This line needs a pulse and the maximum repetition rate accepted by the servo is every 18mS - it will accept a longer timing between pulses. This is the timing between pulses, the actual pulse width is very short, between 0.9mS and 2.2mS. If the pulse is less than 1mS duration (wide) the servo will travel fully in the anticlockwise direction. If the pulse is 2mS, the servo will travel in the clockwise direction. If the pulse is 1.5mS, the servo will travel to the mid position. If the time between pulses is longer than 18mS, the speed of rotation is decreased. This is what we have done. We have provided a 1mS or 2mS pulse and created a long time interval between pulses to produce a reduced rate of movement. The program looks at the position of the pot and adds a number of milliseconds between each pulse to produce these long time intervals. As the resistance of the pot is increased, the pulses are less frequent and the speed decreases.
Speed
This is the first time a speed feature has been added to a servo. The project can vary the speed from full rpm to a few pulses per second. It takes about 12 pulses to move 180°. Sometimes you want to move an object a small distance. A servo is not an ideal driver for this requirement as the smallest step is about 1/25th of a revolution or 15°. Even when a single pulse is delivered to the servo, the increment is about 15°. Unfortunately, this is the finest control we can get from a servo. That's why you use a stepper motor if you want very small incremental steps. However, if the pulses are delivered at about 5 per second, the rotation will be slow but fairly smooth. You will be able to set this via the pot.
Construction
However, if you want to modify the program you will need a PICkit-2 programmer and this comes with a CD containing all the software needed for In-Circuit Programming. You will also need a lead (comes with PICkit-2) to connect the programmer to your laptop via the USB port and an adapter we call a 6-pin to 5-pin Adapter to connect the PICkit-2 to a programming socket on a PC board. This is all covered in our PIC-2 USB Burner project.
The JoyStick
The JoyStick consists of 4 buttons, you can perfectly use a broken JoyStick and only use the buttons.
Adjusting the Range
The angular movement of the output shaft can be adjusted (limited) by setting the width of the forward and/or reverse pulse. When the output shaft reaches the end of its angular movement, any further pulses are neglected by the servo and no current is consumed (other than a few mA for the electronics). In other words, the motor does not get stalled. However, the rotation can be adjusted (limited) so that the output shaft does not reach the end of its travel by adjusting the value of the sub-routine called: acw (anticlockwise pulse width). [You can also (or instead) adjust the clockwise pulse width] The sub-routine "acw" is effectively a delay (made up of loops) that is loaded with a value from 1 to 250 (for 1 to 250 loops) and each loop represents 4uS delay. This means a value of 250 = (4 x 250) uS = 1,000uS = 1mS. By adding an extra instruction: call _1mS to the: call _acw we can create a delay from 1.004mS to 2mS and thus prevent the output shaft reaching the end of its travel. If we load acw with .125 we get a total delay of 1.5mS and the output will only travel to mid-position (90 degrees). A value of .60 (decimal sixty) will allow the shaft to travel 135 degrees. A value of .20 (decimal twenty) will allow the shaft to travel nearly 145 degrees. You must remove the "call _1mS" to allow the shaft to rotate to the 180-degree position. You can also adjust the amount of travel to the final device you are activating, by adjusting the length of the arm on the output of the servo. By combining these two methods you can get a wide variety of activations. You can download the basic source code written in assembly from here
|