HomeArticlesProjectsBlogContact
Articles
Joy Stick Controller
Colin Mitchell
Colin Mitchell
November 10, 2010
Make sure to subscribe to our newsletter and be the first to know the news.

Table Of Contents

01
The CIRCUIT
02
THE JOY STICK
03
THE SERVO
04
SPEED
05
INSTRUCTIONS FOR USE
06
CONSTRUCTION
07
Making the Joy Stick
08
Adjusting the Range
09
Joy Stick Controller Parts List
10
The PROGRAM
11
PROGRAMMING THE CHIP
12
PROGRAMMING LANGUAGE

Also called a: Servo Motor Controller

[Kits are available](mailto:colin@elechelp.com?Subject=Buying Joy Stick Controller kit&Body=Please e-mail the cost of Joy Stick Controller kit by air mail to my country:****___**** and send details of how I can pay for it. My name is:____) for this project from Talking Electronics for $20.00 plus postage.

  • PIC12F629 Data Sheet (.pdf 4,926KB)

  • Instruction Set for PIC12F629

  • blank12F629.asm template

  • PIC12F629.inc

  • See more projects using micros:

  • Notepad++ or VS Code

  • Library of Sub-routines “Cut and Paste”

  • Library of routines: A-E E-P P-Z

This project controls two servo motors - both clockwise and anticlockwise and has variable speed.
You can use the Joy Stick to “pan and tilt” a remote camera or provide “left-right-up-down” action for a crane or an animation on your model layout. The project also tests servo motors.

The CIRCUIT

The circuit is fairly simple.
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 servo’s when the project is used to test these devices. The photo’s below show the circuit built on prototype board: JoyStick 1

JoyStick 2
Joy Stick Controller built on Prototype PCB

THE JOY STICK

There are 7 different (actually more) combinations of positions for the joy stick 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 and 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 is 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 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.

INSTRUCTIONS FOR USE

Connect two servos and move the Joy Stick to turn the appropriate servo in the desired direction.
If the project fails to work, check the batteries as the voltage on the chip must be 5.5v to detect the switches and the correct position of the pot, (via charging the 100n caps) and a low voltage will prevent the right switches being detected.

CONSTRUCTION

You can build the circuit on any type of PC board and we have used a small piece of experimenter board as it has been especially designed for through-hole components and surface-mount devices. With all the lands on the top surface, you can see the components and wiring at the same time and this makes development very easy and you can easily change any of the components.
The kit comes with all the parts you need to get the project working, including a pre-programmed chip and the experimenter board, developed by Talking Electronics.
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 lap top via the USB port and an adapter we call 6pin 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.

Making the Joy Stick

The Joy Stick consists of 4 buttons soldered to the PC board with a small square piece of PC board glued to the tops of the switches with Araldite.
A 15mm x 3mm machine screw (machine bolt) is soldered to the underside of the PC board before gluing to the buttons. A small length of heatshrink is then shrunk over the screw to create a lever.
All the other components are soldered to the board as shown in the photos above, using fine tinned copper or fine enamelled wire to create the wiring.

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 degrees 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.

Joy Stick Controller Parts List

Cost:au$20.00 plus postage
[Kits are available](mailto:colin@elechelp.com?Subject=Buying Joy Stick Controller kit&Body=Please e-mail the cost of Joy Stick Controller kit by air mail to my country:****___**** and send details of how I can pay for it. My name is:____)

  • 1 - 220R (221) SM resistors

  • 6 - 330R (331) SM resistors

  • 2 - 22k (223) SM resistors

  • 2 - 47k (473) SM resistors

  • 1 - 100k pot

  • 4 - 100n SM capacitors

  • 1 - 100u electrolytic

  • 1 - SM diode 1N4148

  • 1 - SPDT mini slide switch

  • 1 - 8 pin IC socket

  • 1 - PIC12F629 chip (with Joy routine)

  • 6 - yellow SM LEDs

  • 4 - mini tactile switches

  • 2 - 3-pin 90 degree header pins

  • 1 - 9v battery snap

  • 1 - 20cm fine enamelled wire

  • 1 - 10cm fine tinned copper wire

  • 1 - 15mm x 15mmm PCB blank

  • 1 - 15mm x 3mm machine screw with nut

  • 1 - 15mm x 3mm heatshrink tubing

  • 20cm very fine solder

  • 1 - Experimenter PC Board

Here are the files you will need:

