Arduino UNO - how to get smooth servo movement ?

Hello all,

I would like to say I’m coming to you with something new, something that no one was asking for on this forum before. Unfortunately I’m facing quite typical (I guess) problem and I simply can’t get where I want by myself. Hoping you guys will be kind enough to help me to trouble shoot a bit.

PROBLEM
I’m trying to get smooth servo movement from my arduino UNO (one of the clones). I know already I should always power up my servo from separate power source, therefore it gets power from dedicated 4xAA = 6V pack. The ground is connected to the arduino ground, and the signal coms from pin9. I’m using a thumb joystick to control the servo. I went with many code tests and ended up with something like this

#include <Arduino.h>
#include <Servo.h>

Servo myservo;  // create servo object to control a servo

int sensorPin = 0;    // select the input pin for the potentiometer
int ledPin = 13;      // select the pin for the LED
int sensorValue = 0;  // variable to store the value coming from the sensor
int servoValue = 90;  // servo initial position. Half way of 180 degree.


void setup() {
  TIMSK0=0;
  // declare the ledPin as an OUTPUT:
  pinMode(ledPin, OUTPUT);
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  Serial.begin(9600);
  myservo.write(servoValue); //set initial servo position 
}

void loop() {
  // read the value from the sensor:
  sensorValue = analogRead(sensorPin);
  if (sensorValue > 530) {
    if (servoValue < 179) {
      servoValue = servoValue + 2;
      myservo.attach(9);
      myservo.write(servoValue);
    }
    else {
      myservo.detach();
    }
  }
  else if (sensorValue < 510) {
    if (servoValue >0) {
      servoValue = servoValue - 2;
      myservo.attach(9);
      myservo.write(servoValue);
    }
    else {
      myservo.detach();
    }
  }
  else {
    myservo.detach();
  }

  Serial.print("Sensor Value:");
  Serial.print(sensorValue);
  Serial.print(" ");
  Serial.print("Servo Value:");
  Serial.print(servoValue);
  Serial.println(";");
  delay(10);
}

Above code gave me the smoothest movement I could get so far but still servo can behave erratically (stops, moves few degree in one direction and then coming back, moves faster or slower ) - I will try to make a video later on. Can anyone suggest on what I could possibly be doing wrong.

Another thing is that I’m not getting full 270 degree travel from my servo. I think I get slightly more than 180. From what I was already able to find on the forum, not all servos are able to deliver they full range movement. I’m using PowerHD LF-20MG-270 servo.

if (sensorValue > 530) {
    if (servoValue < 179) {

Can it ever happen?

Yes. This part works great. SensorValue > 530 means joystick is moved UP. Then servo is moving until it reaches it’s 179 degree position. Code will not execute if servo is already on 179 position.

Funny thing I have observed is that at 0 position servo can stop and stay calm. If I stop servo at 10+ degree it’s going to jitter before it stops.

I was able to clam down the servo by using detach() after every move command. Still not what I’m looking for.

demkat1:

if (sensorValue > 530) {

if (servoValue < 179) {




Can it ever happen?

Sorry, mis-read . I have read "sensorValue " in both if…

Why do you keep attaching and detaching the servo ?

Have you tried writeMicroseconds() rather than write() ? It will give you finer resolution in the servo movement (assuming that the servo is mechanically capable of it) because the servo moves from one end of its movement in 1000 steps rather than 180 steps.

UKHeliBob: Why do you keep attaching and detaching the servo ?

Have you tried writeMicroseconds() rather than write() ? It will give you finer resolution in the servo movement (assuming that the servo is mechanically capable of it) because the servo moves from one end of its movement in 1000 steps rather than 180 steps.

Thanks a lot UKHeliBob. I will try writeMicroseconds() once I'm back home. I keep servo detach after every movement cause only this way I was able to keep servo calm while not directed to move. This is the only reason. Before (without detach() in my code) servo was jittering and erratic even with no changes to servo's position.

Whilst the servo may jitter a little when halted at a position it will at least hold the position. Once detached it is free to move if an external force is applied unlike it would if detached

The Servo library write() method restricts the angle between 0° and 180°. Use writeMicroseconds() to get the full 270° range:

myservo.writeMicroseconds(map(angle, 0, 270, 500, 2500));

The datasheet says that the pulse width range is 500 to 2500 microseconds. The default limits in the library are 544 to 2400, but you can change them in attach():

myservo.attach(9, 500, 2500);

Thanks a lot for all your suggestions. Unfortunately something is still wrong. I tired simple code like

#include <Arduino.h>
#include <Servo.h>

Servo myservo;

void setup() {
    // put your setup code here, to run once:
    myservo.attach(9);
    myservo.writeMicroseconds(1500);  // set servo to mid-point
}

void loop() {
    // put your main code here, to run repeatedly:
}

I was expecting servo to go in to specific position defined by 1500us but instead servo was slowly (about 3sec) moving about 90 degree and coming back with in 1 sec. This movement repeats few (about 8-9) times and then servo stops. After couple of seconds whole process repeats.

I have even tried to comment “myservo.writeMicroseconds(1500);” leaving “myservo.attach(9)” but the result was exactly same as before. Is it possible that my arduino is source of the problem?

Inadequate servo power supply.

jremington:
Inadequate servo power supply.

As mentioned above. I use 6V pack (4xAA) to power up servo. Do you believe it’s not enough?

I [u]am certain[/u] that 4xAA alkaline batteries are inadequate for the PowerHD LF-20MG-270 servos, as they cannot deliver the required stall current.