Mechanical arm problem

Hi everyone, this is my first time writing in this forum, I'm building a robot with 2 mechanical arms (6 servomotors per arm) connected to a PCA9685 module, but after a while the smaller servomotors (of the AD002 micro servo) stop working, here's the script:

// braccio_1_90_90_90_0_0_0
// braccio_2_90_90_90_0_0_0


#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

// Creazione dell'oggetto PCA9685
Adafruit_PWMServoDriver pca = Adafruit_PWMServoDriver();

#define MIN_PULSE_WIDTH 650
#define MAX_PULSE_WIDTH 2350
#define FREQUENCY 50


int numero_movimenti = 50;
// Definizione dei pin per Braccio 1
int braccio1_pins[] = { 6, 7, 11, 8, 9, 10 };

// Definizione dei pin per Braccio 2
int braccio2_pins[] = { 4, 5, 2, 12, 0, 1 };



int braccio1_attuale[] = { 0, 90, 30, 0, 180, 0 };
int braccio1_movimenti_rimanenti[] = { 200, 200, 200, 200, 200, 200 };
int braccio1_obiettivo[] = { 45, 180, 210, 0, 80, 180 };

int braccio2_attuale[] = { 0, 90, 30, 0, 180, 0 };
int braccio2_movimenti_rimanenti[] = { 200, 200, 200, 200, 200, 200 };
int braccio2_obiettivo[] = { 45, 180, 210, 0, 80, 180 };

void setup() {
  Serial.begin(115200);
  pca.begin();
  pca.setPWMFreq(FREQUENCY);
  moveServos(braccio1_pins, braccio1_attuale);
  moveServos(braccio2_pins, braccio2_attuale);
}

void loop() {




  for (int i = 0; i < 6; i++) {
    if (braccio1_movimenti_rimanenti[i] > 0) {
      braccio1_attuale[i] = (braccio1_obiettivo[i] - braccio1_attuale[i]) / braccio1_movimenti_rimanenti[i] + braccio1_attuale[i];
      braccio1_movimenti_rimanenti[i] = braccio1_movimenti_rimanenti[i] - 1;
      //moveServos(braccio1_pins, braccio1_attuale);
    }

    if (braccio2_movimenti_rimanenti[i] > 0) {
      braccio2_attuale[i] = (braccio2_obiettivo[i] - braccio2_attuale[i]) / braccio2_movimenti_rimanenti[i] + braccio2_attuale[i];
      braccio2_movimenti_rimanenti[i] = braccio2_movimenti_rimanenti[i] - 1;
      //moveServos(braccio2_pins, braccio2_attuale);
    }
  }

  moveServos(braccio1_pins, braccio1_attuale);
  moveServos(braccio2_pins, braccio2_attuale);

  delay(20);

  if (Serial.available()) {
    String command = Serial.readStringUntil('\n');

    // Controllo comando per Braccio 1
    if (command.startsWith("braccio_1_")) {
      command.remove(0, 10);  // Rimuove "braccio_1_"
      int angles[6];
      parseCommand(command, angles);

      for (int i = 0; i < 6; i++) {
        braccio1_obiettivo[i] = angles[i];
        braccio1_movimenti_rimanenti[i] = numero_movimenti;
      }
    }

    // Controllo comando per Braccio 2
    else if (command.startsWith("braccio_2_")) {
      command.remove(0, 10);  // Rimuove "braccio_2_"
      int angles[6];
      parseCommand(command, angles);


      for (int i = 0; i < 6; i++) {
        braccio2_obiettivo[i] = angles[i];
        braccio2_movimenti_rimanenti[i] = numero_movimenti;
      }
    }
  }
}



