Go Down

Topic: Servo Library (Read 4080 times) previous topic - next topic


I've just uploaded a new servo library to the playground http://www.arduino.cc/playground/ComponentLib/Servo. It matches (mostly) the wiring.org api http://wiring.org.co/reference/libraries/Servo/index.html.

New and different things about this library:
  • It supports an arbitrary number of servos.
  • It does not block interrupts and lose millis().
  • It has around 4 microseconds of jitter on the pulses and a pulse can be extended by the length of your interrupt handlers (not cumulative, just however many hit in the couple of microseconds between the off time and when it manages to make the pin off call.)
  • You can adjust the servo pulse length for the 0 and 180 degree points on a per servo basis to tune for your servos. It comes set to about 500uS to 2400uS which matches the HS-311 units I tested with.
  • You must periodically call the Servo::refresh() method to keep your pulses coming.

Next in my suite of servo libraries will be the small hardware servo library that only works on pins 9 and 10, but does not jitter, is immune to interrupts, and does not require a call to Servo::refresh()


And here it is... Control of two servos implemented entirely in the timer1 hardware.

I'd choose this one over the software version unless I needed PWM outs on 9 and 10 or more than two servos. It is smaller, faster, and produces rock solid servo pulses.


Awesome, thanks for making this available!

Now how to find some time to start playing with this  ::)


Hi - I was delighted to discover this library! Unfortunately, I have just tried to install ServoTimer1 and received the following error building the library. Anything simple I should do to fix?

ServoTimer1.cpp: In static member function 'static void ServoTimer1::seizeTimer1()':
ServoTimer1.cpp:39: error: 'clockCyclesPerMicrosecond' was not declared in this scope
ServoTimer1.cpp: In member function 'void ServoTimer1::write(int)':
ServoTimer1.cpp:117: error: 'clockCyclesPerMicrosecond' was not declared in this scope


You need to add a
Code: [Select]
#define clockCyclesPerMicrosecond() 16
until the next version of the IDE comes out.


Thanks! That fixes it.


Jun 14, 2007, 08:28 am Last Edit: Jun 14, 2007, 10:04 am by Daniel Reason: 1
Hey jims,

I just tried the ServoTimer1 library in Arduino 008, but I get the following error... any ideas?


ServoTimer1.cpp: In static member function 'static void ServoTimer1::seizeTimer1()':
ServoTimer1.cpp:43: error: 'TICIE1' was not declared in this scope
error: 'Servo' does not name a type In function 'void setup()':
In function 'void loop()':


Jun 14, 2007, 09:50 am Last Edit: Jun 14, 2007, 10:05 am by Daniel Reason: 1

Looking at the datasheet(s) for both the Atmega 8 and atmega16, I think the error is partially coming from the fact that the register bit "TICIE1" does not exist in the Atmega168.

Changing lines 42-43 to this lets Arduino build the library:
Code: [Select]
#if defined(__AVR_ATmega168__)
   TIMSK0 &= ~( _BV(OCIE1A) | _BV(OCIE1B) | _BV(TOIE1) );

But I still get this:
error: 'Servo' does not name a type In function 'void setup()':



You need to use ServoTimer1 instead of Servo.



When I attempt to use both the Serial and SerialTimer1 library with the default example code, I get this:

Servo.cpp: In member function 'void Servo::write(int)':
Servo.cpp:52: error: 'clockCyclesPerMicrosecond' was not declared in this scope
o: In function `setup':
undefined reference to `ServoTimer1::attach(int)'o: In function `loop':
o: In function `__static_initialization_and_destruction_0':

I've tried all the suggestions above with no luck.


I did not like the limitations of a 0-180 value so I created my own spin off of the ServoTimer1 library called ServoTimeTime1.
The main difference is that the angle is set in microseconds instead of degrees for higher precision.

Get it here http://www.arduino.cc/playground/ComponentLib/Servotimetimer1

Thomas Ouellet Fredericks


I am here working with Björn Hartmann, who is adding servo support to Firmata.  His first implementation is based on the ServoTimer1 library, but we also don't like the 180 degree limitation.  There are some 360 degree servos out there, so we should support them.  I think degrees are a nicer unit to use, in combo with the setmin and setmax functions.  

Are there any servos that have a range bigger than 360?

Once this is worked out, I think this library would be quite useful as a standard Arduino library, included in the package.  Then we can use it in Firmata easily. :)


Jan 05, 2008, 03:46 am Last Edit: Jan 05, 2008, 03:48 am by mem Reason: 1
a problem with using degrees is that there is that there is no standard for how many degrees a servo will rotate for a given pulse width, its up to the servo manufacturer.

IMO, the library would be more useful if it takes a PulseWidth parameter (time in milliseconds) and the library included a function (could be a macro) that converts angle to PulseWidth for those applications that want to use degrees and don't mind any inaccuracy.

FWIW, my own code uses pulse width but also has a method that takes servo rotation as a percent (with the units in tenths of a percent). So passing 0 sends  the minimum pulse and 1000 sends the maximum. The actual pulse widths for minimum and maximum can be set using class methods as can the direction the servo rotates as the pulse width increases (again, no standard; some servos rotate clockwise as the pulse increases, others counter clockwise).  This implementation is useful to me but may not be intuitive for other users.


wait im getting confused on what code i need to put in, can somebody put in here what the whole code should look like, with daniels addition to fix ther tic thing, and j's addition to make it work, and i dont know why but in my compiler, it sais i have a stray # in the -># defineine sevrotimer thing...

thnks in advance

Go Up