;*******************************
;;**JoyStickController****.asm**
;
;drives 2 servo motors forward and reverse
;10-11-2010
;*******************************

    list    p=12F629
    radix   dec
    include "p12f629.inc"

    errorlevel  -302    ; Don't complain about BANK 1 registers

    __CONFIG    _MCLRE_OFF & _CP_OFF
                      & _WDT_OFF & _INTRC_OSC_NOCLKOUT  ;Internal osc.

;_MCLRE_OFF  - master clear must be off for gp3 to work as input pin

;******************************
; variables - names and files
;*****************************

temp1         equ 20h       ;
temp2         equ 21h       ;

Sw_FlagT    equ 25h     ;switch flag top
Sw_FlagB    equ 26h     ;switch flag bottom
count   equ 27h         ;loops of discharge time for 100n
PotValue    equ 28h       ;value of pot


;***************************
;Equates
;***************************
status      equ 0x03
rp1         equ 0x06
rp0         equ 0x05
GPIO          equ 0x05


status          equ   03h
option_reg      equ     81h


        ; bits on GPIO

pin7          equ   0   ;GP0  left servo motor
pin6          equ   1   ;GP1  right servo motor
pin5          equ   2   ;GP2  100k speed pot
pin4          equ   3   ;GP3  Input ONLY - not used
pin3          equ   4   ;GP4  input from 2 top buttons
pin2          equ   5   ;GP5  input from 2 bottom buttons


        ;bits

rp0     equ 5   ;bit 5 of the status register

;**********************
;Beginning of program
;**********************
      org   0x00
      nop
      nop
      nop
      nop
      nop
SetUp   bsf   status, rp0   ;Bank 1
      movlw b'11101000'   ;Set TRIS  GP0,1,4 out
        movwf   TRISIO
        bcf   status, rp0       ;bank 0
      movlw 07h             ;turn off Comparator ports
      movwf CMCON           ;must be placed in bank 0
      clrf  GPIO            ;Clear GPIO of junk
        goto    Main



;****************
;delays *
;****************

_uS movlw     08Ch
    movwf     temp1
    decfsz  temp1,f
    goto      $-1
    retlw   00


    ;delay for pulsing servo anticlockwise

acw
    movlw     60h
    movwf     temp1
    decfsz  temp1,f
    goto      $-1
    retlw   00


_1mS    nop
      decfsz    temp1,f
      goto    _1mS
      retlw     00



_10mS   movlw     0Ah
      movwf   temp2
      nop
      decfsz    temp1,f
      goto    $-2
      decfsz    temp2,f
      goto    $-4
      retlw     00

_15mS   movlw     .15
      movwf   temp2
      nop
      decfsz    temp1,f
      goto    $-2
      decfsz    temp2,f
      goto    $-4
      retlw     00


_18mS   movlw     .18
      movwf   temp2
      nop
      decfsz    temp1,f
      goto    $-2
      decfsz    temp2,f
      goto    $-4
      retlw     00


    ;delay to create value for pot for servo speed

PotDel  movlw     0A0h
        movwf     temp1
        decfsz  temp1,f
        goto      $-1
        retlw   00


;***************************
; Sub Routines    *
;***************************


    ;position of pot creates a value in PotValue

Pot bsf   status,rp0
    bcf   trisio,2      ;Make GP2 output
    bcf   status,rp0
    bcf   gpio,2          ;make GP2 LOW
    call    _1mS            ;create delay to discharge 100n
    bsf   status,rp0
    bsf   trisio,2      ;Make GP2 input
    bcf   status,rp0
    clrf    PotValue
    call    PotDel
    incf    PotValue,f
    btfss   gpio,2        ;is input HIGH?
    goto    $-3
    retlw   00            ;returns with a value in PotValue

    ;SwTop sets bit 1,2,3,4 in Sw_FlagT file

SwTop   clrf      Sw_FlagT
      clrf    count
      bsf       status,rp0
      bcf       trisio,4        ;Make GP4 output
      bcf       status,rp0
      bcf       gpio,4        ;make GP4 LOW
      call    _1mS          ;create delay to discharge 100n
      bsf       status,rp0
      bsf       trisio,4        ;Make GP4 input
      bcf       status,rp0
      call    _uS
      incf    count,f
      movlw   .10             ;create 10 loops to definitely return
      xorwf   count,w
      btfsc   status,z
      goto    $+3
      btfss   gpio,4          ;is input HIGH?
      goto    $-7             ;count exits with 1-4
      decfsz    count,f
      goto    $+3
      bsf       Sw_FlagT,1  ;both top buttons pressed
      retlw   00
      decfsz    count,f
      goto    $+3
      bsf       Sw_FlagT,2  ;left top button pressed
      retlw   00
      decfsz    count,f
      goto    $+3
      bsf       Sw_FlagT,3  ;right top button pressed
      retlw   00
      bsf       Sw_FlagT,4  ;no buttons pressed
      retlw   00

    ;SwBott sets bit 1,2,3,4 in Sw_FlagB file

SwBott  clrf    Sw_FlagB
        clrf    count
        bsf   status,rp0
        bcf   trisio,5      ;Make GP5 output
        bcf   status,rp0
        bcf   gpio,5          ;make GP5 LOW
        call    _1mS            ;create delay to discharge 100n
        bsf   status,rp0
        bsf   trisio,5      ;Make GP5 input
        bcf   status,rp0
        call    _uS
        incf    count,f
        movlw   .10           ;create 10 loops to definitely return
        xorwf   count,w
        btfsc   status,z
        goto    $+3
        btfss   gpio,5        ;is input HIGH?
        goto    $-7           ;count exits with 1-4
        decfsz  count,f
        goto    $+3
        bsf   Sw_FlagB,1    ;both lower buttons pressed
        retlw   00
        decfsz  count,f
        goto    $+3
        bsf   Sw_FlagB,2    ;left lower button pressed
        retlw   00
        decfsz  count,f
        goto    $+3
        bsf   Sw_FlagB,3    ;right lower button pressed
        retlw   00
        bsf   Sw_FlagB,4    ;no buttons pressed
        retlw   00


;****************************************************************
;* Main                     *
;****************************************************************

Main    call    SwBott          ;to detect 2 lower buttons
      btfsc Sw_FlagB,4      ;bit 4 set if no buttons pressed
      goto  _b            ;go to detect top buttons
      call  Pot           ;determine servo speed
      btfsc Sw_FlagB,2    ;left lower button pressed
      goto  $+9
      btfss Sw_FlagB,3    ;right lower button pressed
      goto  Main
      bsf     gpio,0            ;creates clockwise motion
      call  _1mS              ;for clockwise pulse
      call  _1mS              ;for clockwise pulse
      bcf     gpio,0
      call  _18mS
      goto  $+5
      bsf     gpio,0            ;creates anticlockwise motion
      call  acw             ;anticlockwise pulse
      bcf     gpio,0
      call  _18mS
      decfsz    PotValue,f
      goto  $-2
      goto  Main


_b  call    SwTop               ;to detect 2 top buttons
    btfsc   Sw_FlagT,4        ;bit 4 set if no buttons pressed
    goto    Main                ;
    call    Pot               ;determine servo speed
    btfsc   Sw_FlagT,2      ;left top button pressed
    goto    $+9
    btfss   Sw_FlagT,3      ;right top button pressed
    goto    _b
    bsf   gpio,1              ;creates clockwise motion
    call    _1mS                ;for clockwise pulse
    call    _1mS                ;for clockwise pulse
    bcf   gpio,1
    call    _18mS
    goto    $+5
    bsf   gpio,1              ;creates anticlockwise motion
    call    acw               ;anticlockwise pulse
    bcf   gpio,1
    call    _18mS
    decfsz  PotValue,f
    goto    $-2
    goto    Main

    END

The PROGRAM

The micro starts at SetUp routine, then goes to Main where it constantly loops the two Joy Stick inputs by accessing one of the lines and discharging the 100n capacitor. It then makes the line an input and calls a delay. It looks to see if the voltage on the 100n is above about 1.5v as this will indicate a HIGH. It increments a counter and loops up to ten times. If one of the buttons is pressed, the line will see a HIGH after 3 loops and thus the sub-routine returns with a bit set in Sw_FlagT for a top button or Sw_FlagB for a bottom button. Bit1 is set if both switches are pressed, Bit2 is set if the left switch is pressed, bit3 is set if the right switch is pressed and bit4 is set to signify no switch is pressed.
This result is used in Main to create a repeat “looking-loop” if no switch is pressed, but if a switch is pressed, the Pot sub-routine is called to determine the position of the potentiometer.
The program detects 12 positions for the pot by firstly discharging the 100n then creating a timing loop and counting the number of loops to charge the 100n to a point where the input line sees a HIGH. This is approx 1.2 - 1.5v.

The instructions in Main then turn on an output for one of the servo motors for 1mS or 2mS, depending on the button that has been pressed, then turns off the output. A delay is then created of 18mS duration (if the pot has the lowest resistance) and this is increased by 18mS for each additional position of the pot.

PROGRAMMING THE CHIP

