New project automaton hat

Hi everyone, thanks for giving me some advice. I'm designing a hat with movable surfaces like feathers that will go up and down... the hardware is made up of a 3S 2500mah 11.1V lipo battery connected to a ZK4XK converter, Arduino Pro Mini, PCA9685 which moves around ten SG90 servomotors which only move 90 degrees max on purpose. I would like to be able to move the servo from the rest position or arm perpendicular to the body of the servo, to the UP position, arm parallel to the servo, via BT commands using an HC05 connected to the Arduino Pro Mini.
Deep search helped me compile a sketch that doesn't seem to work because the servos go to rest position as soon as I power up the circuit (I only powered 3 of them to test), the app communicates via BT but the servos don't respond to the commands given. Here is the sketch and some photos of the connections. What did I do wrong?

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

// Configurazione PCA9685
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

// Configurazione Bluetooth
#include <SoftwareSerial.h>
SoftwareSerial BT(3, 2); // RX, TX (puoi cambiare i pin se necessario)

// Numero di servomotori
const int NUM_SERVOS = 15;

// Posizioni dei servo (in gradi)
const int POS_RIposo = 0;   // Piume giù (perpendicolare al corpo)
const int POS_SU = 90;      // Piume su (parallelo al corpo)

// Velocità di movimento (ms tra i passi)
const int VELOCITA = 15;

// Mappatura dei servo sul PCA9685 (da 0 a 15)
const int servoPins[NUM_SERVOS] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};

// Variabile per lo stato corrente
int currentPos[NUM_SERVOS];

void setup() {
  // Inizializzazione seriale per debug
  Serial.begin(9600);
  Serial.println("Cappello Robotico - Inizializzazione");

  // Inizializzazione Bluetooth
  BT.begin(9600);

  // Inizializzazione PCA9685
  pwm.begin();
  pwm.setPWMFreq(60);  // Frequenza PWM per servomotori (60Hz)

  // Imposta tutti i servo a POS_RIposo all'avvio
  for (int i = 0; i < NUM_SERVOS; i++) {
    setServoAngle(i, POS_RIposo);
    currentPos[i] = POS_RIposo;
  }

  Serial.println("Pronto per i comandi (R=riposo, S=su)");
}

void loop() {
  // Controllo Bluetooth
  if (BT.available()) {
    char comando = BT.read();
    processCommand(comando);
  }

  // Controllo Seriale (per debug)
  if (Serial.available()) {
    char comando = Serial.read();
    processCommand(comando);
  }
}

void processCommand(char comando) {
  switch (comando) {
    case 'R':
    case 'r':
      Serial.println("Comando: Piume a riposo");
      muoviTuttiServo(POS_RIposo);
      break;

    case 'S':
    case 's':
      Serial.println("Comando: Piume su");
      muoviTuttiServo(POS_SU);
      break;

    default:
      Serial.print("Comando non riconosciuto: ");
      Serial.println(comando);
      break;
  }
}

void muoviTuttiServo(int targetPos) {
  // Muove tutti i servo alla posizione target in modo sincronizzato
  bool inMovimento;

  do {
    inMovimento = false;

    for (int i = 0; i < NUM_SERVOS; i++) {
      if (currentPos[i] != targetPos) {
        inMovimento = true;

        if (currentPos[i] < targetPos) {
          currentPos[i]++;
        } else {
          currentPos[i]--;
        }

        setServoAngle(i, currentPos[i]);
      }
    }

    if (inMovimento) {
      delay(VELOCITA);
    }
  } while (inMovimento);
}

void setServoAngle(int servoNum, int angle) {
  // Converte l'angolo in impulso PWM per SG90
  // SG90 tipicamente usa ~500ms per 0° e ~2500ms per 180°
  // PCA9685 ha una risoluzione di 4096 per 20ms (50Hz)

  angle = constrain(angle, 0, 180);
  int pulse = map(angle, 0, 180, 150, 600); // Valori empirici per SG90
  pwm.setPWM(servoPins[servoNum], 0, pulse);
}

![1745075072628|666x500](upload://uj3S9KaRF8XFREjoWlgCRCXGEXV.jpeg)
![1745075072643|666x500](upload://mGaK5O2KgW9uBeb7Iw9S3vtYEKx.jpeg)
![1745075072660|666x500](upload://pqDcp0mlBwB9b2KCpenT1UNHoJ0.jpeg)

to conclude there is power to everything, bt communicates and responds, the servos only move the first time in the sense that they go into the rest position if the arm is moved as a first installation.

Do you see your debug printing when sending commands ?

Good morning, yes i see it

the app communicates and responds with the bt module. Among other things, by programming in loop the servos move. But programming with bt communication nothing.
Maybe the problem is that I haven't connected the vcc and gnd of the pca9685 directly to the arduino...or there is a problem between the hc05 and the arduino pro mini 5v

You need to share GND

Doesn't your level translator need 5V (HV) and 3.3V (LV) power?
Also I'm not sure that the pro mini 5V will work with 5V on the RAW input.

Yes, I'm using the level converter because the bt hc05 would burn with 5v from the Arduino... referring to RAW instead, it's working well because everything is turned on and powered. I think it's a communication problem. Because the servos move, by default they go to the rest position, but then they don't move under the commands of the bt... :smiling_face_with_tear:

ok thanks, are you telling me that I have to connect the GND between pca9685 and arduino? but do I also ask you for the VCC? because with Arduino Pro Mini I seem to have run out of VCC on the board. GND instead there are

Yes all the GND of the ICs need to be shared and of course you need to power all modules… use a breadboard if you want to make it easy to have a power / GND rail so that you can have multiple easy connections (but don’t power anything demanding like a motor from your small arduino)

It's not shown in your schematic.
Are there other missing connections?

Since I don't have space problems, which Arduino would you recommend for this project, Arduino 1 or other?

I have no idea, apart from the gnd which is not shared but is connected directly to the negative of the battery... everything is connected and powered as demonstrated by the lit LEDs of the devices... the Arduino communicates with the servos and in fact the servos execute the rest position as per the sketch, at the first power on... the phone app communicates with the BT and vice versa but the servos do not respond to the commands given..

Nothing wrong with the pro mini but you will find a lot more information on the internet regarding the use of an Uno

If you only move one servo at a time and if the servo load is light like a feather, you can probably eliminate the PCA9685, the big buck converter, and the big battery.
In any case you can eliminate the voltage translator and just use a 2 resistor voltage divider on the HC05 RX line.

I need to be able to move the 15 servos at the same time so I need those components...anyway one of the mistakes I made was that the common GND was not true, furthermore I could use the Arduino's rx tx as a connection to the hc 05, with a level converter

OK, in your original post you said 10

anyway one of the mistakes I made was that the common GND was not true

In your schematic I see all grounds connected.
Is that schematic actually how you have thing connected?

furthermore I could use the Arduino's rx tx as a connection to the hc 05, with a level converter

Well again I see no connections to 5V and 3.3V for your level converter in your schematic.

So again I have to ask does the schematic actually show how you have things connected?

yes, that's the diagram, in fact now I'll post photos of the connections... I used a logic level converter, it's hard to see but it's there, and I just noticed that the GND of the converter is not connected to the common GND... could that be the problem?



With all the discussion of grounds, DO NOT use the same wire to connect the servo grounds as any other ground! Connect the other grounds to the servo power ground at only ONE point!