Braccio Robotico ARM con Arduino

ATTENZIONE GUIDA NON DEFINITIVA

Braccio Robotico ARM con Arduino
Su internet si trovano diverse versioni di questo braccio.
Il nostro lo abbiamo realizzato basandoci sui progetti trovati qui.

Oltre alle parti da stampare con una stampante 3D
i materiali necessari per relaizzare il braccio robotico sono:
– 3 servomotori MG996R
– 3 servomotori MG92B
– 14 viti M2,3×10
– 2 viti M2,3×8
– 12 viti M3x12 a testa bombata per il legno
– 3 viti M3x18
– 4 viti M3x25
– 7 dadi M3 autobloccanti
-14 rondelle M3
– 1 scheda Arduino
– 1 scheda controllo motori con Chip PCA9685
– 1 regolatore di tensione DC – DC con Chip LM2596
– 1 alimentatore 9V – 5A
– 1 cavo con connettore 2,2 x 5,5 per alimentare la scheda Arduino
– 2 morsetti mammut
– 1 prolunga per servomotori di lunghezza 10, 15, 20 e 30 cm
– cavi Dupont vari per le connessioni tra le schede
– 1 base di legno di 315x220x10mm

Le parti in plastica per il braccio, riadattate secondo le nostre esigenze, sono le seguenti:
(cliccando sulla foto potrete scaricare lo zip con i file .stl di tutti i pezzi da stampare in 3D)

Iniziamo il montaggio…
Occorreranno i pezzi stampati visibili in fotografia e i 3 servomotori MG996R con i relativi accessori visibili in foto.
Montare i 3 servomotori sui supporti con le viti date in dotazione (fate attenzione durante il serraggio delle viti, in quanto sono fatte di un materiale morbido e se non utilizzate il giusto cacciavite si può rovinare la sede a croce rendendo impossibile terminare il montaggio o l’eventuale sostituzione di un motore danneggiato).
Il risultato sarà il seguente:

Montare i supporti plastici neri sui seguenti pezzi stampati 3D
(per farlo occorreranno 6 viti M2,3×10).

E questo sarà il risultato:

Adesso procediamo con il montaggio della parte elettrica…
Come visibile nella foto di seguito, saranno necessari: la base in legno (la nostra ha le dimensioni di 200 x 300 x 10 mm), la base del robot con il motore montato, 4 viti M2,3×10, 11 viti 3×12 per il legno, i telaietti stampati 3D per supporto schede, la scheda Arduino (abbiamo utilizzato la nostra Makerslab Nano Shield), la scheda controllo Motori con Chip PCA9685 e il regolatore di tensione DC – DC con Chip LM2596.
Nota: Il regolatore dovrà essere tarato in modo da far uscire una tensione di 5 Volt prima di collegarlo al modulo PCA9685.

Lo schema da noi utilizzato è il seguente:

Procediamo al montaggio come visibilie nella seguente foto:

A questo punto montiamo la base rotante.
Prima di bloccarla definitivamente però si dovranno trovare i parametri min e max da inviare al motore in modo che la base rotante andrà a 0°, 90° e 180°.
Questi paramteri andranno trovati per ogni motore che collegheremo alla scheda PCA9685.
Se volete capire il funzionamento della scheda PCA9685 potete leggere la nostra guida al seguente link:
https://www.makerslab.it/pca9685-controllo-i2c-a-16-canali-pwm-per-led-e-servomotori/

Alla fine di questa pagina troverete lo sketch per Arduino che noi abbiamo utilizzato per testare i motori e trovare i vari parametri di configurazione.

Una volta trovati i parametri le posizioni saranno le seguenti:

Montare il seguente pezzo:
Prima di bloccarlo definitivamente, come indicato precedentemente, si dovranno trovare i parametri min e max da inviare al motore in modo che la base rotante andrà a 0°, 90° e 180°.
Montare il seguente pezzo:

Prima di bloccarlo definitivamente, come indicato precedentemente, si dovranno trovare i parametri min e max da inviare al motore in modo che la base rotante andrà a 0°, 90° e 180°.

