Skip to main content
Bumped by Community user
Bumped by Community user
Made my question more obvious.
Source Link
Tom Auger
  • 193
  • 1
  • 9

We all know servos don't move instantly, which is why it is common to put a delay or a millis() loop whenever you issue a servo.write() command to give it time to reach its target before moving on to the next thing.

What irks me though is that this could be inefficient in situations where the last servo position might be close to its target - you might only need a very short delay in those cases, whereas if it has to sweep the full 359 degrees, you might want more time.

I was disappointed that servo.read() is completely useless for this task (why even include it in the library?) as the following code illustrates:

#include <Adafruit_TiCoServo.h>
Adafruit_TiCoServo servo;
const uint8_t PIN_SERVO = 9;

void setup() {
  servo.attach(PIN_SERVO);
  Serial.begin(9600);


  Serial.println("start");
  servo.write(180);
  delay(1000);

  int pos;
  while(pos != 0){
    pos = servo.read();
    Serial.println(pos); // because it only returns what the last write() operation
                         // was sent, it immediately thinks it's at pos 0 and exits.
    servo.write(0);
  }

  Serial.println("Done");
}

So that sucks. It seems that my options are:

  1. just use a long delay that accommodates the worst-case scenario. I hate this.
  2. add a limit switch at the final target position and just read the state of that switch
  3. build some kind of elaborate encoder that you can read an absolute angle from or buy a more expensive servo that can tell you this info

Am I missing anything? For reference the servo I'm playing with is a hobby servo: MG90S

Specifically my question is to confirm that there are no other options available for the MG90S other than what I've listed above.

We all know servos don't move instantly, which is why it is common to put a delay or a millis() loop whenever you issue a servo.write() command to give it time to reach its target before moving on to the next thing.

What irks me though is that this could be inefficient in situations where the last servo position might be close to its target - you might only need a very short delay in those cases, whereas if it has to sweep the full 359 degrees, you might want more time.

I was disappointed that servo.read() is completely useless for this task (why even include it in the library?) as the following code illustrates:

#include <Adafruit_TiCoServo.h>
Adafruit_TiCoServo servo;
const uint8_t PIN_SERVO = 9;

void setup() {
  servo.attach(PIN_SERVO);
  Serial.begin(9600);


  Serial.println("start");
  servo.write(180);
  delay(1000);

  int pos;
  while(pos != 0){
    pos = servo.read();
    Serial.println(pos); // because it only returns what the last write() operation
                         // was sent, it immediately thinks it's at pos 0 and exits.
    servo.write(0);
  }

  Serial.println("Done");
}

So that sucks. It seems that my options are:

  1. just use a long delay that accommodates the worst-case scenario. I hate this.
  2. add a limit switch at the final target position and just read the state of that switch
  3. build some kind of elaborate encoder that you can read an absolute angle from or buy a more expensive servo that can tell you this info

Am I missing anything? For reference the servo I'm playing with is a hobby servo: MG90S

We all know servos don't move instantly, which is why it is common to put a delay or a millis() loop whenever you issue a servo.write() command to give it time to reach its target before moving on to the next thing.

What irks me though is that this could be inefficient in situations where the last servo position might be close to its target - you might only need a very short delay in those cases, whereas if it has to sweep the full 359 degrees, you might want more time.

I was disappointed that servo.read() is completely useless for this task (why even include it in the library?) as the following code illustrates:

#include <Adafruit_TiCoServo.h>
Adafruit_TiCoServo servo;
const uint8_t PIN_SERVO = 9;

void setup() {
  servo.attach(PIN_SERVO);
  Serial.begin(9600);


  Serial.println("start");
  servo.write(180);
  delay(1000);

  int pos;
  while(pos != 0){
    pos = servo.read();
    Serial.println(pos); // because it only returns what the last write() operation
                         // was sent, it immediately thinks it's at pos 0 and exits.
    servo.write(0);
  }

  Serial.println("Done");
}

So that sucks. It seems that my options are:

  1. just use a long delay that accommodates the worst-case scenario. I hate this.
  2. add a limit switch at the final target position and just read the state of that switch
  3. build some kind of elaborate encoder that you can read an absolute angle from or buy a more expensive servo that can tell you this info

For reference the servo I'm playing with is a hobby servo: MG90S

Specifically my question is to confirm that there are no other options available for the MG90S other than what I've listed above.

Source Link
Tom Auger
  • 193
  • 1
  • 9

How to determine the minimum time for a servo to reach its destination?

We all know servos don't move instantly, which is why it is common to put a delay or a millis() loop whenever you issue a servo.write() command to give it time to reach its target before moving on to the next thing.

What irks me though is that this could be inefficient in situations where the last servo position might be close to its target - you might only need a very short delay in those cases, whereas if it has to sweep the full 359 degrees, you might want more time.

I was disappointed that servo.read() is completely useless for this task (why even include it in the library?) as the following code illustrates:

#include <Adafruit_TiCoServo.h>
Adafruit_TiCoServo servo;
const uint8_t PIN_SERVO = 9;

void setup() {
  servo.attach(PIN_SERVO);
  Serial.begin(9600);


  Serial.println("start");
  servo.write(180);
  delay(1000);

  int pos;
  while(pos != 0){
    pos = servo.read();
    Serial.println(pos); // because it only returns what the last write() operation
                         // was sent, it immediately thinks it's at pos 0 and exits.
    servo.write(0);
  }

  Serial.println("Done");
}

So that sucks. It seems that my options are:

  1. just use a long delay that accommodates the worst-case scenario. I hate this.
  2. add a limit switch at the final target position and just read the state of that switch
  3. build some kind of elaborate encoder that you can read an absolute angle from or buy a more expensive servo that can tell you this info

Am I missing anything? For reference the servo I'm playing with is a hobby servo: MG90S