Pages: [1]   Go Down
Author Topic: Smooth Servo Control  (Read 627 times)
0 Members and 1 Guest are viewing this topic.
Florida
Offline Offline
God Member
*****
Karma: 2
Posts: 554
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,

 The program listed below moves my servos to the desired position, however, the movement is very jerky and happens too fast. Is their anyway to slow down/smooth out the servos motion? Once in the position the servos are fine and their is no twitching.

I looked at the examples of moving servos, however, I was not able to find one which showed smooth motion of 4 servos at the same time.

Any help would be awesome!




Code:
#include <Servo.h>
 
Servo myservo2;
Servo myservo3; 
Servo myservo4;
Servo myservo5;

 
void setup()
{
  myservo2.attach(2); 
  myservo3.attach(3);
  myservo4.attach(4);
  myservo5.attach(5);

}
 
 
void loop()
{
 
    myservo2.write(0);             
    myservo3.write(180);     
    myservo4.write(109);
    myservo5.write(25); 
     
delay(7000);   

 
    myservo2.write(90);   
    myservo3.write(150);     
    myservo4.write(100);
    myservo5.write(115); 

  delay(3000);
 
}
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 549
Posts: 46141
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I looked at the examples of moving servos, however, I was not able to find one which showed smooth motion of 4 servos at the same time.

You have to move servos one at a time. If you move in small enough steps, the servos will all appear, due to inertia, to be moving at one time.

What have you tried?
Logged

Florida
Offline Offline
God Member
*****
Karma: 2
Posts: 554
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I tried at the "sweep" example and I loved the smooth motion however I could not figure out how to sweep all the servos at the same time. In the program I'm using now the servos all appear to start moving at the same time which is what I want. Is it possible to modify the sweep example so that all the servos move smoothly and  at about the same time?

Thanks!
Logged

London
Offline Offline
Edison Member
*
Karma: 23
Posts: 1067
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Which sweep example where?
Logged

Florida
Offline Offline
God Member
*****
Karma: 2
Posts: 554
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The one that comes with the Arduino programing.


Code:
// Sweep
// by BARRAGAN <http://barraganstudio.com>
// This example code is in the public domain.


#include <Servo.h>
 
Servo myservo;  // create servo object to control a servo
                // a maximum of eight servo objects can be created
 
int pos = 0;    // variable to store the servo position
 
void setup()
{
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}
 
 
void loop()
{
  for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees
  {                                  // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees
  {                               
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}
Logged

UK
Offline Offline
Faraday Member
**
Karma: 47
Posts: 3615
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In the servo sweep sketch where it says " myservo.write(pos); " if you add three more lines immediately following (and all before the delay()) - so you have a line for each servo - I think it should work as you want.

...R
Logged

London
Offline Offline
Edison Member
*
Karma: 23
Posts: 1067
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The one that comes with the Arduino programing.
Try:
Code:
// Sweep
// by BARRAGAN <http://barraganstudio.com>
// This example code is in the public domain.


#include <Servo.h>
 
Servo myservo2;  // create servo object to control servo 2
Servo myservo3;  // create servo object to control servo 3
Servo myservo4;  // create servo object to control servo 4
Servo myservo5;  // create servo object to control servo 5
               
int pos = 0;    // variable to store the servo position
 
void setup()
{
  myservo2.attach(2);  // attaches the servo on pin 2 to the servo object
  myservo3.attach(3); // attaches the servo on pin 3 to the servo object
  myservo4.attach(4); // attaches the servo on pin 4 to the servo object
  myservo5.attach(5); // attaches the servo on pin 5 to the servo object
}
 
 
void loop()
{
  for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees
  {                                  // in steps of 1 degree
    myservo(2).write(pos);              // tell servo to go to position in variable 'pos'
    myservo(3).write(pos);             
    myservo(4).write(pos);             
    myservo(5).write(pos);             
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees
  {                               
    myservo(2).write(pos);              // tell servo to go to position in variable 'pos'
    myservo(3).write(pos);             
    myservo(4).write(pos);             
    myservo(5).write(pos);             
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}
Logged

Florida
Offline Offline
God Member
*****
Karma: 2
Posts: 554
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I need the servos to go to different positions (like in the first program i posted) but I want them to move to those positions with the smoothness of the sweep example. I also need them to arrive in their positions at about the same time. In the code you posted I think all the servos will end up in the same position.



My apologies for not being clear.
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 549
Posts: 46141
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I need the servos to go to different positions
From where? The example moves the servo continuously. It doesn't just move a servo to a new position.

You can move all the servos from where they are to new positions, in a for loop, if you have 4 different position variables.
Logged

Florida
Offline Offline
God Member
*****
Karma: 2
Posts: 554
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In the first code I posted (which I wrote) the servos start at a desired position wait a few seconds and move to an other position.  In my code the servos move at ruffly the same time. The problem with my code is that the servos move straight to the position with no steps in-between, making the movement jerky. In the sweep example the servo moves in steps which makes the movement smooth.

 I would like to modify my code so that each servo moves in steps but all the servos finish their steps at about the same time. I don't want one servo moving to position then the other. The servos should all be moving thought their steps at the same time. They will need to go to different positions wait a few seconds and then go back. For example one might go from 0 to 90 and another from 100 to 160.
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 549
Posts: 46141
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You'll need to figure out some common factor in the angles that the servos are to move (90, 30, 9, and 90). Clearly, a for loop that iterates 90 times will work.

On each iteration, increment (or decrement) the position for each servo 1/90th of total range of motion for that servo (1 degree, 1/3 of a degree, 1/10 of a degree, 1 degree). Write that position to the servo. For the two smaller sweeps, the angle value will increment less than a degree, so you can see that ints won't work. The Servo library will truncate the value to an int, but that's OK. It just means that 9 out of 10 passes through the for loop, one of the servos will do nothing. On 1 of three passes, another will do nothing. On each pass, 2 of the servos will move every time.

Keep in mind that the for loop index does not HAVE to be used in the body of the for loop.
Logged

Florida
Offline Offline
God Member
*****
Karma: 2
Posts: 554
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I made a program that uses steps to move the servos and it works perfect. Thanks for all the help!

Also is their anyway to shorten it?


Edit: I have found one problem. When moving to a new position the servo starts at a really low number which does not work in my design with some servos. If the arm is traveling to 180 degrees is their anyway that I can start the travel off at say 100 degrees?


Code:
#include <Servo.h>

int pos1 = 0;
int pos1b = 0;

int pos2 = 0;
int pos2b = 0;

int pos3 = 0;
int pos3b = 0;

Servo myservo2;
Servo myservo3;  
Servo myservo4;


void setup()
{   myservo2.attach(2);
  myservo3.attach(3);
  myservo4.attach(4);

}

void loop()
{
  
  delay(4000);
    myservo2.write(0);  
    myservo3.write(180);    
    myservo4.write(109);      

  delay(4000);
  smove(90,0,0);
  
}








void smove(int s1, int s2, int s3)

{
  
  pos1 = s1 /12;
  pos2 = s2/12;
  pos3 = s3/12;
  
  
  
  
  
  pos3b= pos3;
  pos2b= pos2;
  pos1b= pos1;
  myservo2.write(pos1b);
  myservo3.write(pos2b);
  myservo4.write(pos3b);
  delay(75); //1
  
  pos3b = pos3b + pos3;
  pos2b = pos2b + pos2;
  pos1b = pos1b + pos1;
  myservo2.write(pos1b);
  myservo3.write(pos2b);
  myservo4.write(pos3b);
  delay(75); //2

   pos3b = pos3b + pos3;
  pos2b = pos2b + pos2;
  pos1b = pos1b + pos1;
  myservo2.write(pos1b);
  myservo3.write(pos2b);
  myservo4.write(pos3b);
  delay(75); //3

  pos3b = pos3b + pos3;
  pos2b = pos2b + pos2;
  pos1b = pos1b + pos1;
  myservo2.write(pos1b);
  myservo3.write(pos2b);
  myservo4.write(pos3b);
  delay(75); //4


  pos3b = pos3b + pos3;
  pos2b = pos2b + pos2;
  pos1b = pos1b + pos1;
  myservo2.write(pos1b);
  myservo3.write(pos2b);
  myservo4.write(pos3b);
  delay(75); //5


  pos3b = pos3b + pos3;
  pos2b = pos2b + pos2;
  pos1b = pos1b + pos1;
  myservo2.write(pos1b);
  myservo3.write(pos2b);
  myservo4.write(pos3b);
  delay(75); //6


  pos3b = pos3b + pos3;
  pos2b = pos2b + pos2;
  pos1b = pos1b + pos1;
  myservo2.write(pos1b);
  myservo3.write(pos2b);
  myservo4.write(pos3b);
  delay(75); //7


  pos3b = pos3b + pos3;
  pos2b = pos2b + pos2;
  pos1b = pos1b + pos1;
  myservo2.write(pos1b);
  myservo3.write(pos2b);
  myservo4.write(pos3b);
  delay(75); //8


  pos3b = pos3b + pos3;
  pos2b = pos2b + pos2;
  pos1b = pos1b + pos1;
  myservo2.write(pos1b);
  myservo3.write(pos2b);
  myservo4.write(pos3b);
  delay(75); //9

  pos3b = pos3b + pos3;
  pos2b = pos2b + pos2;
  pos1b = pos1b + pos1;
  myservo2.write(pos1b);
  myservo3.write(pos2b);
  myservo4.write(pos3b);
  delay(75); //10


  pos3b = pos3b + pos3;
  pos2b = pos2b + pos2;
  pos1b = pos1b + pos1;
  myservo2.write(pos1b);
  myservo3.write(pos2b);
  myservo4.write(pos3b);
  delay(75); //11


  pos3b = pos3b + pos3;
  pos2b = pos2b + pos2;
  pos1b = pos1b + pos1;
  myservo2.write(pos1b);
  myservo3.write(pos2b);
  myservo4.write(pos3b);
  delay(75); //12



  
  
}
« Last Edit: June 04, 2013, 03:51:32 pm by Drew Davis » Logged

London
Offline Offline
Edison Member
*
Karma: 23
Posts: 1067
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I made a program that uses steps to move the servos and it works perfect. Thanks for all the help!

Also is their anyway to shorten it?

Try:
Code:

void smove(pos1, pos2, pos3)
{
  pos1 = pos1/12;
  pos2 = pos2/12;
  pos3 = pos3/12;
   
  for (int x =1;x<13;x++){ //do the following 12 times
    pos3b+ =  pos3;  //does the same as pos3b = pos3b + pos3
    pos2b+ =  pos2;
    pos1b+ =  pos1;
    myservo2.write(pos1b);
    myservo3.write(pos2b);
    myservo4.write(pos3b);
    delay(75);
  }
 pos3b = 0;  //reset variables for next call to function but,
     //if you need to retain where the servos are, remove these lines
 pos2b = 0;
 pos1b = 0;
}
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 14
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey Drew,
Here is a code example of sine wave smooth servo movement from two different positions.
The code seems complex but it just uses the more detailed writemicroseconds() command spread out in a bunch of for loops to handle start pause, and alterations in beginning and ending speed.   
You are basically able to pick the beginning and end range of the servo, then pick positions between that you want the servo to travel to. 
The motion between will be a sine wave smooth with a selectable start and end speed.   

http://forum.arduino.cc/index.php?topic=184377.0

Hello,

 The program listed below moves my servos to the desired position, however, the movement is very jerky and happens too fast. Is their anyway to slow down/smooth out the servos motion? Once in the position the servos are fine and their is no twitching.

I looked at the examples of moving servos, however, I was not able to find one which showed smooth motion of 4 servos at the same time.

Any help would be awesome!




Code:
#include <Servo.h>
 
Servo myservo2;
Servo myservo3; 
Servo myservo4;
Servo myservo5;

 
void setup()
{
  myservo2.attach(2); 
  myservo3.attach(3);
  myservo4.attach(4);
  myservo5.attach(5);

}
 
 
void loop()
{
 
    myservo2.write(0);             
    myservo3.write(180);     
    myservo4.write(109);
    myservo5.write(25); 
     
delay(7000);   

 
    myservo2.write(90);   
    myservo3.write(150);     
    myservo4.write(100);
    myservo5.write(115); 

  delay(3000);
 
}
Logged

UK
Offline Offline
Faraday Member
**
Karma: 92
Posts: 3969
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I usually have two sets of variables in arrays (or a struct in a single array - whatever) which contains the desired and current position of each servo on the system.  Then, at pre-defined intervals, either through the use of millis() or on a timer, I update the contents of that array so that the "current" variable is set to half way between its current value and that of the "target" value.  Then I write that new current value to the servo.  It makes for a nice fast start to the movement, but it comes to a nice gentle stop at the right position.  The overall speed is set by the delay between updates.
Logged

Why not visit my eBay shop? http://stores.ebay.co.uk/Majenko-Technologies
Replacement for the Arduino IDE: UECIDE - Proper serial terminal, graphing facilities, plugins, overhauled internals.
Java isn't bad in itself, but it has enabled morons to write programs.

Pages: [1]   Go Up
Jump to: