| 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 CIRCUITThe 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:
 
 
  
		Joy Stick 
		Controller built on Prototype PCB 
 
		THE JOY 
		STICKThere 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.
 |  CONSTRUCTIONYou 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 
		StickThe 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.
 
 
							
								|  |  
								| 
									
										| 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:
 JoyStick.asm
 JoyStick-asm.txt
 JoyStick.hex
 
 
		
			| ;*******************************
;;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.
 |