Servo speed control is not precise.

Hello!

I have a Doman DM-S1506MD continuous servo, powered from an external 5.5V power resource and connected to a digital Arduino pin.

Here is a piece of code controlling my servo:

servoSpeed1 = (1500*(pow(abs(followFocusDelta),(0.001/pow(abs(followFocusDelta),1.7)))));

     if  ( followFocusDelta > 0.003) {servo1.writeMicroseconds(1500+servoSpeed1);}
       else if ( followFocusDelta < (-0.003)) {servo1.writeMicroseconds(1500-servoSpeed1);}
       else {servo1.writeMicroseconds(1500);}

'delta' is a float var and changing smoothly according to a potentiometer position from 0 to 1.

The thing is that the servo is changing its speed CW more or less smooth, not enough smooth in fact. But the other way - CCW it changes its speed really like stepwise, it looks like it has just 3-4 steps of speed. Seems like it is not precise at all.
If CW it starts moving at 1571us, CCW it starts moving just at 1250us and then speed changes stepwise.

Which Servo 360 standard size ±15 kg.cm torque could you recommend?

Tofer:
The thing is that the servo is changing its speed CW more or less smooth, not enough smooth in fact. But the other way - CCW it changes its speed really like stepwise, it looks like it has just 3-4 steps of speed.

You don't seem to have any Serial.print() statements in your code to allow you to see what actual value of microsecs is being used with servo1.writeMicroseconds()

Just out of curiosity why have you changed the integer values returned by analogRead() into a floating point value? Floating point maths is very slow on an Arduino.

If you need more help please post a complete program and use the code button </> so your code looks like this and is easy to copy to a text editor. See How to use the Forum

...R

Here is another code I've written just to check the speed control:

#include <Servo.h>
Servo servo1;
float servoSpeed;


#define CALIBRATION_BUTTON_PIN 4


boolean calibrationButtonWasUp = true;
boolean calibrationLedEnabled = false;

float p3 = 0; // manipulator
int inputPin3 = A3;
boolean CCW = false;

void setup() {
  // put your setup code here, to run once:
pinMode(CALIBRATION_BUTTON_PIN, INPUT_PULLUP);
servo1.attach(9);

Serial.begin(9600);
}




void loop() {


  boolean calibrationButtonIsUp = digitalRead(CALIBRATION_BUTTON_PIN);
  if (calibrationButtonWasUp && !calibrationButtonIsUp) {
    delay(1000);
   calibrationButtonIsUp = digitalRead(CALIBRATION_BUTTON_PIN);
      if (!calibrationButtonIsUp) {
        
        if (CCW== false) {
        CCW = true;}
        else {
         CCW = false; 
        }
        
        
      }
      
  }

  
p3 = analogRead(inputPin3);
servoSpeed = float(1500*(p3/1023));

Serial.println(servoSpeed);
if (CCW == false) {

servo1.writeMicroseconds(1500+servoSpeed);}
else {
  
servo1.writeMicroseconds(1500-servoSpeed);

}

  
}

Same problem. CW - works just ok - very smooth. CCW - starts moving just when 'servoSpeed' is 181us. Then speed changes stepwise in 4 steps. Seems I need another precise servo.

In that program you are still not printing the actual values used with servo1.writeMicroseconds()

Calculate the value and print it before using it in servo.writeMicroseconds()

...R

So, here is the code)

#include <Servo.h>
Servo servo1;
float servoSpeed;


#define CALIBRATION_BUTTON_PIN 4


boolean calibrationButtonWasUp = true;
boolean calibrationLedEnabled = false;

float p3 = 0; // manipulator
int inputPin3 = A3;
boolean CCW = false;

int servoValue;

void setup() {
  // put your setup code here, to run once:
pinMode(CALIBRATION_BUTTON_PIN, INPUT_PULLUP);
servo1.attach(9);

Serial.begin(9600);
}




void loop() {


  boolean calibrationButtonIsUp = digitalRead(CALIBRATION_BUTTON_PIN);
  if (calibrationButtonWasUp && !calibrationButtonIsUp) {
    delay(1000);
   calibrationButtonIsUp = digitalRead(CALIBRATION_BUTTON_PIN);
      if (!calibrationButtonIsUp) {
        
        if (CCW== false) {
        CCW = true;}
        else {
         CCW = false; 
        }
        
        
      }
      
  }

  
p3 = analogRead(inputPin3);
servoSpeed = float(1500*(p3/1023));

//Serial.println(servoSpeed);
if (CCW == false) {

servoValue = 1500+servoSpeed;
Serial.println(servoValue);
servo1.writeMicroseconds(servoValue);}
else {
Serial.println(servoValue);
servoValue = 1500-servoSpeed;
servo1.writeMicroseconds(servoValue);

}

  
}

Servo starts its moving CCW with 1300us, then while the value changes up to 1041us the speed stays the same and becomes faster just after 1041 and then keeps the same pace up to 772, after 772 it again becomes faster and keeps the same pace up to 0. So, it has just 3 speeds CCW. ))) Chinese servos)

I looking at JX PDI-6221MG 360. It looks like it has a more precise speed regulation.

Sounds like it is a dud servo.

...R

Test your servo with this sketch:

/*
 Try this test sketch with the Servo library to see how your
 servo responds to different settings, type a position
 (544 to 2400), in the top of serial monitor and hit [ENTER], start at 1500 and work your
 way toward zero (544) 50 micros at a time, then toward 2400. 
*/
#include <Servo.h>
Servo servo;

void setup() {
  // initialize serial:
  Serial.begin(9600); //set serial monitor baud rate to match
  servo.writeMicroseconds(1500);
  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, 544, 2400);
    servo.writeMicroseconds(pos);
    prntIt();
  }
}
void prntIt()
{
  Serial.print("microseconds =  ");
  Serial.println(servo.readMicroseconds());
}

Never you mind. :slight_smile: G'nite all & happy Easter to those who observe.

No, it's not about the sketch. It seems it's something wrong with the hardware.

It seems the problem is somewhere here (see the attachment). They use two different transistors for left and right connectors. And I can't understand which one is a problem.

It has been my experience that continuous rotation servos frequently have poor speed control.
The control hardware and firmware is designed with the positionally aware servo design in mind. Given a particular position command, go there as quickly as possible and hold that position.
When this hardware/firmware is re-purposed to be a continuous rotation servo, it does one thing very well, let you command the motor to rotate forward, backward and stop.
But it often does NOT give usable speed control.

Some continuous servos have no speed control. They are probably based on very accurate real servos, which turn with full speed all the way to the desired angle and stop immediately. The ones with speed control are probably based on servos, which need to slow down before reaching the desired angle. It's about the torque-inertia ratio.