12f629 and a servo

Electronics Computer Programming Q&A
Post Reply
psycho
Posts: 388
Joined: Thu Jan 10, 2008 8:13 pm
Location: Northwest Indiana
Contact:

12f629 and a servo

Post by psycho » Thu Jan 10, 2008 8:46 pm

Hi all,
I have a project which should be very basic. I need to move a servo from the rightmost extreme to the leftmost extreme. Pic is @ 4MHz. I have written a program in mikroPascal which will do this :

program ServoControl;
Procedure Pulseout(time : word);
begin
SetBit(GPIO, 2);
delay_cyc(time); // delays time * 10 cycles
ClearBit(GPIO, 2);
end;

var
b : byte;

begin
TRISIO := %0000000;
CMCON := $07;

// Pulseout(25); // set servo to right
// delay_ms(5000); // wait for servo to react

repeat
//pulseout(225); // leftmost position
//pulseout(25); // rightmost position

for b := 25 to 225 do
begin
Pulseout(b);
delay_ms(90);
end;

SetBit(GPIO, 0);

for b := 225 downto 25 do
begin
Pulseout(b);
delay_ms(90);
end;

ClearBit(GPIO, 0);
until true = false;
end.

This works, but... I need more servo resolution than the 200 steps that are available. I am thinking of using asm instead of pascal but, I know nothing about it :(

What I need is for the servo to start out on the right and go to the left in the smallest possible steps. And, it needs to take approx 3 mins to go all the way. The 3 minutes is fine in the above pgm but, the resolution is such that the servo looks like a second hand ticking on a clock. If I were to use asm, would I be able to get better resolution out of a hitec hs-81?

btw, this is going to be used in a play as an old time elevator floor pointer. I guess the premiss is that the elevator goes up as the kids dance to some song (3 mins or whatever).


Thanks a million,
Kevin

User avatar
jaem
Posts: 148
Joined: Thu Feb 15, 2007 3:36 pm
Location: BC, Canada
Contact:

Post by jaem » Thu Jan 10, 2008 9:26 pm

sorry to kind of hijack the thread, but is mikroPascal free? I couldn't find a decent compiler for PICs...

psycho
Posts: 388
Joined: Thu Jan 10, 2008 8:13 pm
Location: Northwest Indiana
Contact:

Post by psycho » Thu Jan 10, 2008 9:45 pm

no. but, there are free versions. They (mikroElectronika) make mikroBasic, mikroC, & mikroPascal. They are nice and you can check them out at http://www.mikroe.com - I like their EasyPic dev boards!

Hope you like it :)
Kevin

hlreed
Posts: 349
Joined: Wed Jan 09, 2002 1:01 am
Location: Richmond, TX
Contact:

Assembly servo for 12f675

Post by hlreed » Fri Jan 11, 2008 10:01 am

