Come fare per muovere un servo di 10° in 10 secondi in modo continuo?

Ciao a tutti,

sto pilotando un servo con arduino 2009. Vorrei fargli fare un movimento di 10° in 10 secondi. Purtroppo però il movimento va a scatti....io vorrei che fosse continuo. E' colpa del servo che non ce la fa a gestire tale movimento? (in realtà scatta anche a 45° e 10 secondi....a 60°, il movimento non è piu cosi scattoso).

Qui c'è parte dello sketch:
...
myservo.write(10);
delay(1000);
...

Avevo letto che si potrebbe usare la funzione:
myservo.writeMicroseconds(X);

Secondo voi è possibile migliorare le prestazioni o devo lasciar perdere?

Grazie!!!

Io non ho capito sinceramente il problema. Devi far muovere il servo di 10gradi in 10sec. Però è scatto.. Se te scrivi

Myservo.write(10)
Delay(1000)

Vuol dire ke ti sei spostato a 10 e hai aspettato un secondo..

Potresti fare invece,

Count=0;
While((count++)>10){
Myservo.write(count);
Delay(1000);
}

Non so se funziona xo.. Prova

Se vuoi fare muovere un Servo a piccoli passi in tempi lunghi devi pilotarlo in piccoli passi.

for (int a=10; a>20;a++)
{
Myservo.write(a);
Delay(1000);
}

Ciao Uwe

ciao, scusate ma mi sono espresso male.

Il mio obiettivo è muovere un servo motore di 10° (es. da 0° a 10°) con un movimento che sia continuo e non scattoso. Per non scattoso intendo che il delay (che solo ora ho capito essere la pausa tra un movimento e l'altro del servo) dovrebbe essere diciamo...zero. Cioè, non voglio che il servo faccia una pausa tra uno scatto e l'altro (delay=1000 vuol dire che fa pausa di 1 secondo) ma proprio che il movimento sia continuo.

Spero di essermi spiegato.....

Grazie!!

for (int a=0; a>10;a+=0.000001)
{
Myservo.write(a);
Delay(10);
}

Non so se vanno bene decimali x una servo write.. Ma x ora è l'unica idea ke mi viene in mente.. Il processore andando a 16MHz dovrebbe fare più o meno 16 milioni di istruzioni al secondo.. Facendo un loop così forse riesci a fargli fare tutte le istruzioni.. Non potendo dare la velocità del motore devi simulare un "potenziometro" in qualche modo.:slight_smile:

ci ho gia pensato ma non si puo fare perche write accetta solo valori int...

:drooling_face:

crystal13:
ciao, scusate ma mi sono espresso male.

Il mio obiettivo è muovere un servo motore di 10° (es. da 0° a 10°) con un movimento che sia continuo e non scattoso. Per non scattoso intendo che il delay (che solo ora ho capito essere la pausa tra un movimento e l'altro del servo) dovrebbe essere diciamo...zero. Cioè, non voglio che il servo faccia una pausa tra uno scatto e l'altro (delay=1000 vuol dire che fa pausa di 1 secondo) ma proprio che il movimento sia continuo.

Spero di essermi spiegato.....

Grazie!!

La precisione del Servo non é cosí grande da poter fare dei passi infinitesimamente piccoli.
Se usi servo.writeMicroseconds(uS) puoi dare valori da 1000 a 2000 percui 1000 passi; mentre con servo.write(angle) dai dei angoli da 0 a 180, percui 180 passi.

@mancio
Hai provato quel codice proposto?
Sai cosa succede se a un int sommi un numero decimale? rest lo stesso numero percui hai creato un bel ciclo infinito.

Ciao Uwe

si l'ho scritto stanotte dal tablet e mi sono accorto che serviva un float.. :grin: :grin:

Lo standard per i servo RC è che la loro posizione deve essere aggiornata ogni 20 ms (50Hz), questo vuol dire che è inutile cercare di aggiornarla molto più velocemente, p.e. 10 ms, ed è deleterio aggiornarla molto più lentamente, p.e. 1s, se si vuole ottenere un movimento fluido alla velocità desiderata.
Nel tuo caso devi creare un ciclo con un timing di 20ms che aggiorna la posizione del servo del corretto numero di step ogni volta utilizzando la myservo.writeMicroseconds() che consente una risoluzione maggiore rispetto alla myservo.write(), con la prima puoi impostare variazioni di 1us sul comando PPM, pari a circa 0.09° ciascuna (1 ms = 90°), con la seconda imposti movimenti di grado in grado, molto meno precisa e il servo si sposta tra le varie posizioni alla massima velocità.
Dato che anche la myservo.writeMicroseconds() accetta solo numeri interi compresi tra 500 (-90°) e 2500 (+90°) va da se che il suo incremento deve avvenire in accordo con tale range di valori e non è detto che puoi incrementare il valore ad ogni ciclo di 20 ms, sopratutto nel caso di movimenti molto lenti, quindi dovrai prevedere un contatore che ti permette di incrementare di una unità ogni tot cicli servo in accordo con l'escursione e il tempo desiderato.
Se tutto questo ti sembra complicato hai visto giusto, far muovere in modo fluido, e controllato, un servo non è una cosa semplice da fare come il farlo passare da una posizione all'altra con movimenti sempre alla massima velocità :slight_smile:

for (int a=0; a>10;a+=0.000001)
{
Myservo.write(a);
Delay(10);
}

Scusatemi, nei primi post del thread avevo pensato che il codice riportato fosse solo esemplificativo e non avevo fatto notare la condizione a > 10 che pensavo fosse solo un svista notata da tutti.

Adesso mi pare di capire che il codice sia stato testato e forse è opportuno sottolineare che così come è scritto il ciclo non viene mai eseguito.

vittorio68:
Adesso mi pare di capire che il codice sia stato testato e forse è opportuno sottolineare che così come è scritto il ciclo non viene mai eseguito.

A parte la svita sulla for non ha alcun senso sommare un valore decimale ad un int, il risultato sarà sempre il valore iniziale del int, ovvero sa fai:

int A = 1;
A += 0.1;

Il valore di A sarà sempre 1.

vittorio68:

for (int a=0; a>10;a+=0.000001)

{
Myservo.write(a);
Delay(10);
}

Questo codice non può funzionare.
Assegni un valore in virgola mobile ad una variabile di tipo int, per cui il valore memorizzato verrà sempre arrotondato all'intero. Quindi andrà sempre a scatti. Prova usando un float, ma non so se la libreria servo che cosa accetti in ingresso.