// Funzione per convertire un angolo (0-180) in un valore di impulso
int angleToPulse(int angle, int numero_motore) {

    return map(angle, 0, 180, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
  
}

// Funzione per muovere i servomotori ai valori specificati
void moveServos(int pins[], int angles[]) {
  for (int i = 0; i < 6; i++) {
    int pulse = angleToPulse(angles[i], i);
    pca.writeMicroseconds(pins[i], pulse);
  }
}

// Funzione per parsare il comando e ottenere gli angoli
void parseCommand(String command, int angles[]) {
  for (int i = 0; i < 6; i++) {
    int index = command.indexOf('_');
    if (index == -1) index = command.length();
    angles[i] = command.substring(0, index).toInt();
    command.remove(0, index + 1);
  }
}

I checked the hardware over and over again but everything is still OK, could you help me?

What did the code look like when the small servos were working?

using String is not secure for long term run

I send the command via serial
braccio_1_90_90_90_90_90_90
and everything works, and after a while the motors burn out or go "tick", meaning they no longer hold power and are no longer as fluid as before, checking with a laboratory power supply I see that there are peaks of 3 amps and then it goes back to 1 amp

How could I fix it?

change to char array

are you able to change sequence to "1_90_90_90_90_90_90\n" ?

but can this actually burn the motors?, and are the pulses correct?

#define MIN_PULSE_WIDTH 650
#define MAX_PULSE_WIDTH 2350

ok tanks

but can this actually burn the motors?, and are the pulses correct?

#define MIN_PULSE_WIDTH 650
#define MAX_PULSE_WIDTH 2350

i asked other thing.

but wait, what is this?

it mean it work only 200 times. why?

that's what's used to make the arm move in x steps

that's what's used to make the arm move in x steps

ah,.. oops, never mind

ok thanks how could I solve it?, but could this end up burning out engines??

yes, you must remove burnEngine() command from sketch

ok tanks :rofl:, but I need it to make the servos move gradually

It is used to adjust the number of steps, to make it move gradually

well, question is are you able instead of
braccio_1_90_90_90_90_90_90
to send
1_90_90_90_90_90_90
? remove "braccio_" from command?

the code becomes like this

// 1_90_90_90_0_0_0
// 2_90_90_90_0_0_0


#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

// Creazione dell'oggetto PCA9685
Adafruit_PWMServoDriver pca = Adafruit_PWMServoDriver();

#define MIN_PULSE_WIDTH 650
#define MAX_PULSE_WIDTH 2350
#define FREQUENCY 50


int numero_movimenti = 50;
// Definizione dei pin per Braccio 1
int braccio1_pins[] = { 6, 7, 11, 8, 9, 10 };

// Definizione dei pin per Braccio 2
int braccio2_pins[] = { 4, 5, 2, 12, 0, 1 };



int braccio1_attuale[] = { 0, 90, 30, 0, 180, 0 };
int braccio1_movimenti_rimanenti[] = { 200, 200, 200, 200, 200, 200 };
int braccio1_obiettivo[] = { 45, 180, 210, 0, 80, 180 };

int braccio2_attuale[] = { 0, 90, 30, 0, 180, 0 };
int braccio2_movimenti_rimanenti[] = { 200, 200, 200, 200, 200, 200 };
int braccio2_obiettivo[] = { 45, 180, 210, 0, 80, 180 };

void setup() {
  Serial.begin(115200);
  pca.begin();
  pca.setPWMFreq(FREQUENCY);
  moveServos(braccio1_pins, braccio1_attuale);
  moveServos(braccio2_pins, braccio2_attuale);
}

void loop() {




  for (int i = 0; i < 6; i++) {
    if (braccio1_movimenti_rimanenti[i] > 0) {
      braccio1_attuale[i] = (braccio1_obiettivo[i] - braccio1_attuale[i]) / braccio1_movimenti_rimanenti[i] + braccio1_attuale[i];
      braccio1_movimenti_rimanenti[i] = braccio1_movimenti_rimanenti[i] - 1;
      //moveServos(braccio1_pins, braccio1_attuale);
    }

    if (braccio2_movimenti_rimanenti[i] > 0) {
      braccio2_attuale[i] = (braccio2_obiettivo[i] - braccio2_attuale[i]) / braccio2_movimenti_rimanenti[i] + braccio2_attuale[i];
      braccio2_movimenti_rimanenti[i] = braccio2_movimenti_rimanenti[i] - 1;
      //moveServos(braccio2_pins, braccio2_attuale);
    }
  }

  moveServos(braccio1_pins, braccio1_attuale);
  moveServos(braccio2_pins, braccio2_attuale);

  delay(20);

  if (Serial.available()) {
    String command = Serial.readStringUntil('\n');

    // Controllo comando per Braccio 1
    if (command.startsWith("1_")) {
      command.remove(0, 2);  // Rimuove "1_"
      int angles[6];
      parseCommand(command, angles);

      for (int i = 0; i < 6; i++) {
        braccio1_obiettivo[i] = angles[i];
        braccio1_movimenti_rimanenti[i] = numero_movimenti;
      }
    }

    // Controllo comando per Braccio 2
    else if (command.startsWith("2_")) {
      command.remove(0, 2);  // Rimuove "2_"
      int angles[6];
      parseCommand(command, angles);


      for (int i = 0; i < 6; i++) {
        braccio2_obiettivo[i] = angles[i];
        braccio2_movimenti_rimanenti[i] = numero_movimenti;
      }
    }
  }
}



// Funzione per convertire un angolo (0-180) in un valore di impulso
int angleToPulse(int angle, int numero_motore) {

    return map(angle, 0, 180, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
  
}

// Funzione per muovere i servomotori ai valori specificati
void moveServos(int pins[], int angles[]) {
  for (int i = 0; i < 6; i++) {
    int pulse = angleToPulse(angles[i], i);
    pca.writeMicroseconds(pins[i], pulse);
  }
}

// Funzione per parsare il comando e ottenere gli angoli
void parseCommand(String command, int angles[]) {
  for (int i = 0; i < 6; i++) {
    int index = command.indexOf('_');
    if (index == -1) index = command.length();
    angles[i] = command.substring(0, index).toInt();
    command.remove(0, index + 1);
  }
}

are the pulses correct ??

#define MIN_PULSE_WIDTH 650
#define MAX_PULSE_WIDTH 2350

i don't know. ask manufacturer or determine in an experiment. defaults are 1000-2000