; 08/30/03 program for SMNodes Version
; Copyright 2003 Harold L. Reed
; Use TNode board
; Integer -> Timed pulse for servo
; Out = pulse cycle
; Node is:
; 4 Mhz is Megacycles/sec 4000000
; 4 clock cycles per pic code line.
; 1 Microsecond/cycle .0000001 sec/cycle
; 1 millisecond = .001 sec = 1000 cycles
; Vcount for variable time
; Servo is: In comp
; 1 millisecond puts servo full CCW input = -128 0
; 1.5 millisecond puts servo at center input = 0 128
; 2 milliseconds puts servo full CW input = 127 255
; Wait 20 milliseconds for next cycle.
; Rule is:
;loop
; turn on pulse
; By default produce 1.0 ms
; I produces up to 1.0 ms 5 cc = 1 int = .005 ms
; turn off pulse 1000 cc = 200 int = 1.00 ms
; wait 20 ms cc = int*5 = ms*0.001
; goto loop
; I pulse hex
; -100 1 ms 9C
; -99 1.005 ms 9D
; 0 1.5 ms 0
; 1 1.505 ms 1
; 100 2 ms 64
; Begin SMNode
LIST p=12F629, w=1
; Constants
CTime EQU D'32' ;feeds CCount makes 100
DTime EQU D'10' ;10 Decade
DVTime EQU D'5' ;5 VCount = 5*In
BigTime EQU D'19' ;19 was 20, now incl inp
moff EQU 80h ;-128
;
IC EQU 05h ;input port pins
ID EQU 04h
;
OD EQU 00h ;pulse pin
; registers
; Bank 0
STATUS EQU 03h
GPIO EQU 05h
INTCON EQU 0Bh
PIR1 EQU 0Ch
TICON EQU 10h
CMCON EQU 19h
ADRESH EQU 1Eh
ADCON EQU 1Fh
;
; Bank 1
OPTIONR EQU 81h
TRISIO EQU 85h
PIE1 EQU 8Ch
PCON EQU 8Eh
OSCCAL EQU 90h
WPU EQU 95h
IOC EQU 96h
VRCON EQU 99h
EEDATA EQU 9Ah
EEADR EQU 9Bh
EECON1 EQU 9Ch
EECON2 EQU 9Dh
ADRESL EQU 9Eh
ANSEL EQU 9Fh
; Variables
I EQU 020h ;Raw input variable
TCount EQU 021h ;20 ms counter
BigCount EQU 022h ;20 ms inner count
D EQU 023h ;bit count
TT EQU 024h ;input timer
;
CCount EQU 025h ;1 ms counter var
Decade EQU 026h ;decade count var
VCount EQU 027h ;variable counter var
VarConst EQU 028h ;Const for variable count
;
ORG 00h
BCF STATUS,5 ;bank0
CLRF GPIO
MOVLW 07h
MOVWF CMCON ;comparator off
CLRF PIR1
CLRF TICON
;
BSF STATUS,5 ;bank1
CALL 3FFh ;get calibration
MOVWF OSCCAL ;set it
; do bank1 init
CLRF OPTIONR ;option
CLRF PIE1
CLRF PCON
CLRF WPU ;Disable weak pullups
CLRF IOC ;dissable interrupt on change
CLRF VRCON
; set IO
MOVLW 3Ch ;5,4,3,2 in 1,0 out
MOVWF TRISIO
;
BCF STATUS,5 ;bank 0
CLRF GPIO
;
Loop
; 08/21/03
;------------------------------------------
; I input for TNodes, SMNodes, MoNodes
ReadI
;Find start
MOVLW 04h ;4, 9, 18
MOVWF TT ;bit, halfword, whole word
CI
BTFSC GPIO,IC ;1 look at IC
GOTO ReadI ;2 is on
DECFSZ TT ;3
GOTO CI ;4 5*TT
; found start, read the word.
CLRF D ;start with bit 0
CLRF TT ;
BCF STATUS,0 ;
I1
BTFSC GPIO,IC ;0 bit Low?
GOTO RDIBit ;1 no, is high, go read
DECFSZ TT ;2 yes, time it
GOTO I1 ;3 try again
GOTO GotI ; give up
; read bit
RDIBit
BTFSS GPIO,ID ;2 yes, test bit
GOTO ZeroI ;3 is zero
BSF I,7 ;4 is one, move it to I
GOTO ComI ;5
ZeroI
BCF I,7 ;4 move bit to I
NOP ;5
; bit read.
ComI
INCF D ;7 next bit
BTFSC D,3 ;8 bits done?
GOTO GotI ;9
BCF STATUS,0 ;10
RRF I,1 ;11
GOTO I1 ;11 Do until bits are done
GotI
;----------------------------------------------------
;
; Begin SMNode function
;
MOVLW moff ; W = moff,make it offset
ADDWF I,1 ; I = I + W ,0 to 255
MOVF I,W ; W = I
MOVWF VCount ; VCount = W, variable count
; Do servo pulse
MOVLW DTime ; W = DTime
MOVWF Decade ; Decade = W
; Servo Pulse starts /----------------------------\
BSF GPIO,OD ; OD = 1, set pulse on
;
; Do 1 millisecond count for full CCW 1000 count
MOVLW DTime ; W = DTime, set up counters
MOVWF Decade ; Decade = W
BL1
MOVLW CTime ; W = CTime
MOVWF CCount ; CCount = W
MS1
DECFSZ CCount,1 ; CCount = CCount - 1, .000001 seconds
GOTO MS1 ; MS = 2*CCount
DECFSZ Decade,1 ; Decade = Decade - 1
GOTO BL1 ; BL = 5*Decade*MS
; 1000 = 2*CCount*5*Decade = 2*10*5*10 is 1.01 ms
;
; Variable time starts
; 1000 = 256*3.906 = In*3.906 (250*4 = 1000)
; Servo counts integer offset
; CCW 0 counts -128 0
; 0 500 counts 0 128
; CW 1000 counts 127 255
;
VarCount
MOVF VCount,W ; W = VCount
BTFSC STATUS,2 ; is VCount = 0?
GOTO done ; [yes], exit
VS
NOP ; [no]
DECFSZ VCount,1 ; VCount = VCount - 1
GOTO VS ; = 4*VCount
done
BCF GPIO,OD ; Pulse off -------\
; Pulse off. Start 20 millisecond cycle - 2
; 20 milliseconds requires 200000 cycles
; Do 20 ms off cycle do 1 ms 20 times
;
MOVLW BigTime ; W = BigTime
MOVWF BigCount ; BigCount = W
; 1 ms start
ML20
MOVLW DTime ; W = DTime
MOVWF Decade ; Decade = W
BL2
MOVLW CTime ; W = CTime
MOVWF CCount ; CCount = W ,makes 100
MS2
DECFSZ CCount,1 ; CCount = CCount - 1
GOTO MS2 ;
DECFSZ Decade,1 ; Decade = Decade - 1
GOTO BL2 ;
; 1 ms stop
DECFSZ BigCount,1 ; BigCount = BigCount - 1
GOTO ML20 ;20*1ms
;
; End SMNode function
;
GOTO Loop ;
;
; End SMNode
END
Harold L. Reed
Microbes got brains

