code8825 / arduino

Automatically exported from code.google.com/p/arduino
Other
0 stars 0 forks source link

Bug in Servo library #908

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
Good catch!

https://github.com/arduino/Arduino/commit/71e9ff63f8ae3ede963cda5b16c63816128950
f9

Original comment by dmel...@gmail.com on 9 May 2012 at 12:42