Puzzling Servo Angle Values


#1

According to the documentation, my servo should have an angle value range of 0 to 180 degrees. However, after experimenting, I found that my servo doesn’t use the standard angle measure system. It has a starting angle value of around 40 degrees and can achieve 180 degree motion within 100 degrees. Is my servo defective? If so, is there any way to correct this without resorting to angle unit conversion? Thanks


#2

Could you paste your code about the servo??


#3
#include <Me_BaseShield.h>
#include <Me_ServoDriver.h>
#include <Me_InfraredReceiver.h>
#include <Servo.h>

Me_BaseShield baseShield;
Me_InfraredReceiver infraredReceiver;// use ME_PORT_4 in default
Me_ServoDriver servoDriver(PORT_2);//can ONLY be PORT_1,PORT_2

void setup()
{
    // initialize serial communication with computer:
    Serial.begin(9600);
    // initialize Infrared Receiver:
    infraredReceiver.begin();
    servoDriver.Servo1_begin();
    Serial.println("Start!");
}

void loop()
{
    int key = infraredReceiver.read();
    if(key>=0)
    {
        Serial.println(key);
        switch (key)
        {
            case IR_PLUS_BUTTON:servoplus();break;
            case IR_TEST_BUTTON:reset45();break;
            case IR_RETURN_BUTTON:reset135();break;
            case IR_PREVIOUS_BUTTON:reset0();break;
            case IR_NEXT_BUTTON:reset180();break;
            case IR_MINUS_BUTTON:servominus();break;
            case IR_PLAY_BUTTON:reset90();break;
            default:break;
        }
    }
}

void reset0()
{
    servoDriver.writeServo1(30);
    delay(1000);
}

void reset180()
{
    servoDriver.writeServo1(150);
    delay(1000);
}

void reset90()
{
    servoDriver.writeServo1(90);
    delay(1000);
}

void reset45()
{
    servoDriver.writeServo1(60);
    delay(1000);
}

void reset135()
{
    servoDriver.writeServo1(120);
    delay(1000);
}

void servoplus()
{
    servoDriver.writeServo1(servoDriver.readServo1()+5);
    delay(1000);
}

void servominus()
{
    servoDriver.writeServo1(servoDriver.readServo1()-5);
    delay(1000);
}

#4

Finaly, we find the reason of the issue.

The Makeblock DIGITAL SERVO is controlled by sending it pulses ranging from 1ms to 2ms in duration, Pulse-width modulation (PWM), at 50Hz (50 pilses per second) or more.It means that a 1.5ms pulse will center a servo at 90deg, a 1ms pulse will move the servo to 0deg and a 2ms pulse will move the servo to 180deg. (See in following picture)

In MeServoDriver libraby, we use Arduino default servo library (#include <Servo.h>), but in Arduino default servo library the servo is controlled by sending it pulses ranging from 0.5ms to 2.5ms in duration. So if you want to solve this issue, find the “Servo.h” in Arduino IDE folder and open it. In the code you may see the default MIN_PULSE_WIDTH is defined as 544 and the default MAX_PULSE_WIDTH is defined as 2400. See in following code:

#define MIN_PULSE_WIDTH    544
#define MAX_PULSE_WIDTH    2400

Replace the value of the MIN_PULSE_WIDTH as 1000 and the value of the MIN_PULSE_WIDTH as 2000:

#define MIN_PULSE_WIDTH    1000
#define MAX_PULSE_WIDTH    2000

If the Servo Angle Values are still not correct exactly, you can change the vaule of the MIN_PULSE_WIDTH and the value of the MAX_PULSE_WIDTH a bit. Maybe 960 for MIN_PULSE_WIDTH and 2040 for MAX_PULSE_WIDTH is more useful according to my test.

This is a bug in our Me_ServoDriver libraby, so sorry about that. And we will make a new library of this soon. Thank you for your feedback. If you still have any questions about our products, contact with us, and we will hlep you to solve it as soon as possible.

Thank you so much!


#5

We have uploaded the document of Makeblock DIGITAL SERVO Specifications. You can download it in the Download page and see more details about our servo


#6