Pages: [1] 2 3   Go Down
Author Topic: Servo Library  (Read 1716 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Full Member
***
Karma: 0
Posts: 203
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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()
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 203
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

And here it is... Control of two servos implemented entirely in the timer1 hardware.
http://www.arduino.cc/playground/ComponentLib/Servotimer1

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.
Logged

Netherlands
Offline Offline
Sr. Member
****
Karma: 0
Posts: 414
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Awesome, thanks for making this available!

Now how to find some time to start playing with this  :smiley
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 203
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks! That fixes it.
Logged

Daniel
Guest
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey jims,

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

D

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()':
« Last Edit: June 14, 2007, 03:04:09 am by Daniel » Logged

Daniel
Guest
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok,

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:
#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()':

D
« Last Edit: June 14, 2007, 03:05:11 am by Daniel » Logged

Forum Administrator
Cambridge, MA
Offline Offline
Faraday Member
*****
Karma: 12
Posts: 3538
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You need to use ServoTimer1 instead of Servo.
Logged

Daniel
Guest
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks!

D
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Canada
Offline Offline
Jr. Member
**
Karma: 0
Posts: 76
I Love Arduino!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Tom
Logged

Thomas Ouellet Fredericks

Brooklyn, NY, USA
Offline Offline
Full Member
***
Karma: 0
Posts: 115
arduino for all
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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. smiley
Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: January 04, 2008, 09:48:03 pm by mem » Logged

0
Offline Offline
God Member
*****
Karma: 0
Posts: 507
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Pages: [1] 2 3   Go Up
Jump to: