Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Servo Controlling using PIC16F877A

Status
Not open for further replies.

bogusmeister

Junior Member level 2
Junior Member level 2
Joined
Nov 3, 2010
Messages
21
Helped
2
Reputation
4
Reaction score
1
Trophy points
1,283
Activity points
1,452
Hi guys. i am currently working on a project right now and im having a problem regarding the bit transfer from my pic16f877a to my servo controller. ive done differents set of program codes using assembly but im not able to get any acknowledgement (ACK pin) from the servo controller.. this is the manual that im referring to with sequence and steps (http://www.e-gizmo.com/KIT/images/servokit/ServoController.pdf)..

pls check my codes if it has a problem.. i dont really understand much on how the timing should go and the serial bit transfer. thanks in advance! and happy new year!!!


Code ASM - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#INCLUDE "P16F877A.INC"
   __CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF
 
   ERRORLEVEL -302
 
COUNTER EQU 0x0c
COUNTERA EQU 0x0d
 
   ORG 0x00
   GOTO START
 
   ORG 0x04
   GOTO START
 
 
START
   BSF STATUS,RP0
   MOVLW 0x02
   MOVWF TRISB
   
   MOVLW 0x07
   MOVWF OPTION_REG
   
   BCF STATUS,RP0
   CLRF PORTB
 
 
MAIN
   BSF PORTB,5      ;SWITCH EN1 TO HIGH 
   CALL ENABLE1
   CALL ENABLE0
   CALL ENABLE0
   CALL ENABLE0
   CALL ENABLE0
   CALL ENABLE0
   CALL ENABLE1
   CALL ENABLE0
 
 
   CALL ENABLE0
   CALL ENABLE0
   CALL ENABLE0
   CALL ENABLE1
   
   CALL ENABLE0
   CALL ENABLE0
   CALL ENABLE0
   CALL ENABLE0   ;SET SERVO 1 & 7 ON
   
 
   CALL ENABLE0
   CALL ENABLE0
   CALL ENABLE0
   CALL ENABLE1
   CALL ENABLE0
   CALL ENABLE1
   CALL ENABLE0
   CALL ENABLE1   
 
   CALL ENABLE0
   CALL ENABLE1
   CALL ENABLE0
   CALL ENABLE0
 
   CALL ENABLE1
   CALL ENABLE0
   CALL ENABLE0
   CALL ENABLE0   ;SETS POSITION OF SERVO1 TO 17DEGREES
   
   CALL ENABLE0
   CALL ENABLE1
   CALL ENABLE0
   CALL ENABLE0
   CALL ENABLE0
   CALL ENABLE0   
   CALL ENABLE0
   CALL ENABLE1
 
   CALL ENABLE0
   CALL ENABLE1
   CALL ENABLE0
   CALL ENABLE0
   
   CALL ENABLE1
   CALL ENABLE1
   CALL ENABLE1
   CALL ENABLE0   ;SETS POSITION OF SERVO7 TO -18DEGREES
   BSF
 
   GOTO MAIN   
   
ENABLE1
   BSF PORTB,3      ;SWITCH CLK TO HIGH
   CALL DELAY
 
   BCF PORTB,5      ;SWITCH EN1 TO LOW
   CALL DELAY
 
   BSF PORTB,4      ;SEND 1 TO DATA
   CALL DELAY
 
CLOCK1
   BCF PORTB,3      ;SWITCH CLOCK TO LOW
   CALL DELAY
   
   BTFSC PORTB,1
   GOTO CLOCK1
   RETURN
 
ENABLE0
   
   BSF PORTB,5      ;SWITCH EN1 TO HIGH 
   CALL DELAY
   
   BCF PORTB,5      ;SWITCH EN1 TO LOW
   CALL DELAY
 
   BCF PORTB,4      ;SEND 0 TO DATA
   CALL DELAY
 
CLOCK0
   BCF PORTB,3      ;SWITCH CLOCK TO LOW
   CALL DELAY
 
   BTFSC PORTB,1
   GOTO CLOCK0
   RETURN
   
DELAY
   MOVLW D'1'
   MOVWF COUNTER
 
LOOP
   CALL DELAYA
   DECFSZ COUNTER,1
   GOTO LOOP
   RETLW 0x00
 
DELAYA
   MOVLW D'20'
   MOVWF COUNTERA
 
LOOPA
   CALL DELAYB
   DECFSZ COUNTERA,1
   GOTO LOOPA
   RETLW 0x00
 
DELAYB
   CLRF TMR0
   BCF INTCON, T0IF
 
LOOPB
   BTFSS INTCON, T0IF
   GOTO LOOPB
   RETLW 0x00
   
   END

 
Last edited by a moderator:

Hi,

Well it would not really be possible to fully check your code without being able to simulate that servo board.
A simple look at the code shows that your user register addresses are wrong - for the 877A chip they start at 20h not 0Ch.

What does seem a bit odd, assuming you are using the typical hobby servo motors, then if you are using a 877a chip with about 32 free i/o lines why are you trying to run a 16 channel controller from it.
Would have thought you could have easily controlled 16 servos direct from the 877A ?
 
Hi,

Well it would not really be possible to fully check your code without being able to simulate that servo board.
A simple look at the code shows that your user register addresses are wrong - for the 877A chip they start at 20h not 0Ch.

What does seem a bit odd, assuming you are using the typical hobby servo motors, then if you are using a 877a chip with about 32 free i/o lines why are you trying to run a 16 channel controller from it.
Would have thought you could have easily controlled 16 servos direct from the 877A ?


hi. thanks for the reply,... actually i was having a hard time controlling a a hobby servo directly from my PIC16F877A. im kinda new with controlling servos that's why i brought this servo controller.. but the problem is i cant seem to properly send the bits..

uhm. is there any way i could get some example assembly codes for controlling servo motor directly from my 877A?. im looking over the internet but cant find any.. thanks you very much!!..
 

Hi,

Well I did have some simple working servo assembler code but cannot find it now !

There are loads of pic assember servo code around this forum and the web.

First have a look at this tutorial which explains how the servo is controlled.
That code should run on your 877a if you change the pic84 to 877A and again put the user registers starting at 0x20 .
**broken link removed**

Also see this thread -
https://www.edaboard.com/threads/194850/

Both of the above use whats called Software PWM, which means the pic is dedicated to doing just that.
On the 877A you have 2 hardware PWM modules which allow you to set the pulse rate you want, then go off and do other things, so you can have 2 servos directly controlled by the 877a.

There is a good PWM tutorial for the 876/7 chips here -

PIC Tutorial* Eight - using the PWM hardware


For you servo controller board think l you should search out more specific details of the comms method it needs, the datasheet is very general, with no real timing details.
Would think someone will have the answer for you.
 
Code:
	#include "p16f877.inc"
	LIST P=PIC16f877

	__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & _LVP_OFF & _CPD_OFF

	; Define variables used
	CBLOCK		0x20
			delay
			delay1
			delay2
	ENDC

	ORG		0x00
init:
	Banksel		TRISA
	CLRF		PORTA		; All pins on porta are output
	banksel		PORTA




loop:	
	BSF		PORTA,1		;
	MOVLW		d'249'		; set delay of approx 1.5ms
	CALL		Delay_1x	; 
	BCF		PORTA,1		; Turn them off, no more pulse
	MOVLW		d'18'		; set delay of approx 18ms
	CALL		Delay_10x	; 
	GOTO 		loop		; Start over





;Setup up the delay routines that may be used
;delay of 1ms for 4mHz clock
;

Delay_1ms
	Movlw	D'166'	
Delay_1x                                 ;call here with W set allows diiferent delays
	Movwf	Delay
delay_loop
	Nop
	Nop
	Nop
	Decfsz	Delay,f
	goto 	delay_loop
	return




;delay of 10ms for 4mHz clock
Delay_10ms
	movlw	d'10'
Delay_10x                               ;call here with W set allows diiferent delays

	movwf	Delay2
Delay_Loop_10ms	
	Call 	Delay_1ms		; Call 1ms delay	
	Decfsz	Delay2,f
	goto 	Delay_Loop_10ms
	return





end

Here is an example that uses Porta,1 for the signal pulse.
 
Last edited:
Hi,

Just had a bit more time to look at the Gizmo Controller and your code for it.

It needs a quite complicated routine to send out the 16 bits of command data, can see how you have attemped to do it for your one set of values, but you cannot code repeatedly in that fashion - plus what you had coded is wrong in a few areas - but no worries you have tried to start and get somewhere, it all part of learning, you will get there;-)

