Problema regolazione velocità di posizionamento servomottori

Buongiorno a tutti,

sono uno studente che per la maturità sta provando a progettare un braccio robotico munito principalmente di tre servomotori (rotazione di 180°) che permettono di posizionarsi lungo un piano. Dopo aver fallito miseramente nel tentativo di posizionare il braccio inserendo le coordinate finali (a causa di errori intrinsechi e irresolubili, credo) mi sono accontentato di indicare io stesso l'angolo di rotazione del servomotore scegliendo il punto finale. Ora, se inserissi la posizione dei tre servomotori che compongono il braccio , l'alta velocità che assumono i servomotori causerebbe danni alle giunture portando alla rottura delle stesse. Ho provato a posizionare il braccio gradualmente con l'ausilio di ciclo for che però hanno il difetto di far ruotare i singoli motori in cascata(prima quello al centro, poi la base ed infine l'ultimo arto). Ho provato allora a creare un codice che con un solo ciclo for posizionasse simultaneamente i tre servomotori nonostante avessero angoli differenti, ma nonostante ciò il braccio si comporta come con i cicli separati in cascata. Ecco il codice:

/*Con il seguente codice dovrebbe essere possibile posizionare un braccio robotico fornito di servomotori muovendo tutti i sevomotori contemporaneamente sebbene gli angoli 
 *di posizionamento siano diversi senza però far muovere i servomotori di scatto per non rompere le giunture. 
*/

#include <Servo.h>        //include nel codice la libreria Servo.h

Servo myservo1;           //inizializza il nome dei servomotori
Servo myservo2;
Servo myservo3;

int n=2;                  //MOLTO IMPORTANTE: n deve avere lo stesso valore delle colonne della matrice
int posizione [3] [2]{    //inizializzo la matrice delle posizioni 3=costante indica le righe, il secondo è variabile al numero di punti impostati
  {41, 71},               //tutte le coordinate di a1
  {124, 98},              //tutte le coordinate di a2
  {10, 6}                 //tutte le coordinate di a3
};

int vel=20;               //delay tra un passo e un altro nei servomotori
int a1=0;                 //inizializzo l'angolo che il motore 1 dovrà prendere
int a2=0;                 //inizializzo l'angolo che il motore 2 dovrà prendere
int a3=0;                 //inizializzo l'angolo che il motore 3 dovrà prendere
int riga, cella, colonna; //inizializzo le variabili di lettura della matrice

int i, p,p1, pos;         //inizializzo le variabili che servono durante lo spostamento dei bracci

int pos1=0;               //inizializzo le variabili che indicano le posizioni attuali dei servomotori con le rispettive posizioni di partenza
int pos2=180;             
int pos3=90;

void setup() {
Serial.begin(9600);       //inizializziamo la frequenza di commutazione con il serial monitor

myservo3.attach(5);       //inizializzo il pin a cui è connesso il servo 3
myservo2.attach(3);       //inizializzo il pin a cui è connesso il servo 2
myservo1.attach(2);       //inizializzo il pin a cui è connesso il servo 1

myservo1.write(pos1);     //posiziono i servo nella posizione di partenza
myservo2.write(pos2);
myservo3.write(pos3);
}

