Notifications
Clear all

Trouble moving 2 servos smoothly

2 Posts
2 Users
0 Likes
1,106 Views
(@driveralot)
Member
Joined: 4 years ago
Posts: 1
Topic starter  

Hello all I need help with this program I am making. Basically I am trying to make the servo move smoothly in different positions with delays. I used the Arduino example sweep example and implemented in my code so the servo moves swiftly and all positions are in the array. The servos jump around if I use my code. That is because if servo1 is completed its position movement and servo2 is still going they will both stop wait for the delay and then jump to the next position. This way servo1 will go to the next movement smoothly while servo2 has to jump and not be smooth. Example when servo1 goes from 80 to 100 and servo2 goes from 80 to 140 during the same time frame I see servo1 completing the movement from 80 to 100 quicker than servo2 which has a longer run. But once servo1 has completed its movement the program stops and waits for the delay and goes to the next position. Then Servo1 goes from 100 to 120 while servo2 has to jump to 140 which it hadn't completed and go to position 160. Look at the serial monitor after my code to see what I am talking about

 

#include <Servo.h>

Servo myservo1;
Servo myservo2;

const int pos1[] = {0, 40, 80, 100, [b]80, 100[/b], 120, 180, 100, 50, 0};
const int pos2[] = {0, 20, 80, 100, [b]80, 140[/b], 160, 100, 50, 20, 0};
const int turn_size = sizeof(pos1) / sizeof(pos1[0]);
const int delay1[turn_size] = {3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000};

void setup()
{
  myservo1.attach(9);
  myservo2.attach(4);
  Serial.begin(9600);

}

void loop()
{
  for (int i = 0; i < turn_size-1; i++)
  {
    //---start1
    int start1 = pos1[i];
    int end1 = pos1[i+1];
    int start2 = pos2[i];
    int end2 = pos2[i+1];
   
    int inc1 = 1;  // assume counting up
    int inc2 = 1;
    if ( end1 < start1 && end2 < start2)
    {
      inc1 = -1; // counting down
      inc2 = -1;
    }
    else if ( end1 < start1 && end2 > start2)
    {
      inc1 = -1; // counting down
      inc2 = 1;
    }
    else if ( end1 > start1 && end2 < start2)
    {
      inc1 = 1; // counting down
      inc2 = -1;
    }
    while( start1 != end1 && start2 != end2)
    {
      myservo1.write(start1);
      delay(15);
      start1 += inc1;
     
      myservo2.write(start2);
      delay(15);
      start2 += inc2;

      Serial.print("S1:");
      Serial.print(start1);
      Serial.print(", S2:");
      Serial.println(start2);
       
    }
    delay(delay1[i]);
    //---end1
  }
}

   
Quote
Ruplicator
(@ruplicator)
Member
Joined: 4 years ago
Posts: 127
 

I hope I understand your problem. I believe your trying to get each servos to smoothly move regardless of what the other servo is doing. I believe you can accomplish this with just a couple of pointers. First you can just tell the servo what angle you want it to track to from 0 to 180 degrees. In other words if a servo is setting at 40 degrees and you want it to move to 175 degrees you just write 175 degrees to it. Second, You can write to the servos very quickly without delays but if you are feeding the changes of positions to the servos from something like an array like you were doing, then you must wait for the servo to physically move to the new position. You can see in the sample code I made from your code, the writes happen one right after the other with no delays. But before another command is sent to them the longest travel distance of the two servos is calculate an the delay is based on that distance. If you are feeding servo positions from something like a joy stick you may not have to do delays since the stick will move more slowly than looping through an array. Here is a link to a simulation video that is running the code below>>> https://photos.app.goo.gl/VaHNW4PXZzxpzPEa6

 #include 

Servo myservo1;
Servo myservo2;

const int pos1[] = {0, 40, 80, 100, 80, 100, 120, 180, 100, 10, 0};
const int pos2[] = {0, 20, 80, 100, 80, 140, 160, 100, 50, 20, 0};
const int turn_size = sizeof(pos1) / sizeof(pos1[0]);
const int delay1[turn_size] = {3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000};
int i = 0;
int delaytot = 0;
int mot1pos = 90; //servo 1 last position
int mot2pos = 90; //sevo 2 last position


void setup()
{
  myservo1.attach(9);
  myservo2.attach(4);
  Serial.begin(9600);

}

void loop()
{
  for (int i = 0; i < turn_size; i++)
  {
      myservo1.write(pos1[i]);
      myservo2.write(pos2[i]);

	  delaytot = abs(pos1[1] - mot1pos); //calculater servo 1 travel distance

	  if (abs(pos2[i] - mot2pos) >= delaytot) delaytot = abs(pos2[i] - mot2pos);

//	  delaytot now containg the longest travel time of either servo 1 or 2
	  mot1pos = pos1[i];
	  mot2pos = pos2[i];
      Serial.print("S1:");
      Serial.print(pos1[i]);
      Serial.print(", S2:");
      Serial.print(pos2[i]);
      Serial.print(", Delay: ");
      Serial.println(delaytot);
      delay(delaytot * 10);       //delay based on travel time
    }
    delay(delay1[i]);
    //---end1
  }

   
ReplyQuote