The kit comes with a pre-programmed PIC chip but if you want to program your own chip or modify the program, the .hex file is available as well as the assembly file, so you can see how the program has been written and view the comments for each line of code.
The PIC12F629 is one of the smallest micros in the range but you will be surprised how much can be achieved with such a tiny micro.
Even a program as simple as this is not easy to put together and if you want to change any of the features, you should do things in very small steps and stages so that each can be tested before adding more code.
This is what we have done. We produced the program, one small step at a time.
We had to firstly work out a routine to produce a value of 1,2,3,4 for the Joy Stick switches, then create a pulse of the correct duration to create clockwise and anticlockwise rotation.
When this was done we needed to create an output for the pot and add the delay to the program to create the speed.
If you want to change anything, you will have to buy a programmer (“burner”) called a PIC-2 USB Burner if you are using a laptop. It is the cheapest and best on the market and comes with a USB cable and CD containing the programs needed to “burn” the chip. If you are using a desk-top and/or tower with a serial port, you can use a cheaper programmer called MultiChip Programmer from Talking Electronics. You will also need NotePad2 to write your .asm program. This can be downloaded from Talking Electronics website. You will use JoyStick.asm or JoyStick-asm.txt as a template for your program, plus a 6 pin to 5 pin connector that fits between the burner and the project. This is also available on Talking Electronics website.
To be able to modify the chip you will need a programming socket and PC board for the socket.
You can then put the chip into the socket and program it, then re-fit it into this project for execution.

PROGRAMMING LANGUAGE

There are a number of kits, programs and courses on the market that claim and suggest they teach PIC Programming.
Most of these modules and courses use a PIC microcontroller as the chip carrying out the processes, but the actual programming is done by a proprietary language invented by the designer of the course.
Although these courses are wonderful to get you into “Programming Microcontrollers” they do not use any of the terms or codes that apply to the PIC microcontroller family.
All our projects use the 33 instructions that come with the PIC Microcontroller and these are very easy to learn.
We use the full capability of the micro and our pre-programmed chip is less than the cost of doing it any other way.
In addition, anything designed via our method can be instantly transferred to a PIC die and mass produced. And we use all the input pins and all the memory of the chip. The other approaches use less than 25% of the capability of the memory and one of the pins is not available.
In fact it would be difficult to reproduce this project via any of the opposition methods. It would require a larger chip and more expense.
You can use our method or the opposition. Just be aware that the two are not interchangeable.
Ours is classified as the lowest “form” (level) of programming - commonly called machine code - invented in the early days of microprocessors - and now called mnemonic programming as each line of code is made up of letters of a set of words. The opposition uses a higher level language where one instruction can carry out an operation similar to a sub-routine.
But you have to learn the “higher level language” in order to create a program. And this requires a fair amount of skill and capability.
It sounds great and it is a good idea. But if you want to learn PIC programming, it does not assist you. It is “a step removed” from learning PIC language. The other disadvantage of the opposition is the “overhead.” The 1,000 spaces allocated for your program is filled with pre-written sub-routines. You may require only 10 of these sub-routines but ALL of them are loaded in the memory space. And they take up all the memory.
You have no room for your own program.
To get around this the opposition uses the 128 bytes in EEPROM to deliver instructions on how to apply the sub-routines. This provides about 30 powerful instructions using their language called BASIC (or a similar language).
It’s a bit like selling a diary filled with all the paragraphs you need to express yourself, and leaving a few blank pages at the back for you to write single lines such as: see page 24, paragraph 7, see page 63 paragraph 4, to create your diary entries.
It depends on how much you want to be in charge of writing a program. Using our method is like writing your own auto-biography. Using the opposition is like getting a “ghost writer.”
When using a higher level language to create a program, you have absolutely no idea how the code is generated for the micro.
In some of the developmental kits, the code is “locked away” and you are NEVER able to access it.
Everything runs smoothly until a fault appears. With our method you can see the code. With the other methods, you cannot see the code - it’s like doing key-hole surgery without the advantage of an illuminated endoscope to see what you are doing.
Everything has its place and our method of hand-assembly is only suitable for very small micros and you will eventually need to “learn a high level language.” The PIC12F629 has over 1,000 locations for code and this equates to more than 20 pages when printed, so this is about the limit to doing things by hand.
But our drive is to show how much can be done with the simplest devices on the market, at the lowest cost.
Anyone can show you high-technology at a high price but this is not where you start and this is not where you get enthusiasm.
We provide the things to get you started. That’s the difference.


Colin Mitchell

Colin Mitchell

Expertise

electronics
writing
PIC-Chips

Social Media

instagramtwitterwebsite

Related Posts

TODO
Transistor Test
© 2021, All Rights Reserved.

Quick Links

Advertise with usAbout UsContact Us

Social Media