Searching \ for '%What I am trying to do...%' in subject line. ()
Help us get a faster server
FAQ page: www.piclist.com/techref/index.htm?key=what+trying
Search entire site for: 'What I am trying to do...'.

_Sub string match.
'What I am trying to do...'
2000\05\16@161447 by

Hello all again-

I am starting to think I should just give up :)
Here is an extremely (hopefully) detailed explanation of what I am trying to
do:

---- Background information
A servo is a neat little device that is used in R.C. Cars, boats,
airplane... ect.  The position of the motor is determined by the duty cycle
of a 40 - 60 Hz pulse.  The servos that I have can turn a total of 180
degrees.  a pulse of 1 ms HIGH turns the servo fully one direction (0
degrees). 1.5 ms centers the servo at 90 degrees. 2 ms high turns the servo
to 180 degrees.  With this in mind I would like to create a small PIC
program that receives data either via parallel, or preferably serial
communication.  Based on the data given to it, the PIC should be able to
create a 40 Hz signal, with the length of pulse being between 1.00 - 2.00 ms
(with .01 ms increments).  This will give me 100 different positions to put
the servo..or 1.8 degrees apart.  Now this is my _VERY_ first project using
assembly, so if this is not a mailing list for beginners please let me know.
For hardware I am using a 16F84, and a 10.000 MHz ceramic resonator +/-
.05%

The biggest problem I am having is the timing.  I am not sure when to use
interrupts and when not to.  I can calculate how many TMR0 increases are
required to create a certain amount of time, but what is the best way to use
this information?  there are a number of possible option I have thought of
here they are:

Number 1

1) For N times... (however long we want to turn the servo for)
2) Set the servo control line HIGH
3) Delay for a certain amount of time using loops (1.00 - 2.00 ms).
4) Set the control line low
5) delay for a certain amount of time using loops (to make a 40 Hz signal)
1)

Number 2

1) For N times...
2)Set servo control line HIGH
3)Use TMR0 interrupts in some way to delay..
4) Set control line low...
5) Use TMR0 interrupts to create a delay that makes a 40Hz signal..
1)

The biggest thing for me is the accuracy.  I want to be able to get it as
close to 1.00 ms ,1.01 ms ,1.02 ms .. as possible.  Last night I decided
that I would teach myself assembly and I have come up with the following
code:

list    p=16f84
TMR0    EQU     0x01
OREG    EQU     0x81
PORTA   EQU     0x05
TRISA   EQU     0x85
STATUS  EQU     0x03
RP0     EQU     5
W       EQU     0

ORG     0x000                   ;Begin code at address 0

BEGIN   BSF     STATUS, RP0             ;Bank 1
MOVLW   b'11011000'             ;Store 0xE8 in W
MOVWF   OREG                    ;Setup Option Register
MOVLW     0                       ;Store 0 in W
MOVWF     TRISA                   ;Make PORTA outputs

;=============================================================
;Do loop stuff in here.
;In future.. add code to determine (perhaps interupt)
;To determine how to move servo (serial communication?)

LOOP    BSF     PORTA,1                 ;Turn LED on.
CLRF    TMR0                    ;Set Timer0 to 0

GOTO    LOOP

END

I know the code isn't much, but I started with assembly code about 18 hours
ago.  I have yet to find out how to use what would be equivalent to
"variables" in languages like C/C++.  I have looked at the servo code in the
archives, but it written in C...
If anyone could give any pointers in the right direction, suggestions on
books to by, snippets of sample code...  anything... it would be terribly
appreciated :)  I am but simple electrical engineering major in
university... and assembly is a little new to me.

Samuel

Search the archive (piclist.com) and you should find 1-instruction-time accurate
time delays.

If you are using a PIC with the CCP/PWM module, it can be done to 1uS with a
4MHz clock VERY easily.

Andy

The critical factor when driving servos is not the pulse frequency- the
important thing is pulse width.  Using TMR0 you can get the very accurate
pulse width you want- the frequency doesn't need to be as precise, though by
varying the frequency you will vary the "update" rate of the servo.  As long
as it is faster than, oh, about 20Hz, you won't notice it.

If you're just driving a single servo, use TMR0 to control the "high" time
of the servo cycle, and then do a simple loop- 40 Hz is a 25ms period, and
if your high time varies between 1 and 2ms, use TMR0 to control the 1-2ms
part, and then do a constant 24ms delay, which will make your pulse
frequency vary between 38 and 42 Hz, depending on servo position- you
probably won't notice.

I did a similar project on a 16F84 (no, the code isn't handy, in case anyone
was thinking of asking) that drove 2 servos for a camera pan/tilt head that
was controlled by a serial port.  Since the serial port had the most
critical timing (9600 baud), I used the timer and interrupts for doing the
bit-banged serial port, and then using simple counters, coded a dual servo
drive- worked pretty good, unless you happened to send serial information to
it when the servo pulse was high- it screwed up the servo counters, and this

{Original Message removed}
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

>I did a similar project on a 16F84 (no, the code isn't handy, in case anyone
>was thinking of asking) that drove 2 servos for a camera pan/tilt head that
>was controlled by a serial port.  Since the serial port had the most
>critical timing (9600 baud), I used the timer and interrupts for doing the
>bit-banged serial port, and then using simple counters, coded a dual servo
>drive- worked pretty good, unless you happened to send serial information to
>it when the servo pulse was high- it screwed up the servo counters, and this

I have this on an AVR8515 in a cooperative multitasker with eight servos,
(and a bunch of other stuff) and buffered serial I/O  You'd have to write
the part that takes the chars from the serial in buffer, and tells the
servos what position to go to. The rest is handled.

Rep rate isn't critical, and it sounds like more or less the same approach.
I have a 1mS opsys "tick" that controls the repetition rate. When it counts
to zero, then it allows the servos to be loaded. For each servo, I start a
servo pulse, and the timer with the width, and when the timer hits zero,
the ISR turns the servo pulse off, and points to the next servo. When all
eight have been done, then I reload the ram timer for the repetition rate,
and it all starts over.  The servo widths are stored in ram as proportional
values, 0-255 and the servo routines calculate the right pulse width per
servo, from defined min and max times (different brands want different widths)

- --
Are you an ISP?  Tired of spam?
http://www.spamwhack.com  A pre-emptive strike against spam!

Where's Dave? http://www.findu.com/cgi-bin/find.cgi?kc6ete-9

-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 6.5.2 for non-commercial use <http://www.pgp.com>

iQA/AwUBOSHPtIFlGDz1l6VWEQJrdgCfQgZ7ifaPU0YMG8wu+LTZMMIbM/IAoJPs
mymTI1dzP/bR1WoXkQXQ6r7k
=TBic
-----END PGP SIGNATURE-----

More... (looser matching)
- Last day of these posts
- In 2000 , 2001 only
- Today
- New search...