Using more than 3 servos in Arduino MEGA 2560

Hello guys,

I’m making a project that converts each char from a string (received by a Bluetooth module) to servos positions.

#include <Servo.h>
String frase=0;
char c;
int x=0;
int angulo = 19;     //Determina o angulo equivalente da anguloição zero. Vai de 1 a 180.
int num_caract = 5;  //Ajusta o programa ao número de caracteres que são mostrados por vez.
int pos = 0;

int ascii[100];
Servo a1;
Servo a2;
Servo b1;
Servo b2;
Servo c1;
Servo c2;
Servo d1;
Servo d2;
Servo e1;
Servo e2;


byte pa1 = 49;
byte pa2 = 51;
byte pb1 = 45;
byte pb2 = 47;
byte pc1 = 41;
byte pc2 = 43;
byte pd1 = 37;
byte pd2 = 39;
byte pe1 = 33;
byte pe2 = 35;
  
boolean debug = 0;

void setup(){
  biblioteca();        //Inicia os valores da biblioteca.
  zerarServo();
  a1.attach(pa1);
  a2.attach(pa2);
  b1.attach(pb1);
  b2.attach(pb2);
  c1.attach(pc1);
  c2.attach(pc2);
  d1.attach(pd1);
  d2.attach(pd2);
  e1.attach(pe1);
  e2.attach(pe2);
pinMode(13,OUTPUT);
Serial.begin(9600);
Serial1.begin(38400);
Serial1.print("AT+RESET \r\n");
Ler();
Serial1.print("AT+UART=115200,0,0");
Ler();
Serial1.begin(115200);
Serial1.print("AT+ORGL \r\n");
Ler();
Serial1.print("AT+NAME=dispositivobraille \r\n");
Ler();
Serial1.print("AT+INIT \r\n");
Ler();
Serial1.print("AT+INQ \r\n");
Ler();
Serial.println("PRONTO!");
}
void loop(){
//Comunicação Android->Arduino:
if(frase==0){
while(Serial1.available()){
c=Serial1.read();
frase = String(frase + c);
x=1;
digitalWrite(13,HIGH);
}
delay(100);
if(x==1){
Serial.println(frase);
zerarServo();
imprimirBraille();
frase = 0;
x=0;
digitalWrite(13,LOW);
}
}
//Comunicação Arduino->Android:
if(frase==0){
while(Serial.available()){
c=Serial.read();
frase = String(frase + c);
x=1;
digitalWrite(13,HIGH);
}
delay(100);
if(x==1){
Serial1.println(frase);
frase = 0;
x=0;
digitalWrite(13,LOW);
}
}
}
void Ler(){
String Comando;
while (Serial.available()) { 
if (Serial.available() >0) {
char c = Serial.read();
Comando += c;
}
} 
if (Comando.length() >0) {
Serial.print(Comando); 
}
delay(500);
}
void imprimirBraille(){
  int y;
  int colesq = 0;
  int coldir = 0;
  int ciclo;
  int paginas = 1;
    for(y=0; y<5; y++){
      Serial.println(frase[y]);
      bitWrite(colesq,0,bitRead(ascii[frase[y+(num_caract*ciclo)]-32],0));
      bitWrite(colesq,1,bitRead(ascii[frase[y+(num_caract*ciclo)]-32],1));
      bitWrite(colesq,2,bitRead(ascii[frase[y+(num_caract*ciclo)]-32],2));
      bitWrite(coldir,0,bitRead(ascii[frase[y+(num_caract*ciclo)]-32],3));
      bitWrite(coldir,1,bitRead(ascii[frase[y+(num_caract*ciclo)]-32],4));
      bitWrite(coldir,2,bitRead(ascii[frase[y+(num_caract*ciclo)]-32],5));
      Serial.println(colesq);
      Serial.println(coldir);
      Serial.println();
      switch (y){
        case 0:
        a1.write(angulo*coldir);
        a2.write(angulo*colesq);
        break;
        case 1:
        b1.write(angulo*coldir);
        b2.write(angulo*colesq);
        break;
        case 2:
        c1.write(angulo*coldir);
        c2.write(angulo*colesq);
        break;
        case 3:
        d1.write(angulo*coldir);
        d2.write(angulo*colesq);
        break;
        case 4:
        e1.write(angulo*coldir);
        e2.write(angulo*colesq);
        break;

      }
  }
          delay(100);
}

void biblioteca(){             //+32
  ascii[0] = 0;
  ascii[65] = 1; //'a';
  ascii[66] = 3; //'b'; 
  ascii[67] = 9; //'c';
  ascii[68] = 25; //'d';
  ascii[69] = 17; //'e';
  ascii[70] = 11; //'f';
  ascii[71] = 27; //'g';
  ascii[72] = 19; //'h';
  ascii[73] = 10; //'i';
  ascii[74] = 26; //'j';
  ascii[75] = 5; //'k';
  ascii[76] = 7; //'l';
  ascii[77] = 13; //'m';
  ascii[78] = 29; //'n';
  ascii[79] = 21; //'o';
  ascii[80] = 15; //'p';
  ascii[81] = 31; //'q';
  ascii[82] = 23; //'r';
  ascii[83] = 14; //'s';
  ascii[84] = 30; //'t';
  ascii[85] = 37; //'u';
  ascii[86] = 39; //'v';
  ascii[87] = 52; //'w';
  ascii[88] = 45; //'x';
  ascii[89] = 61; //'y';
  ascii[90] = 53; //'z';
  ascii[33] = 1; //'a';
  ascii[34] = 3; //'b'; 
  ascii[35] = 9; //'c';
  ascii[36] = 25; //'d';
  ascii[37] = 17; //'e';
  ascii[38] = 11; //'f';
  ascii[39] = 27; //'g';
  ascii[40] = 19; //'h';
  ascii[41] = 10; //'i';
  ascii[42] = 26; //'j';
  ascii[43] = 5; //'k';
  ascii[44] = 7; //'l';
  ascii[45] = 13; //'m';
  ascii[46] = 29; //'n';
  ascii[47] = 21; //'o';
  ascii[48] = 15; //'p';
  ascii[49] = 31; //'q';
  ascii[50] = 23; //'r';
  ascii[51] = 14; //'s';
  ascii[52] = 30; //'t';
  ascii[53] = 37; //'u';
  ascii[54] = 39; //'v';
  ascii[55] = 52; //'w';
  ascii[56] = 45; //'x';
  ascii[57] = 61; //'y';
  ascii[58] = 53; //'z';
  ascii[16] = 26; //'0';
  ascii[17] = 1; //'1';
  ascii[18] = 3; //'2';
  ascii[19] = 9; //'3';
  ascii[20] = 25; //'4';
  ascii[21] = 17; //'5';
  ascii[22] = 11; //'6';
  ascii[23] = 27; //'7';
  ascii[24] = 19; //'8';
  ascii[25] = 10; //'9';
  ascii[1] = 22; //'!';
  ascii[2] = 38; //'"';
  ascii[4] = 48; //''';
  ascii[7] = 2; //''';
  ascii[8] = 55; //'(';
  ascii[9] = 62; //')';
  ascii[10] = 20; //'*';
  ascii[12] = 2; //',';
  ascii[13] = 36; //'-';
  ascii[14] = 4; //'.';
  ascii[26] = 9; //':';
  ascii[27] = 6; //';';
  ascii[29] = 54; //'=';
  ascii[31] = 34; //'?';
  ascii[59] = 42; //'[';
  ascii[60] = 51; //'\';
  ascii[61] = 59; //']';
  ascii[63] = 56; //'_';
  ascii[3] = 60; //'#' - sinal de algarismo;
  ascii[62] = 40; //'^' - sinal de maiusculo;
}

void zerarServo(){
  a1.write(0);
  a2.write(0);
  b1.write(0);
  b2.write(0);
  c1.write(0);
  c2.write(0);
  d1.write(0);
  d2.write(0);
  e1.write(0);
  e2.write(0);
}

The program is working very well with 1, 2 and 3 servos. But when I connect the fourth servo, all servos stop working properly, not responding to .write() function. I intend to use 10 servos, and I made a project before that used 12 servos… so it’s kinda strange O.o

Arduino is connected in the USB port, and the servos are using an external source of 800mA of max. current. 4.5V. Both GNDs are connected.
I’m not using interruptions, or timers. Help plz!

Arduino is connected in the USB port, and the servos are using an external source of 800mA of max. current. 4.5V. Both GNDs are connected.
I'm not using interruptions, or timers. Help plz!

You need more current capacity. I plan when using servos to budget one amp of supply current for each servo to be used. Ten servos, ten amp 5vdc external power supply.

Lefty

I will try to change my source later.... thanks!
btw can arduino drive enough current to send to servos controls? using it on the USB port? or I will need an external source to it too?

chadvader:
I will try to change my source later.... thanks!
btw can arduino drive enough current to send to servos controls? using it on the USB port? or I will need an external source to it too?

No problem there, servo control signals require very little current so no limit there to worry about, just servo power current. Be sure to also add a wire from the external power supply negative lead to a arduino ground pin.

Lefty

Thank you very much! :smiley:

Please note that, at present, the String library has bugs as discussed here and here.

In particular, the dynamic memory allocation used by the String class may fail and cause random crashes.

I recommend reworking your code to manage without String. Use C-style strings instead (strcpy, strcat, strcmp, etc.), as described here for example.

Alternatively, install the fix described here: Fixing String Crashes

And as a by-the-way, most servos operate on 4.8 to 6VDC so your 4.5 is probably too low anyhow, regardless of current issues.

But check your servo datasheet for details of voltage and current requirements. Datasheets often don't give the maximum current (ie at stall) so go with lefty's 1A each unless you either a) get a lower figure from the datasheet or b) measure it. It's easy to measure the current at stall- hook it up with an ammeter in series (making sure it's on a high enough range). It will likely draw something like 100mA under free running. Grab the servo in one hand and try to stop the the horn with the other: you'll see the current climb probably to 500mA or so, or more....

Search for member DuaneB and follow the links in his signature to see some current testing he did.

frase = String(frase + c);

Even after fixing the malloc issue, this is still a waste of resources. A call to the constructor is needed to create the object on the right. Then, the copy constructor is called to copy the right operand to the left operand. Then, the two destructors are called.

A real waste when the String class overloads the += operator to concatenate a char.

PaulS:
A real waste when the String class overloads the += operator to concatenate a char.

Seems to me that the String class as a whole is a solution looking for a problem - which introduces other problems of its own. I can only suppose that the people who manage the Arduino API are fans of Java and want to provide features of Java which they think are neat - regardless of whether they're appropriate or necessary here. (The way the source code is mucked around before compilation is another case in point.)