Basically, learn to control the servo direct from the Pic chip using the code examples shown and even using the Hardware PWMs - shout if you are stuck.

Get it all working together on the hardware and then when you want to control more than 2 motors come back and get help on the software for the Gizmo.
 
Have you seen Nigel Goodwin's tutorials? Send me a PM if you can't find him by an internet search.

One of them includes the software (in assembly) for RS232 data transfer.. It may help you.

If it is not exactly what you want, you may be able to modify it.
 
Have you seen Nigel Goodwin's tutorials? Send me a PM if you can't find him by an internet search.

One of them includes the software (in assembly) for RS232 data transfer.. It may help you.

If it is not exactly what you want, you may be able to modify it.

Why not just post the link Nigel Goodwins tutorial page
 
  • Like
Reactions: bogusmeister

    bogusmeister

    Points: 2
    Helpful Answer Positive Rating
    V

    Points: 2
    Helpful Answer Positive Rating
Have you seen Nigel Goodwin's tutorials? Send me a PM if you can't find him by an internet search.

One of them includes the software (in assembly) for RS232 data transfer.. It may help you.

If it is not exactly what you want, you may be able to modify it.

Hi,

Had mentioned Nigels good assembler tutorial earlier for help on the Hardware PWM.

That Gizmo board does send data in a simple serial fashion but uses a custom 4 wire protocol which sadly none of the standard PICUsart / rs232 or spi modules will handle so it seems a routine needs to be coded - not a project for the beginner.