psycho
Posts: 388
Joined: Thu Jan 10, 2008 8:13 pm
Location: Northwest Indiana
Contact:

Post by psycho » Fri Jan 11, 2008 2:19 pm

I fired up the above code and, it "jitters" the servo, but, could you explain what it is supposed to do?

tnx,
kevin

hlreed
Posts: 349
Joined: Wed Jan 09, 2002 1:01 am
Location: Richmond, TX
Contact:

Post by hlreed » Sat Jan 12, 2008 7:31 am

; This is the servo code. Servo is connected to pin 4
; If you can replace your proceedure with this it might work
; Begin SMNode function
;
MOVLW moff ; W = moff,make it offset
ADDWF I,1 ; I = I + W ,0 to 255
MOVF I,W ; W = I
MOVWF VCount ; VCount = W, variable count
; Do servo pulse
MOVLW DTime ; W = DTime
MOVWF Decade ; Decade = W
; Servo Pulse starts /----------------------------\
BSF GPIO,OD ; OD = 1, set pulse on
;
; Do 1 millisecond count for full CCW 1000 count
MOVLW DTime ; W = DTime, set up counters
MOVWF Decade ; Decade = W
BL1
MOVLW CTime ; W = CTime
MOVWF CCount ; CCount = W
MS1
DECFSZ CCount,1 ; CCount = CCount - 1, .000001 seconds
GOTO MS1 ; MS = 2*CCount
DECFSZ Decade,1 ; Decade = Decade - 1
GOTO BL1 ; BL = 5*Decade*MS
; 1000 = 2*CCount*5*Decade = 2*10*5*10 is 1.01 ms
;
; Variable time starts
; 1000 = 256*3.906 = In*3.906 (250*4 = 1000)
; Servo counts integer offset
; CCW 0 counts -128 0
; 0 500 counts 0 128
; CW 1000 counts 127 255
;
VarCount
MOVF VCount,W ; W = VCount
BTFSC STATUS,2 ; is VCount = 0?
GOTO done ; [yes], exit
VS
NOP ; [no]
DECFSZ VCount,1 ; VCount = VCount - 1
GOTO VS ; = 4*VCount
done
BCF GPIO,OD ; Pulse off -------\
; Pulse off. Start 20 millisecond cycle - 2
; 20 milliseconds requires 200000 cycles
; Do 20 ms off cycle do 1 ms 20 times
;
MOVLW BigTime ; W = BigTime
MOVWF BigCount ; BigCount = W
; 1 ms start
ML20
MOVLW DTime ; W = DTime
MOVWF Decade ; Decade = W
BL2
MOVLW CTime ; W = CTime
MOVWF CCount ; CCount = W ,makes 100
MS2
DECFSZ CCount,1 ; CCount = CCount - 1
GOTO MS2 ;
DECFSZ Decade,1 ; Decade = Decade - 1
GOTO BL2 ;
; 1 ms stop
DECFSZ BigCount,1 ; BigCount = BigCount - 1
GOTO ML20 ;20*1ms
;
; End SMNode function
;
Harold L. Reed
Microbes got brains

User avatar
philba
Posts: 2050
Joined: Tue Nov 30, 2004 1:01 am
Location: Seattle
Contact:

Post by philba » Wed Feb 13, 2008 8:49 am

would people PLEASE PLEASE use the code option to post source code. That assembler code is frickin unreadable when it's posted that way. I generally don't bother to read it if the poster hasn't taken the 2 extra seconds to make iit readable.

Yes, I'm cranky this morning.

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests