Controlling 12 servos with Arduino Uno

Hello there guys,

I am using a 6V - 3A max power supply for the servos. My computer is powering the board. The servos start moving correctly, however they slow down progressively over time. I am not sure whether this is an electricity problem or a code problem. Would you guys take a look at my code, please? Can you spot any problems?

Thank you very much in advance.

#include <Servo.h> 
#define servoNum 4

Servo servos[servoNum];
int servoPins[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ,11};

// initial servo position
int pos = 0;

// maximum position the servo can go to
int angle = 180;

//controls the servo speed
int delaySpeed = 15;

// waits to open/close
int delayToMove = 1000;

// blade delay
int spiralDelay = 30;

void setup() 
{ 
  // attaches the servo objects to pins on the board
  // and sends servos to initial position
  for(int i = 0; i < servoNum; i++)
  {
    servos[i].attach(servoPins[i]);
    servos[i].write(pos);
    delay(delaySpeed);
    //Serial.print(i; DEC);
    //Serial.print(", ");
  }
  //Serial.println(" ");
} 

void loop() 
{ 
  
  ////////////////////////////////////////////// open  ///////////////////////////////////////////////////////
  for(pos = 0; pos < angle + ((servoNum-1)*spiralDelay); pos += 1)  // goes from 0 degrees to 180 degrees + delay to wait for all servos to get to the same position
  {    
    int i;
    for(i = 0; i < servoNum; i++)
    {
      if (pos >= i*spiralDelay)
      {
        servos[i].write(pos - i*spiralDelay);
        delay(delaySpeed);
      }
      
    }   
  } 

  //////////////////////////////////////////////////////////////////////////////////////////////////////////
  
  // waits to close
  delay(delayToMove);
  
  //////////////////////////////////////////// close  ///////////////////////////////////////////////////////

  //  reverse the movement
  // starts motion for the first servo
  
  for(pos = angle+((servoNum-1)*spiralDelay); pos >= 1; pos -= 1)    // goes from 180 degrees + delay to 0 degrees
  {  
    int i;
    for(int i = 0; i < servoNum; i++)
    {
      if(pos <= (angle+((servoNum-1)*spiralDelay))-i*spiralDelay)
      {
        servos[i].write(pos - ((servoNum-(i+1))*spiralDelay));
        delay(delaySpeed); 
      }
      
    } 

  } 
  
  //////////////////////////////////////////////////////////////////////////////////////////////////////////
  
  // waits to open
  delay(delayToMove);
}

Your code has turned to italics.

Please read this: http://forum.arduino.cc/index.php?topic=148996.0

Pay particular attention to point 7.

Attach your code using the </> icon on the left side of the posting menu.
Have you measured the 6 volt power supply when things go bad?

Please edit your post and put code tags (</> icon) round the code unless half of it is meant to be in italics.

I see that you are using pins 0 and 1 for servos. Bad idea. These pins are used by the Serial interface and cannot be shared with other functions.

Servo servos[servoNum];

Can you please explain exactly what that line of code does ?

Sweet guys, thanks for the prompt responses. Just trying to edit my post over here, first time I have been to this forum.

I guess the post is correct now?

6V constant power supply.

Ok, I can then use pin 13 instead. Can I use the analog pins for the missing one?

It creates a single array of servo objects.

A0-A5 are the same as D14-D19 They can be used as digital inputs. D0 and D1 are for your serial connections and should be avoided.

Is the 6 volt power supply stable?

Thanks LarryD. I will use those instead.

Yes, I am measuring the power as it runs.

Do you think the delay function calls could also be causing the problem or nothing to do?

Will let you know tomorrow morning London time, thanks a lot!

An easy way to check power issues is disconnect all servos except one and see if it still has issues. If it performs as expected, then the power supply probably can't support all 12 servos. A single servo under load can draw more than one amp if it is a standard size servo.

It creates a single array of servo objects.

The reason that I asked is that the code is at odds with the title of the thread.

Yes, I was probably trying it with less servos when I uploaded to the forum. Sorry for that. I can change that variable to 12 and add the pins to the pin list.

Yes all working now. For future reference I am running on 5.2V and the servos are driving 1.7A max. I have to link the servos to a 200g app. piece of acrylic so that current will increase a bit.

As a matter of feedback I bought a variable power supply that always goes above what it says. When I set it up to 6V it goes up to 6.2V! My servos are Hitec HS-311 and don't like more than 6V, so I have to run them on 5V so I have 5.2V

But in terms of code you guys think its all correct right?

Thanks a lot :)

All the best, mdalligna

mdalligna: But in terms of code you guys think its all correct right?

Is the code producing the desired outcome?

Yes.

The reason why I ask is because if you noticed in both of my loops I am sending angles larger than 180 to the servos. Because they go to that position in sequence I hold them in the maximum position that way.

mdalligna: Yes.

The reason why I ask is because if you noticed in both of my loops I am sending angles larger than 180 to the servos. Because they go to that position in sequence I hold them in the maximum position that way.

The "angle" thing in the Servo class is a convenient, though often inaccurate, fiction. Some servos can manage more than 180 degrees of movement, many cannot, but the Servo class has no way of knowing what its instances are attached to. It just scales the "angle" to a pulse width in the range of about 550 to 2000us and sends it out.