adafruit/Adafruit-PWM-Servo-Driver-Library

setServoPulse method in servo.ino has math error

captainnibbles opened this issue · 0 comments

Does the ServoPulse method in servo.ino have an error of a factor of 1000? According to the comment, the input is expected in Seconds (which is an odd expectation, given that servos are specced in ms (microseconds))

`// you can use this function if you'd like to set the pulse length in seconds
// e.g. setServoPulse(0, 0.001) is a ~1 millisecond pulse width. its not precise!
void setServoPulse(uint8_t n, double pulse) {
double pulselength;

pulselength = 1000000; // 1,000,000 us per second
pulselength /= 60; // 60 Hz
Serial.print(pulselength); Serial.println(" us per period");
pulselength /= 4096; // 12 bits of resolution
Serial.print(pulselength); Serial.println(" us per bit");
pulse *= 1000;
pulse /= pulselength;
Serial.println(pulse);
pwm.setPWM(n, 0, pulse);
}`

First of all, the method has 60Hz hard coded in (why?), so pulselength = (1,000,000 us / 60 * 4096) = 4.069010416666667, meaning pulselength is about 4 _micro_seconds. Great so far, not sure why we are using microseconds, but sure. Now we read in our pulse. Per the example comment, lets say it is 1 _milli_second, so the value of the parameter is .001

Now (pulse * 1000)/pulselength = .001 * 1000 / 4.069010416666667 = 0.24576

Our pulse for pwm.setPWM(n, 0, pulse) is less than one unit of our 4096? Wouldnt this round to 0, meaning no pulse time? My understanding, and the rest of the example indicate that the pulse time should be a few hundred units. This forum post here is how I understand the timing. https://forums.adafruit.com/viewtopic.php?f=50&t=103718#p519073

According to that formula, each period of a 60Hz cycle is 1000/60ms, so 16.6667ms. We want our pulse to be 1ms of each of these 16.6667ms cycles, which are broken into 4096 segments, thus (1/16.666)*4096 = 245.7609830439322, exactly 1000 times the value given by the algorithm, and well within the seeming range listed in the rest of the sketch.