void loop() {
  for(colonna=0; colonna<n; colonna++){     //inizializzo il primo ciclo for per leggere le colonne della matrice
    for(riga=0; riga<3; riga++){            //inizializzo il primo ciclo for per leggere le righe della matrice
      cella=posizione[riga][colonna];       //leggo il valore della cella
      switch (riga){                        //posiziono il valore letto nell'angolo a seconda del numero della righa
      case 0:
        a1=cella;
        break;
      case 1:
        a2=cella;
        break;
      case 2:
        a3=cella;
        break;
      }
      
      for(p=0; p<180;p++){              //inizia il ciclo per regolare la velocità con cui i servomotori si posizionano
        p1=180-p;                       //inverto il valore dell'angolo per facilizzare i conti
        
        pos=myservo1.read();            //leggo la posizione del servo 1
        if(pos!=a1){                    //se la posizione del motore coincide con la posizione che deve prendere non vengono apportate modifiche
          if(a1>pos1){                  //se la posizione che deve prendere è maggiore della posizione che ha, allora:
            if(p>=pos1){                //solo se il valore del contattore raggiunge o è maggiore di quello del servo allora:
              myservo1.write(p);        //posiziona il servo allo stesso valore di del ciclo for
              delay(vel);               //aspetta per t=vel
            }
          }
          if(a1<pos1){                  //se la posizione che deve prendere è minore della posizione che ha, allora:
            if(p1<=pos1){               //solo se il valore del contattore raggiunge o è minore di quello del servo allora:
              myservo1.write(p1);       //posiziona il servo allo stesso valore di del ciclo for
              delay(vel);               //aspetta per t=vel
            }
          }
        }
        
        pos=myservo2.read();            //esegue gli stessi passaggi del servo 1
        if(pos!=a2){
          if(a2>pos2){
            if(p>=pos2){
              myservo2.write(p);
              delay(vel);
            }
          }
          if(a2<pos2){
            if(p1<=pos2){
              myservo2.write(p1);
              delay(vel);
            }
          }
        }

        pos=myservo3.read();            //esegue gli stessi passaggi del servo 1
        if(pos!=a3){
          if(a3>pos3){
            if(p>=pos3){
              myservo3.write(p);
              delay(vel);
            }
          }
          if(a3<pos3){
            if(p1<=pos3){
              myservo3.write(p1);
              delay(vel);
            }
          }
        }
      }                                 //fine ciclo per la velocità dei servo
        pos1=a1;                        //pone la posizione attuale uguale a quella che doveva prendere prima del ciclo
        pos2=a2;
        pos3=a3;
    }
    delay(500);                         //aspetta un tempo t prima di cominciare la lettura del punto sucessivo
  }                                     //fine ciclo lettura delle posizioni nella matricce
}

Dopo questa lunga introduzione la mia domanda è: esiste una libreria, un codice o un comando che mi permetta di selezionare, oltre che alla posizione del servomotore, anche la velocità con cui quest'ultimo esegue il movimento?
Ho provato a cercare in rete ma non ho trovato soluzioni di tipo software. Se mi fossi lasciato perdere una conversazione mi scuso.

Aspetto pazientemente risposta. Buona giornata,
Elia

Secondo me il programma è inutilmente complesso.
Comunque non c'è modo di sincronizzare i tre servo e non esistono controlli della velocità dei servo.

Risolvi con due cicli for uno per ogni posizionamento

Esempio primo ciclo for, primo posizionamento

for(int i=0;i<180;i++){// Un ciclo che ripete per i massimi posizionamenti possibili

    if(servo1.read()<posizione[0][0]){
  
         servo1.write(servo1.read()+1);

    }else if(servo1.read()>posizione[0][0]){

         servo1.write(servo1.read()-1);

    }


    if(servo2.read()<posizione[1][0]){
  
         servo2.write(servo2.read()+1);

    }else if(servo2.read()>posizione[1][0]){

         servo2.write(servo2.read()-1);

    }

    if(servo3.read()<posizione[2][0]){
  
         servo3.write(servo3.read()+1);

    }else if(servo3.read()>posizione[2][0]){

         servo3.write(servo3.read()-1);

    }

    delay(100); // Mettere pausa adeguata

}

Ho appena provato il codice e funziona! Probabilmente quello che avevo fatto io aveva un bug. Grazie mille e, si, purtroppo penso sempre in modo molto complesso

>doraimon: Quando si quota un post, NON è necessario riportarlo (inutilmente) tutto; bastano poche righe per far capire di cosa si parla ed a cosa ci si riferisce, inoltre, se si risponde al post immediatamente precedente, normalmente NON è necessario alcun "quote" dato che è sottinteso. :slight_smile:

Gli utenti da device "mobile" (piccoli schermi) ringrazieranno per la cortesia :wink:

Guglielmo

P.S.: Ho eliminato io il "quote" dal tuo post qui sopra :wink: