Searching \ for '[PIC] Simple Servo Code' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/ios.htm?key=servo
Search entire site for: 'Simple Servo Code'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] Simple Servo Code'
2002\08\09@185915 by Nick Stedman

flavicon
face
Hello,

I'm seeking some code to drive a hobby servo. I understand the principle of
the servo. What's relatively new to me is Assembly. All the stuff I've found
on the web is for driving 4 to 12 servos with serial input and all these
other bells and whistles...the code makes my head spin (some programs are
over 20 pages!). So if anyone has a very simple program or routine I can
look at to understand how to hook up a servo to a pic, it would much
appreciated.
Cheers
Nick

--
http://www.piclist.com hint: To leave the PICList
spam_OUTpiclist-unsubscribe-requestTakeThisOuTspammitvma.mit.edu


2002\08\09@202853 by Pic Dude

flavicon
face
If you reduce the font size, you can shrink the
code to much less than 20 pages.  :-)

Seriously though, perhaps this may be smaller code
than what you have...
       http://www.botkin.org/dale/servo_tester.htm

Courtesy of Dale Botkin when I asked a similar
question some weeks back.

Cheers,
-Neil.




> {Original Message removed}

2002\08\09@232029 by John Dammeyer

flavicon
face
Bad programming practice.

void main() {

 init hardware.

 Do the test code.

 main();
}


Better to do it this way:

void main() {

 init hardware.

 while ( 1 ) do {
       Do the test code.
 }
}


John Dammeyer


Wireless CAN with the CANRF module.
www.autoartisans.com/documents/canrf_prod_announcement.pdf
Automation Artisans Inc.
Ph. 1 250 544 4950


> {Original Message removed}

2002\08\09@233451 by Dale Botkin

flavicon
face
Yeah, it's messy all right.  That was the very first program I ever wrote
in C, as I was teaching myself how.  I'd have yanked it from the web site
long ago, but people keep asking for it.

Dale
---
We are Dyslexia of Borg.
Fusistance is retile.
Your ass will be laminated.

On Fri, 9 Aug 2002, John Dammeyer wrote:

{Quote hidden}

> > {Original Message removed}

2002\08\17@164649 by Jeff Mann

flavicon
face
Nick Stedman wrote:
> Hello,
>
> I'm seeking some code to drive a hobby servo. I understand the
principle of
> the servo. What's relatively new to me is Assembly. All the stuff
I've found
> on the web is for driving 4 to 12 servos with serial input and all these
> other bells and whistles...the code makes my head spin (some programs are
> over 20 pages!). So if anyone has a very simple program or routine I can
> look at to understand how to hook up a servo to a pic, it would much
> appreciated.
> Cheers
> Nick
>


Hi Nick -

Did you get any help with this?

What else does your PIC have to do, other than driving the servo?

One approach would be to use the PicBasic Pro compiler at InterAccess,
which is a lot easier than assembler, and use the PULSOUT command.

On the other hand, there are lots of good reasons to learn assembler.

The basic problem is how to time the servo pulse output. You set the
output pin high (eg. BSF PORTA,0), then wait for somewhere between
1-2ms, then set it low again. Then you wait a while, around 20ms (this
time doesn't need to be very accurate), and do it again.

You can use a software loop to do the timing - you calculate how long
each instruction takes, based on the clock speed, and then run through a
loop of a few instructions that do nothing, enough times to make up the
amount of time you need. This is what the PULSOUT command of the Stamp
or PicBasic does. But PULSOUT does all the calculations for you - you
just tell it how many microseconds you want. With assembler, you have to
calculate it all yourself. Luckily, there are lots of examples of timing
(delay) routines around that can make it easier - check piclist.org

The drawback to this is that you can't really do anything else while
you're executing the timing loop (there are tricks with putting real
code into the timing loop, but that can get complicated). A better
approach is to use a hardware timer on the PIC - this is a handy thing
to learn how to do. A reasonably straightforward approach would be to
use the 8-bit timer, Timer 0, which can count up to 255. Using 8-bit
values make the assembly coding much easier.

You configure timer 0 using the OPTION register; set it to run from the
internal clock, which is 1/4 of the crystal frequency. With a 4MHz
crystal, the internal clock is 1MHz, i.e. 1us per tick.

This is going to be too fast; the timer could only run for 256us. So you
use the Prescaler to set a 1:8 ratio with the internal clock, giving the
timer a period of 8us per timer tick. 256 x 8us = 2048us, or about 2ms.

To time the pulse, you add 128 (for the minimum 1ms pulse) plus some
value between 0 and 127 which determines the servo position. For
example, to centre the servo you would add 64: 128 + 64 = 192; 192 * 8us
= 1.5ms. Since the timer counts up to 255, you subtract this number from
255 and load it into the counter: 255 - 192 = 63; the timer would start
counting at 63 and count for 192 ticks up to 255.

When the timer times out (rolls over 255 to 0) a flag is set in the
INTCON register, and an (optional) interrupt is generated. Either you
can keep checking the flag regularly during the rest of your program or,
better, use an interrupt handling routine. Interrupts are also a really
good thing to learn how to use.

After you've sent the pulse, you'd then set the timer to 0 (2ms) and run
it nine or ten times (18-20ms delay), then send another pulse.

The code, using interrupts, would go something like this:

main code:
set up variables, pin definitions, etc.
set up OPTION register for timer 0 for internal clock, 1:8 prescaler

put initial 0-127 target position of the servo, eg. 64 into a variable
clear and enable timer 0, with interrupts
call startPulse subroutine
loop:
   calculate new target position, based on ???
   save it in the target variable
   do something else if you want
   goto loop

startPulse subroutine:
add 128 to target value variable
subtract this number from 255 (the timer counts up to 255)
load the result into the timer
set the pin high
return

interrupt code: (the timer has timed out)
clear the interrupt flag
is the pin high?
if so: (this is the end of the pulse)
  set the pin low - turn off pulse
  set the delay counter variable to 0 - ready to count 20ms delay
  load 0 into the timer - set to 2ms timeout
  return from interrupt
if not: (this is one of the 2ms delay timeouts)
  is the delay counter variable = 9?
  if so: (have delayed for 9x2ms - 18ms delay)
      set the delay counter variable to 0
      call startPulse
      return from interrupt
  if not:
      increment the delay counter variable
      return from interrupt

This is only one approach, and it gives you only 127 positions on the
servo. If you want to get more complicated, you could run the timer at
1:4, and do the pulse in two parts, a 1ms initial pulse plus an 8-bit
variable pulse. Otherwise, you could also use the 16-bit timer, timer 1.

Hope this helps... <Jeff

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


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