I found a bug in the Servo library in 1.0 (and it's probably been there for a
while):
In libraries/Servo/Servo.cpp:
Code:
90 else {
91 // finished all channels so wait for the refresh period to expire before starting over
92 if( (unsigned)*TCNTn < (usToTicks(REFRESH_INTERVAL) + 4) ) // allow a few ticks to ensure the next OCR1A not missed
93 *OCRnA = (unsigned int)usToTicks(REFRESH_INTERVAL);
94 else
95 *OCRnA = *TCNTn + 4; // at least REFRESH_INTERVAL has elapsed
96 Channel[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel
97 }
The "+4" on line 92 should be on the other side of the inequality, OR it should
be a "-4" instead. As it is, there is a 4-8 microsecond interval during which
the logic in the library will set OCR1A to a value that it has just missed, and
it has to go all the way around to pick it up.
The comment says "allow a few ticks" but it actually dis-allows those ticks.
Think of the logic: If TCNT1 is the refresh interval plus one (clearly, already
too late,) then this if statement will still allow the code to set OCR1A to the
refresh interval.
So, if your servos sometimes twitch, or sometimes take longer to respond than
they should (but only when you use a few, with some particular set of control
values,) then this would be the reason.
I also reported this in the forums:
http://arduino.cc/forum/index.php/topic,104459.0.html
Original issue reported on code.google.com by jwa...@gmail.com on 6 May 2012 at 7:00
Original issue reported on code.google.com by
jwa...@gmail.com
on 6 May 2012 at 7:00