Adesso prendiamo il pezzo stampato 3D, visibile nella prossima foto, insieme ad un servomotore MG92B e le sue due viti di fissaggio.

Il servomotore andrà montato dentro il pezzo montato precedentemente.

Su quel pezzo si dovrà anche incollare il piccolo spessore stampato 3D con un goccia di colla cianoacrilica (come ad esempio Super Attack).

Il montaggio è quasi ultimato, ora occorrono i materiali della seguente foto:
il pezzo stampato 3D, 2 viti M2,3×10, il supporto in plastica e la vite di blocco per il servomotore MG92B.

Il supporto in plastica andrà tagliato come segue prima del montaggio
(alla fine del montaggio i supporti da tagliare saranno 3):

Ed il risultato sarà il seguente:

Ora fissiamolo al braccio bloccandolo con la vite rimasta.

Nota: prima di bloccarlo definitivamente, come indicato precedentemente, si dovranno trovare i parametri min e max da inviare al motore in modo che la base rotante andrà a 0°, 90° e 180°.

Ora occorrerà un altro servomotore SG92R con le sue viti di fissaggio:

Il servomotore andrà montato nel pezzo precedentemente fissato al braccio,
facendo prima passare il cavo nell’asola rettangolare:

Adesso non ci resta che montare la pinza.
Per farlo occorreranno le ultime parti in pastica stampate 3D, un servomotore  MG92R,
2 viti di fissaggio del motore, 2 supporti in plastica tagliati come da indicazioni precedenti,
2 viti per il bloccaggio del supporto in plastica al motore, 2 viti M2,3×10, 2 viti M2,3×8,
4 viti M3x25, 3 viti M3x18, 7 dadi M3 autobloccanti, 14 rondelle M3,
tutto come da immagine sottostante.

La pinza andrà montata come mostrato nell’immaggine seguente, avendo cura di trovare i giusti parametri Min e Max per far aprire e chiudere la pinza correttamente senza troppo sforzo sul motore e avendo cura di far passare il cavo del motore nell’apposita asola.

Una volta ultimato il montaggio della pinza la fisseremo al braccio avendo cura, come al solito, prima di bloccarla definitivamente, di trovare i parametri XXX min e max da inviare al motore in modo che la base rotante andrà a 0°, 90° e 180°.
Il montaggio del braccio è ultimato, ora si dovranno sistemare per bene i passaggi dei cavi dei motori in modo da non danneggiarli con i vari movimenti del braccio.
Per falo ci serviranno: 1 prolungha per sevomotori da 10 cm, 1 da 15 cm, una da 20 cm e una da 30 cm. Sono fatte come quella della foto seguente
(se non le recuperate potrete usare dei cavi Dupont Maschi-Femmina).

Questo è un esempio del passaggio dei cavi a lavoro ultimato.

Questo è lo sketch che abbiamo utilizzato per trovare i parametri dei servomotori da utilizzare con la libreria di  Adafruit, la Adafruit PWM Servo Driver Library.

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
// modificare il seguente rigo in base all'indirizzo i2c della propria scheda
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40);
// i parametri da inserire nella seguente scheda andranno trovati empiricamente
#define SERVO_FREQ 50

// questi sono i valori degli impulsi minimi e massimi da dare ai servomotori dopo averli rilevati
// Motore 10 - Base Rotante
#define SERVO10MIN  130
#define SERVO10MAX  510
// Motore 11 - Spalla
#define SERVO11MIN  125
#define SERVO11MAX  500
// Motore 12 - Gomito
#define SERVO12MIN  130
#define SERVO12MAX  505
// Motore 13 - Polso
#define SERVO13MIN  105
#define SERVO13MAX  475
// Motore 14 - Rotazione Pinza
#define SERVO14MIN  105
#define SERVO14MAX  475
// Motore 15 - Pinza
#define SERVO15MIN  110
#define SERVO15MAX  320

// variabili utilizzate per calcolare il segnale da inviare al servomotore in base ai parametri rilevati
int lungImpulso10, lungImpulso11, lungImpulso12, lungImpulso13, lungImpulso14, lungImpulso15;

void setup() {
  Serial.begin(9600);
  Serial.println("Test Braccio Robotico");

  pwm.begin();
  pwm.setOscillatorFrequency(27000000);
  pwm.setPWMFreq(SERVO_FREQ);
  delay(10);

  // il seguente rigo serve a calcolare la lunghezza dell'impulso da inviare al servomotore in base ai gradi scelti
  // basterà sostituire il 90 con il valore in gradi della posizione in cui dovrà andare il servomotore
  lungImpulso10 = map(90, 0, 180, SERVO10MIN, SERVO10MAX);
  // il seguente rigo invia l'impulso calcolato al servomotore scelto
  pwm.setPWM(10, 0, lungImpulso10);
  lungImpulso11 = map(90, 0, 180, SERVO11MIN, SERVO11MAX);
  pwm.setPWM(11, 0, lungImpulso11);
  lungImpulso12 = map(90, 0, 180, SERVO12MIN, SERVO12MAX);
  pwm.setPWM(12, 0, lungImpulso12);
  lungImpulso13 = map(90, 0, 180, SERVO13MIN, SERVO13MAX);
  pwm.setPWM(13, 0, lungImpulso13);
  lungImpulso14 = map(90, 0, 180, SERVO14MIN, SERVO14MAX);
  pwm.setPWM(14, 0, lungImpulso14);
  lungImpulso15 = map(90, 0, 180, SERVO15MIN, SERVO15MAX);
  pwm.setPWM(15, 0, lungImpulso15);
  delay(2000);
}
void loop() {
  /* elenco servomotori connessi
  servo su connettore 10 - Base rotante
  servo su connettore 11 - Spalla
  servo su connettore 12 - Gomito
  servo su connettore 13 - Polso
  servo su connettore 14 - Rotazione Pinza
  servo su connettore 15 - Pinza
  */
  // numero del servomotore da testare
  int motore = 14;
  // valore minimo da trovare
  int SERVOMIN = 105;
  // valore massimo da trovare
  int SERVOMAX = 475;

  int posizione;

  // posiziona il servo a 0 gradi
  posizione = map(0, 0, 180, SERVOMIN, SERVOMAX);
  pwm.setPWM(motore, 0, posizione);
  Serial.println("Posizione  0");
  Serial.print("Valore ");
  Serial.println(posizione);
  delay(3000);
  // posiziona il servo a 90 gradi
  posizione = map(90, 0, 180, SERVOMIN, SERVOMAX);
  pwm.setPWM(motore, 0, posizione);
  Serial.println("Posizione 90");
  Serial.print("Valore ");
  Serial.println(posizione);
  delay(6000);
  // posiziona il servo a 180 gradi
  posizione = map(180, 0, 180, SERVOMIN, SERVOMAX);
  pwm.setPWM(motore, 0, posizione);
  Serial.println("Posizione 180");
  Serial.print("Valore ");
  Serial.println(posizione);
  delay(3000);
  // posiziona il servo a 90 gradi
  posizione = map(90, 0, 180, SERVOMIN, SERVOMAX);
  pwm.setPWM(motore, 0, posizione);
  Serial.println("Posizione 90");
  Serial.print("Valore ");
  Serial.println(posizione);
  delay(6000);
}

