Go Down

Topic: [SOLVED] Use a servo motor with precision (Read 163 times) previous topic - next topic

iacoposk8

Jul 11, 2018, 08:45 pm Last Edit: Jul 14, 2018, 03:48 pm by iacoposk8
Hello everyone! I have a servomotor (mg996r) that I put on a goniometer (video example :D https://drive.google.com/open?id=1y83XvZb10X7m79iMCFHbqaGK0Rr9gdnH) and I saw that if I move it from 0 to 180 degrees, it actually has a 200 degree range.
So I thought to move it from 0 to 152 and it works, but if I then tell him to go to 76 in reality it goes to 92 and not to 90.
What is the most accurate way to handle this?
Code: [Select]


#include <Servo.h>
 
Servo myservo;

int servo_speed = 15;
int moveTO(Servo servo, int degree){
  int pos = servo.read();
  if(pos == degree){
    return pos;
  }
  if(pos < degree){
    for(; pos < degree; pos += 1)
    {
      servo.write(pos);
      delay(servo_speed);
    }
  } else {
    for(; pos >= degree; pos -= 1)
    {
      myservo.write(pos);
      delay(servo_speed);
    }
  }
  return pos;
}
 
void setup()
{
  myservo.attach(9);
  Serial.begin(9600);
}
 
void loop()
{
  moveTO(myservo, 76);
  delay(1000);
  moveTO(myservo, 152);
  delay(1000);
  moveTO(myservo, 0);
  delay(1000);
}

slipstick

Ordinary hobby servos really aren't very accurate. They always have a small dead band in the centre where a change in signal doesn't move the servo. So if you want accurate movements you'll need to calibrate it yourself for your particular servo. Even getting another servo of the same type won't necessarily move exactly the same.

Having said that if you use writeMicroseconds(pulselength) instead of write(angle) you will have finer control over the servo because the range you will use will be something like 800 to 2100 rather than the rather coarse 0 to 180.

Steve

FredScuttle

Try this test sketch with your servo, might help to map microseconds to degrees:
Code: [Select]
/*
 Try this test sketch with the Servo library to see how your
 servo responds to different settings, type a position
 (0 to 180) or if you type a number greater than 200 it will be
 interpreted as microseconds(544 to 2400), in the top of serial
 monitor and hit [ENTER], start at 90 (or 1472) and work your
 way toward zero (544) 5 degrees (or 50 micros) at a time, then
 toward 180 (2400).
*/
#include <Servo.h>
Servo servo;

void setup() {
  // initialize serial:
  Serial.begin(9600); //set serial monitor baud rate to match
  servo.write(90);
  servo.attach(9);
  prntIt();
}

void loop() {
  // if there's any serial available, read it:
  while (Serial.available() > 0) {

    // look for the next valid integer in the incoming serial stream:
    int pos = Serial.parseInt();
    pos = constrain(pos, 0, 2400);
    servo.write(pos);
    prntIt();
  }
}
void prntIt()
{
  Serial.print("  degrees = ");
  Serial.print(servo.read());
  Serial.print("\t");
  Serial.print("microseconds =  ");
  Serial.println(servo.readMicroseconds());
}

iacoposk8


Go Up