Its quite common to find devices like this with their own prototcols, many sensors like SHT11 and DTH11 all use non standard serial ways.

Have searched around for a code example of that Gizmo board - nothing to be found.....
 
  • Like
Reactions: bogusmeister

    bogusmeister

    Points: 2
    Helpful Answer Positive Rating
    V

    Points: 2
    Helpful Answer Positive Rating
Code:
	#include "p16f877.inc"
	LIST P=PIC16f877

	__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & _LVP_OFF & _CPD_OFF

	; Define variables used
	CBLOCK		0x20
			delay
			delay1
			delay2
	ENDC

	ORG		0x00
init:
	Banksel		TRISA
	CLRF		PORTA		; All pins on porta are output
	banksel		PORTA




loop:	
	BSF		PORTA,1		;
	MOVLW		d'249'		; set delay of approx 1.5ms
	CALL		Delay_1x	; 
	BCF		PORTA,1		; Turn them off, no more pulse
	MOVLW		d'18'		; set delay of approx 18ms
	CALL		Delay_10x	; 
	GOTO 		loop		; Start over





;Setup up the delay routines that may be used
;delay of 1ms for 4mHz clock
;

Delay_1ms
	Movlw	D'166'	
Delay_1x                                 ;call here with W set allows diiferent delays
	Movwf	Delay
delay_loop
	Nop
	Nop
	Nop
	Decfsz	Delay,f
	goto 	delay_loop
	return




;delay of 10ms for 4mHz clock
Delay_10ms
	movlw	d'10'
Delay_10x                               ;call here with W set allows diiferent delays

	movwf	Delay2
Delay_Loop_10ms	
	Call 	Delay_1ms		; Call 1ms delay	
	Decfsz	Delay2,f
	goto 	Delay_Loop_10ms
	return





end

Here is an example that uses Porta,1 for the signal pulse.


would this be the exact code if im gonna send a pulse directly to a servo motor?.. because i have researched a schematic diagram for direct interface to a servo motor?..

---------- Post added at 10:54 ---------- Previous post was at 10:47 ----------

hi guys. thanks for your replies!!!... this servo controller board is really giving me hard time, been working with this for weeks and cant get any good results..... would it be possible to control 5 servo motors directly with the use of a PIC16f877A if im gonna operate those 5 motors one at a time or maybe two at a time?. cause right now im planning to shift from this controller board to just directly using my PIC to control the motors.. could someone give an ASSEMBLY CODE for this scenario of controlling motors?... thank you very much everyone!!!
 

    V

    Points: 2
    Helpful Answer Positive Rating
would this be the exact code if im gonna send a pulse directly to a servo motor?.. because i have researched a schematic diagram for direct interface to a servo motor?..

---------- Post added at 10:54 ---------- Previous post was at 10:47 ----------

hi guys. thanks for your replies!!!... this servo controller board is really giving me hard time, been working with this for weeks and cant get any good results..... would it be possible to control 5 servo motors directly with the use of a PIC16f877A if im gonna operate those 5 motors one at a time or maybe two at a time?. cause right now im planning to shift from this controller board to just directly using my PIC to control the motors.. could someone give an ASSEMBLY CODE for this scenario of controlling motors?... thank you very much everyone!!!

Hi,

Well first things first..

Here is the code that Cuban posted earlier, with a couple of amendments so it will build ok.

So you need to connect your servo and run this code on it to prove it works.

By following those Servo tutorials mentioned earlier and changing the Delay Values you will start to see how you control the motor.

This method is "software" PWM - good and simple but limiting.

Get this done and proven then you can move on to the Hardware PWM method which means you can easily control 2 servos from each pic.

Look at controlling 5 motors when you have learnt how to do the above.

As you saying you do not know how to connect up the pic and motor - do you need a diagram ?

