Go Down

Topic: Control a Servo -How? (Read 6849 times) previous topic - next topic

MovieMaker

I generally put something like:

PULSOUT RightServo, 850
Pause 2000

How would I do this in c ?

I just want to move a Servo to a certain spot and leave it there until it is required to move again.

Thanks!

retrolefty

The best way is to utilize the library routine designed to support servos. The MegaServo library is the most comprehensive one at the present time. It's located in the Arduino playground site and has the files to download, instructions on use and an example sketch.

http://www.arduino.cc/playground/Code/MegaServo

Lefty

MovieMaker


eried

#3
Aug 03, 2009, 06:10 pm Last Edit: Aug 03, 2009, 06:12 pm by eried Reason: 1
There is PulseOut in Arduino (Wiring) C. I don't like using a bloated library to control servos. The best way to control servos is directly with:

Code: [Select]
#define ANGLE_MIN -90
#define ANGLE_MAX 90
#define PWM_MIN 130
#define PWM_MAX 235


void rotate(int angle, int servo)
{
 analogWrite(servo,map(angle,ANGLE_MIN,ANGLE_MAX,PWM_MIN,PWM_MAX));
}


The servo must be connected to a digital PWM pin in your arduino. Angle and PWM values depends on your servo. To find the PWM value just try a high or lower value if the default does not work well.
My website: http://ried.cl

mem

eried, I think that advice is flawed.

According to the arduino documentation, the frequency of analogWrite is 490 Hz.  This is ten times higher than the recommended frequency for driving typical hobby servos. I would think that a hobby servo could be damaged by driving at with analogWrite, even if you do get the duty cycle to produce valid pulse widths.

One can get special servos  that can operate at higher frequencies, but these are not common and are more expensive then typical servos.

My advice is to stay well away from analogWrite and use the servo libraries unless you really know what you are doing and can be sure your servos can cope.

eried

you can adjust the pwm freq, but I have used the default configuration in several servos:

One 360º servo, no-brand that I buy in www.olimex.cl, 2 others 180º tamiya I think from Mirax.cl and in 7 other no-brand 180º ultra cheap servos from www.dealextreme.com

None of them failed or something "bad" happened. I will check at night the pwm output in my cheap chinese oscilloscope xD to investigate why, but it works very well. The last code that I pasted here, is from this robot: http://www.youtube.com/watch?v=VKftf8Ztisw (the direction servo is working until today, nearly a year after)

My website: http://ried.cl

mem

You may be lucky but others reading your advice will not thank you if their servos overheat because they are driven well beyond their intended operating range.

Running an analog servo at 500Hz is not something to be recommended.

You may want ask some of the experts on RCgroups what they think of that idea.
http://www.rcgroups.com/forums/showthread.php?t=755135

eried

I think you're wrong (or the arduino pwm reference, who knows). Check this out:



This is the reading of the pin 5 of my duemillanove:

Code: [Select]
void setup()
{
   analogWrite(5,100);
}

void loop()
{
}


Now check a servo pwm reference:



Notice that my oscilloscope is with a 20 ms sec/div
My website: http://ried.cl

MovieMaker

#8
Aug 04, 2009, 02:27 am Last Edit: Aug 04, 2009, 02:46 am by J.Smith Reason: 1
Thank You guys for your information. That is a Neat O'Scope!

Cool Robot~!

:-)

AWOL

#9
Aug 04, 2009, 09:26 am Last Edit: Aug 04, 2009, 10:39 am by AWOL Reason: 1
@eried:

"20Ms" on your scope display - is that a typo for "20ms" (milliseconds), or does it refer to the sample rate "20 Mega samples"?

I can believe that it's a 100/256 duty cycle being displayed, what I can't believe is that the PWM frequency is only 25Hz (or somewhat less), which is what is implied by your 20ms per division claim.

[EDIT] Also, from your scope trace, assuming 100/256, if a cycle is about 40ms long, 100* 40 / 256 = 15.6mS which is completely wrong for the 0.7 to 1.5ms you show for driving a servo in your diagram.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

mem

#10
Aug 04, 2009, 10:16 am Last Edit: Aug 04, 2009, 10:20 am by mem Reason: 1
The attached image is from a logic analyzer showing the output from the arduino servo library and analgoWrite.


The servo library trace is in red at the top and the analogWrite is orange. The servo pulse is around 1.5millisconds and repeats in 20 millisconds. The yellow bar marked A indicates the start of the next servo pulse.

The orange trace is from analogWrite on pin 5 and is completely outside the range that a normal servo expects.

These traces were made on an arduino Diecimila in version 0015 using the following sketch:
Code: [Select]
#include <Servo.h>

Servo servo1;  // create servo objects to control a servo

void setup()
{
   analogWrite(5,100);
   servo1.attach(9);
}

void loop()
{
}


Bottom line - don't use analogWrite to drive normal hobby servos!

eried

Its very very strange,

@AWOL: I believe that is 20 ms, http://www.jyetech.com/en/default.html

just take a look to the specs, 5 Msps, so it is unlike to offer 20 Msps as an option. In the manual it says "timebase per div" for that area, I think chinese does not know about upper/lower case xD.

If I zoom in I can see the small variations as mem suggests by the logic analyzer capture. I really don't know how can all my servos work nice with this pwm output if is so wrong.
My website: http://ried.cl

mem

#12
Aug 04, 2009, 12:12 pm Last Edit: Aug 04, 2009, 12:17 pm by mem Reason: 1
Are you sure you had the scope connected to pin 5 and were using an unmodified version of analogWrite to create the pulses. The picture of the trace you posted would indicate that the pulses are 20 milliseconds in duration repeating every 40 milliseconds or so. I would be surprised if any hobby servo would operate correctly on those pulses.

BTW, even if you modified analogWrite to create pulses that were within the design range  of a servo, the resolution on pin 5 would be terrible.  Except for pins 9 and 10 (as used by the Arduino servo library) analogWrite only has 256 steps within the duty cycle range of 0 to 100%.  1ms to 2ms every 20 ms requires a duty cyle range of around 10 percent. In other words, around 30 steps between 0 degrees and 180 degrees - The Arduino library has a precision 6 times better than that. And the MegaServo library is capable of 5 times more precision than the arduino library.

In summary, using analogWrite (on pins other then those used by the Arduino library) is less precise than the arduino Servo library and can potentially damage servos. Although it is interesting to read that your experiments have been successful for you, I strongly urge readers of this thread to stick with the libraries that were designed to drive servos.

eried

I am not saying that servos run with my demo sketch (that graphed in the scope), I will run more test with a running servo using both methods and the scope results
My website: http://ried.cl

mem

#14
Aug 04, 2009, 03:09 pm Last Edit: Aug 04, 2009, 03:11 pm by mem Reason: 1
Quote
I am not saying that servos run with my demo sketch (that graphed in the scope),

Why post a sketch and scope trace in a thread titled  'Control a Servo -How?' if its not relevant for controlling a servo?  

BTW, I was curious why the output on pin 5 in the trace I posted was twice the  published clock rate. (see the Arduino analogWrite reference : http://www.arduino.cc/en/Reference/AnalogWrite )

The reference says analogWrite frequency is approximately 490 Hz. This is correct for pins 3 and 11 (timer 2) and pins 9 and 10 (timer 1).

But  pins 5  and 6 use timer 0 and this outputs PWM at double this frequency which is why there are around 20 pulses on pin 5 in 20 millliseconds. This means that servos driven using analogWrite on pins 5 and 6 are actually being pulsed at around 1khz, twenty times higher then the recommended rate.

Can we agree that even if it may work with some servos, using analogWrite instead of one of the Servo libraries is not a good thing to do for those that want to drive servos within their design range.

Go Up