Salve a tutti , grazie per chi mi darà un consiglio. Sto progettando un cappello con delle superfici mobili tipo piume che andranno su e giù... l' hardware è composto da batteria lipo 3s 2500mah 11.1 V collegato a convertitore zk4xk, arduino pro mini , pca9685 che muove una decina di servomotori sg90 che muovono solo di 90gradi max volutamente. Vorrei poter muovere i servo dalla posizione di riposo ovvero braccio perpendicolare al corpo servo , alla posizione piume SU, braccio parallelo al servo, tramite comandi bt usando un hc05 collegato all arduino pro mini.
Deep seek mi ha aiutato a compilare uno sketch che pare non funzioni perchè i servo vanno in posizione di riposo appena alimento il circuito (ne ho alimentati solo 3 per provare), l app comunica via bt ma i servo non rispondono ai comandi impartiti. Ecco lo sketch e alcune foto dei collegamenti. Cosa ho sbagliato ?
#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);
}
per concludere c'è alimentazione a tutto , bt comunica e risponde , i servo si muovono solo la prima volta nel senso vanno in posizione di risposo se il braccio è spostato come prima installazione.