Let us know what hardware have you got, breadboard, soldering on a strip , psu ,programmer etc

Code:
	LIST P=PIC16f877A

	#include "p16f877A.inc"

	__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _XT_OSC & _LVP_OFF & _CPD_OFF

	; Define variables used
	CBLOCK		0x20
			Delay
			Delay1
			Delay2
	ENDC

	ORG		0x00
init:

	banksel  	 ADCON1
	movlw		 0x06 		; all pins digital I/O			
	movwf		 ADCON1
	
	CLRF		PORTA

	Banksel		TRISA
	CLRF		TRISA		; All pins on porta are output
	banksel		PORTA




loop:	
	BSF			PORTA,1		;
	MOVLW		d'249'		; set delay of approx 1.5ms
	CALL		Delay_1x	; 
	BCF			PORTA,1		; Turn them off, no more pulse
	MOVLW		d'18'		; set delay of approx 18ms
	CALL		Delay_10x	; 
	GOTO 		loop		; Start over





;Setup up the delay routines that may be used
;delay of 1ms for 4mHz clock
;

Delay_1ms
	Movlw	D'166'	
Delay_1x                                 ;call here with W set allows diiferent delays
	Movwf	Delay
delay_loop
	Nop
	Nop
	Nop
	Decfsz	Delay,f
	goto 	delay_loop
	return




;delay of 10ms for 4mHz clock
Delay_10ms
	movlw	d'10'
Delay_10x                               ;call here with W set allows diiferent delays

	movwf	Delay2
Delay_Loop_10ms	
	Call 	Delay_1ms		; Call 1ms delay	
	Decfsz	Delay2,f
	goto 	Delay_Loop_10ms
	return





	end
 
  • Like
Reactions: bogusmeister

    bogusmeister

    Points: 2
    Helpful Answer Positive Rating
    V

    Points: 2
    Helpful Answer Positive Rating
Hi,

The code above is just a simple instruction to move the servo to one position, perhaps not the best way to prove the hardware.

The attached .hex file, ready to program into your 877A, will move the servo between two points 45 degrees apart every five seconds.

I have it working on my 877A and Hitec HS-311 now.
 

Attachments

  • servo1.rar
    130.7 KB · Views: 150
Last edited:

    V

    Points: 2
    Helpful Answer Positive Rating
could you show me a diagram how to connect the servo to the PIC877A?.. im actually using MPLAB for compiling and i guess i have the stuff needed for this.. could i also have the source code of this hex file so that i could customize or edit it in a way if i would like to change positions of angles. thanks!!!
 

Hi,

Files below ..
 

Attachments

  • servo1.rar
    131.4 KB · Views: 135
  • Like
Reactions: bogusmeister

    bogusmeister

    Points: 2
    Helpful Answer Positive Rating
    V

    Points: 2
    Helpful Answer Positive Rating
thank you very much. by the way what do you mean by connect a 100nF caps. across pin 31 & 32? its not shown in the figure.. and how do i compute the delay for a specific angle that i want?.. again thank you..
 

The normal throw for a servo is regarded as 180 degrees. With futaba, at the centre ie 90 degrees the pulse is 1.5ms and the 2 extremes 1ms & 2ms. There are some servos where the centre is 1.52ms, but this should not cause you any problems using the figures above. Using these figures you should be able to calculate the pulse time to angle.

1/180= 0.0055555555555556

Therefore each degree swing is approx 0.00555 * no of degrees + 1ms. (depending how many decimal places you wish to goto)



90 degrees = 90 * 0.00555 approx = 0.4995 + 1 = 1.4995ms (1.5ms centre)
 
Last edited:

    V

    Points: 2
    Helpful Answer Positive Rating
The normal throw for a servo is regarded as 180 degrees. With futaba, at the centre ie 90 degrees the pulse is 1.5ms and the 2 extremes 1ms & 2ms. There are some servos where the centre is 1.52ms, but this should not cause you any problems using the figures above. Using these figures you should be able to calculate the pulse time to angle.

1/180= 0.0055555555555556

Therefore each degree swing is approx 0.00555 * no of degrees + 1ms. (depending how many decimal places you wish to goto)



90 degrees = 90 * 0.00555 approx = 0.4995 + 1 = 1.4995ms (1.5ms centre)


oh i see.. and by the way im using a hobby servo for this.. i should be able to get this now. how about the speed? how will i control it? thanks!!!
 

what do you mean by connect a 100nF caps. across pin 31 & 32? its not shown in the figure.. y

Hi,

Connect one pin of the 100nf cap to Pic pin 32 and the other to pin 31 .
Its an important suppressor for the +5v rail.
 

    V

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top