Controllo del Braccio tramite modulo Bluetooth e App per Android
Una volta trovati tutti i parametri da inviare alla scheda PCA9685 per posizionare correttamente ogni motore possiamo dotare il nostro braccio di un modulo Bluetooth HC-05 o HC-06.
(Una guida sul funzionamento dei moduli Bluetooth con Arduino
la potrete trovare alla pagina:
https://www.makerslab.it/i-moduli-hc-05-e-hc-06-con-arduino/ )
Per aggiungere questa funzionalità occorreranno i seguenti materiali:
Modulo Bluetooth, 2 viti M2,3×10, un supporto in plastica per tenere fermo il modulo Bluetooth e dei cavetti Maschio / Femmina per i collegamenti.
Lo schema di collegamento è visibile all’inizio di questa guida.
Abbiamo scelto di collegare il modulo Bluetooth ai pin 11 e 12 ed utilizzare una seriale software per lasciare libera la seriale hardware di Arduino per ulteriori programmazioni, altrimenti ogni volta che vogliamo inviare un programma ad Arduino seremo costretti a disconnettere il modulo Bluetooth.
Per controllare il robot abbiamo crato un’apposita App per Android:
la Makerslab Arm Robot Control
la cui documentazione è visibile alla pagina:
https://www.makerslab.it/makerslab-arm-robot-control-app/

Lo sketch da caricare sull’Arduino è il seguente:

/*
   Sketch per gestire un braccio con 6 servomotori
   utilizzando schede basate sul chip I2C PCA9685
   Per inviare la nuova posizione usare:
   setPosizioni(velocità, servo1 , servo2, servo3, servo4, servo5, servo6);
   Es: setPosizioni(20, 90, 180, 0, 75, 60, 180);
   valori accettati:
   - Velocità movimenti da 5 (veloce) a 30 (lento)
   - Servomotori da 0 a 180
*/
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
#include <SoftwareSerial.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40); //indirizzo I2C della scheda
#define SERVO_FREQ 50

#define servo1 10 // Base Rotante
#define servo2 11 // Spalla
#define servo3 12 // Gomito
#define servo4 13 // Polso
#define servo5 14 // Rotazione Pinza
#define servo6 15 // Pinza
// questi sono i valori degli impulsi minimi e massimi da dare ai servomotori.
#define SERVO1MIN  130
#define SERVO1MAX  510
#define SERVO2MIN  125
#define SERVO2MAX  500
#define SERVO3MIN  130
#define SERVO3MAX  505
#define SERVO4MIN  105
#define SERVO4MAX  475
#define SERVO5MIN  105
#define SERVO5MAX  475
#define SERVO6MIN  110
#define SERVO6MAX  320
// posizioni da inviare al braccio
int PP1 = 90, PP2 = 90, PP3 = 90, PP4 = 90, PP5 = 90, PP6 = 90;
// variabili per raggiougere le posizioni inviate al braccio
int posizione1, posizione2, posizione3, posizione4, posizione5, posizione6;
// Salva l'ultima posizione chiamata
int posPrec1 = 90, posPrec2 = 90, posPrec3 = 90, posPrec4 = 90, posPrec5 = 90, posPrec6 = 90;
// array per memorizzare velocità e posizioni da eseguire automaticamente
int speedSalva[50], posSalva1[50], posSalva2[50], posSalva3[50], posSalva4[50], posSalva5[50], posSalva6[50];
int index = -1; // indice dell'array
int Speed = 13; // velocità predefinita
char data; // variabile dove salvare il dato ricevuto via Bluetooth
SoftwareSerial Bluetooth(12, 11); // Seriale virtuale per il modulo Bluetooth (Arduino(RX, TX)/HC-05 Bluetooth (TX, RX))

void setup() {
  Serial.begin(9600);
  Serial.println("Test Braccio Robotico");
  Bluetooth.begin(9600);
  Bluetooth.flush();
  pwm.begin();
  pwm.setOscillatorFrequency(27000000);
  pwm.setPWMFreq(SERVO_FREQ);
  delay(10);

  // posizionamento iniziale del braccio
  posizione1 = map(90, 0, 180, SERVO1MIN, SERVO1MAX);
  pwm.setPWM(servo1, 0, posizione1);
  posizione2 = map(90, 0, 180, SERVO2MIN, SERVO2MAX);
  pwm.setPWM(servo2, 0, posizione2);
  posizione3 = map(90, 0, 180, SERVO3MIN, SERVO3MAX);
  pwm.setPWM(servo3, 0, posizione3);
  posizione4 = map(90, 0, 180, SERVO4MIN, SERVO4MAX);
  pwm.setPWM(servo4, 0, posizione4);
  posizione5 = map(90, 0, 180, SERVO5MIN, SERVO5MAX);
  pwm.setPWM(servo5, 0, posizione5);
  posizione6 = map(90, 0, 180, SERVO6MIN, SERVO6MAX);
  pwm.setPWM(servo6, 0, posizione6);
  delay(2000);
}

void loop() {
  if (Bluetooth.available() > 0) {
    data = Bluetooth.read();
    delay(3);
  }
  switch (data) { // compara il dato ricevuto via Bluetooth
    case 'M':
      Serial.println("sono in m");
      data = 0;
      break;
    case 'S': // decrementa di 1 la posizione del Servo6
      PP6 -= 1;
      if (PP6 <= 0) {
        PP6 = 0;
      }
      Serial.println(PP6);
      setPosizioni(Speed, PP1, PP2, PP3, PP4, PP5, PP6);
      break;
    case 's': // incrementa di 1 la posizione del Servo6
      PP6 += 1;
      if (PP6 >= 180) {
        PP6 = 180;
      }
      Serial.println(PP6);
      setPosizioni(Speed, PP1, PP2, PP3, PP4, PP5, PP6);
      break;
    case 'C': // decrementa di 1 la posizione del Servo5
      PP5 -= 1;
      if (PP5 <= 0) {
        PP5 = 0;
      }
      Serial.println(PP5);
      setPosizioni(Speed, PP1, PP2, PP3, PP4, PP5, PP6);
      break;
    case 'c': // incrementa di 1 la posizione del Servo5
      PP5 += 1;
      if (PP5 >= 180) {
        PP5 = 180;
      }
      Serial.println(PP5);
      setPosizioni(Speed, PP1, PP2, PP3, PP4, PP5, PP6);
      break;
    case 'Q': // decrementa di 1 la posizione del Servo4
      PP4 -= 1;
      if (PP4 <= 0) {
        PP4 = 0;
      }
      Serial.println(PP4);
      setPosizioni(Speed, PP1, PP2, PP3, PP4, PP5, PP6);
      break;
    case 'q': // incrementa di 1 la posizione del Servo4
      PP4 += 1;
      if (PP4 >= 180) {
        PP4 = 180;
      }
      Serial.println(PP4);
      setPosizioni(Speed, PP1, PP2, PP3, PP4, PP5, PP6);
      break;
    case 'T':  // decrementa di 1 la posizione del Servo3
      PP3 -= 1;
      if (PP3 <= 0) {
        PP3 = 0;
      }
      Serial.println(PP3);
      setPosizioni(Speed, PP1, PP2, PP3, PP4, PP5, PP6);
      break;
    case 't': // incrementa di 1 la posizione del Servo3
      PP3 += 1;
      if (PP3 >= 180) {
        PP3 = 180;
      }
      Serial.println(PP3);
      setPosizioni(Speed, PP1, PP2, PP3, PP4, PP5, PP6);
      break;
    case 'D': // decrementa di 1 la posizione del Servo2
      PP2 -= 1;
      if (PP2 <= 0) {
        PP2 = 0;
      }
      Serial.println(PP2);
      setPosizioni(Speed, PP1, PP2, PP3, PP4, PP5, PP6);
      break;
    case 'd': // incrementa di 1 la posizione del Servo2
      PP2 += 1;
      if (PP2 >= 180) {
        PP2 = 180;
      }
      Serial.println(PP2);
      setPosizioni(Speed, PP1, PP2, PP3, PP4, PP5, PP6);
      break;

    case 'U': // decrementa di 1 la posizione del Servo1
      PP1 -= 1;
      if (PP1 <= 0) {
        PP1 = 0;
      }
      Serial.println(PP1);
      setPosizioni(Speed, PP1, PP2, PP3, PP4, PP5, PP6);
      break;
    case 'u': // incrementa di 1 la posizione del Servo1
      PP1 += 1;
      if (PP1 >= 180) {
        PP1 = 180;
      }
      Serial.println(PP1);
      setPosizioni(Speed, PP1, PP2, PP3, PP4, PP5, PP6);
      break;
    case 'X': // salva le posizioni attuali nei relativi array
      Serial.println("salva");
      if (index < 50) {
        index++;                   // Incremento dell'indice dell'array
        speedSalva[index] = Speed; // Salvataggio velocità e posizioni in un array
        posSalva1[index] = PP1;
        posSalva2[index] = PP2;
        posSalva3[index] = PP3;
        posSalva4[index] = PP4;
        posSalva5[index] = PP5;
        posSalva6[index] = PP6;
        Serial.print("Posizione salvata = ");
        Serial.println(index);
      }
      data = 0;
      break;
    case 'E': // muove il braccio nelle posizioni salvate negli array
      Serial.println("esegui");
      if (index > -1) {
        for (int x = 0; x <= index; x++) {
          Serial.print("Posizione estratta = ");
          Serial.println(x);
          Speed = speedSalva[x]; // Estrazione velocità e posizioni dall'array
          PP1 = posSalva1[x];
          PP2 = posSalva2[x];
          PP3 = posSalva3[x];
          PP4 = posSalva4[x];
          PP5 = posSalva5[x];
          PP6 = posSalva6[x];
          setPosizioni(Speed, PP1, PP2, PP3, PP4, PP5, PP6); // Movimento braccio
          delay (300);
        }
      }
      else Serial.print("Nessuna posizione salvata");
      data = 0;
      break;
    case 'H': // muove il braccio nella posizione di Home
      Serial.println("Home");
      PP1 = 90; PP2 = 90; PP3 = 90; PP4 = 90; PP5 = 90; PP6 = 90;
      setPosizioni(Speed, PP1, PP2, PP3, PP4, PP5, PP6);
      data = 0;
      break;
    case 'Z': // azzera l'indice dell'array e muove il braccio nella posizione di Home
      Serial.println("resetta");
      Speed = 13; PP1 = 90; PP2 = 90; PP3 = 90; PP4 = 90; PP5 = 90; PP6 = 90;
      delay (500);
      setPosizioni(Speed, PP1, PP2, PP3, PP4, PP5, PP6);
      index = -1;
      data = 0;
      break;
    case '1': // imposta la velocità
      Speed = 5;
      data = 0;
      break;
    case '2': // imposta la velocità
      Speed = 8;
      data = 0;
      break;
    case '3': // imposta la velocità
      Speed = 10;
      data = 0;
      break;
    case '4': // imposta la velocità
      Speed = 13;
      data = 0;
      break;
    case '5': // imposta la velocità
      Speed = 16;
      data = 0;
      break;
    case '6': // imposta la velocità
      Speed = 19;
      data = 0;
      break;
    case '7': // imposta la velocità
      Speed = 21;
      data = 0;
      break;
    case '8': // imposta la velocità
      Speed = 25;
      data = 0;
      break;
    case '9': // imposta la velocità
      Speed = 30;
      data = 0;
      break;
  }
  Bluetooth.flush();
}

void setPosizioni(int velocita, int pos1, int pos2, int pos3, int pos4, int pos5, int pos6) {
  // prima di eseguire la funzione si controllano i parametri passati per evitare valori fuori dai limiti
  if (velocita > 30) velocita = 30;
  if (velocita < 5) velocita = 5;
  if (pos1 < 0) pos1 = 0;
  if (pos1 > 180) pos1 = 180;
  if (pos2 < 0) pos2 = 0;
  if (pos2 > 180) pos2 = 180;
  if (pos3 < 0) pos3 = 0;
  if (pos3 > 180) pos3 = 180;
  if (pos4 < 0) pos4 = 0;
  if (pos4 > 180) pos4 = 180;
  if (pos5 < 0) pos5 = 0;
  if (pos5 > 180) pos5 = 180;
  if (pos6 < 0) pos6 = 0;
  if (pos6 > 180) pos6 = 180;
  int ciclo = 1;
  //questo ciclo viene eseguito fino a quanto tutti i motori non sono arrivati alla posizione stabilita
  while (ciclo)
  {
    //Per ogni servomotore, se il grado successivo non è uguale al precedente, si esegue il movimento

    if (pos1 != posPrec1) {  //---- Servo1 -----
      posizione1 = map(posPrec1, 0, 180, SERVO1MIN, SERVO1MAX);
      pwm.setPWM(servo1, 0, posizione1);
      //Un passo avanti
      if (pos1 > posPrec1) {
        posPrec1++;
      }
      //Un passo indietro
      if (pos1 < posPrec1) {
        posPrec1--;
      }
    }
    if (pos2 != posPrec2) {  //---- Servo2 -----
      posizione2 = map(posPrec2, 0, 180, SERVO2MIN, SERVO2MAX);
      pwm.setPWM(servo2, 0, posizione2);
      //Un passo avanti
      if (pos2 > posPrec2) {
        posPrec2++;
      }
      //Un passo indietro
      if (pos2 < posPrec2) {
        posPrec2--;
      }
    }
    if (pos3 != posPrec3) {  //---- Servo3 -----
      posizione3 = map(posPrec3, 0, 180, SERVO3MIN, SERVO3MAX);
      pwm.setPWM(servo3, 0, posizione3);

      //Un passo avanti
      if (pos3 > posPrec3) {
        posPrec3++;
      }
      //Un passo indietro
      if (pos3 < posPrec3) {
        posPrec3--;
      }
    }

    if (pos4 != posPrec4) {  //---- Servo4 -----
      posizione4 = map(posPrec4, 0, 180, SERVO4MIN, SERVO4MAX);
      pwm.setPWM(servo4, 0, posizione4);
      //Un passo avanti
      if (pos4 > posPrec4) {
        posPrec4++;
      }
      //Un passo indietro
      if (pos4 < posPrec4) {
        posPrec4--;
      }
    }
    if (pos5 != posPrec5) {  //---- Servo5 -----
      posizione5 = map(posPrec5, 0, 180, SERVO5MIN, SERVO5MAX);
      pwm.setPWM(servo5, 0, posizione5);
      //Un passo avanti
      if (pos5 > posPrec5) {
        posPrec5++;
      }
      //Un passo indietro
      if (pos5 < posPrec5) {
        posPrec5--;
      }
    }
    if (pos6 != posPrec6) {  //---- Servo6 -----
      posizione6 = map(posPrec6, 0, 180, SERVO6MIN, SERVO6MAX);
      pwm.setPWM(servo6, 0, posizione6);
      //Un passo avanti
      if (pos6 > posPrec6) {
        posPrec6++;
      }
      //Un passo indietro
      if (pos6 < posPrec6) {
        posPrec6--;
      }
    }
    delay(velocita);     //ritardo tra ogni movimento
    //Verifica se tutti i servomotori sono nella posizione desiderata
    if ((pos1 == posPrec1) && (pos2 == posPrec2)
        && (pos3 == posPrec3) && (pos4 == posPrec4)
        && (pos5 == posPrec5) && (pos6 == posPrec6)) {
      // si salvano le posizioni attuali come posizioni precedenti
      posPrec1 = pos1;
      posPrec2 = pos2;
      posPrec3 = pos3;
      posPrec4 = pos4;
      posPrec5 = pos5;
      posPrec6 = pos6;
      ciclo = 0; // e si esce dal ciclo while
    } else { // altrimenti si resta nel ciclo while in attesa di raggiungere tutte le posizioni indicate
      ciclo = 1;
    }
  }
}

Il funzionamento dello sketch è il seguente:
l’app invia dellle lettere in base ai pulsanti premuti.
Quando si muove il braccio manualmente si può muovere un servomotore alla volta.

Tramite lo slide si potrà sceglere la velocità dei motori.

Arrivati alla posizione desiderata si può salvare la posizione di tutti i motori con il pulsante “Salva Punto”.
Il pulsante “Vai Home” serve a far tornare in posizione iniziale il braccio (nello sketch abbiamo scelto di andare con tutti i sorvomotori a 90°, ma ogniuno può personalizzare la posizione di Home come vuole).
Se viene salvata almeno una posizione sarà possibile far muovere il braccio nelle posizioni salvate con il pulsante “Esegui”.
A braccio fermo potranno essere aggiunte nuove posizioni.
Con il pulsante “Reset” verranno cancellate tutte lo posizioni salvate ed il braccio tornerà in posizione di Home.
Sotto i pulanti vedremo quanti posizioni abbiamo salvato.