The existing servo rotation function looks like this: an integer value is used as the input. First, the function will make sure that this integer is between 0 and 180 since that is the scope of the servo rotation. Then this integer will be mapped into a value between SERVO_MIN() and SERVO_MAX(). Here is how the map() function work: assuming that y = map(x, 0, 180, SERVO_MIN, SERVO_MAX), then (x - 0)/(180 - x) = (y - SERVO_MIN)/(SERVO_MAX - y). This y will be used to drive the servo operation. Below is the existing function in the Arduino servo library:
void Servo::write(int value)
{
if(value < MIN_PULSE_WIDTH)
{ // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds)
if(value < 0) value = 0;
if(value > 180) value = 180;
value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX());
}
this->writeMicroseconds(value);
}
To make sub-degree rotation possible, we create a new function with floating-point number as input.
// To write angle in floating value /Nan Zhang
void Servo::writeFloat(float value)
{
if(value < MIN_PULSE_WIDTH)
{ // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds)
if(value < 0.0) value = 0.0;
if(value > 180.0) value = 180.0;
value = map((int) (value*10), 0, 1800, SERVO_MIN(), SERVO_MAX());
}
this->writeMicroseconds(value);
}
In this new function, we will first check whether this input is between 0.0 and 180.0. After that, the rounded value of (input*10) will be injected into the map function as map((int) (value*10), 0, 1800, SERVO_MIN(), SERVO_MAX()). Essentially, this makes the smallest achievable rotation to be 0.1 degree. You may want to further increase the granularity by doing things like map((int) (value*100), 0, 18000, SERVO_MIN(), SERVO_MAX()). But you will face physical limitation of how precise the servo can operate. For example, the default value for MAX and MIN are:
#define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo
#define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo
That means the best the device can do is (180)/(2400-544)=0.097 degree. Therefore, increasing granularity beyond 0.1 degree does not make sense for this servo device.
No comments:
Post a Comment