Pages: [1]   Go Down
Author Topic: Arduino + Servomotori  (Read 3137 times)
0 Members and 1 Guest are viewing this topic.
Milano
Offline Offline
Newbie
*
Karma: 0
Posts: 16
fReE tHa kNoWlEdGe
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao a tutti, ho acquistato un piccolo servo standard, precisamente il Futaba S3003 (le specifiche si trovano qui http://www.futaba-rc.com/servos/servos.html). Ho eseguito i collegamenti in questo modo, dopo aver alimentato arduino esternamente (e cambiato lo switch ovviamente): cavo nero del motore: +5V, cavo rosso del motore: GND, cavo bianco del motore: pin 9 (PWM0)... Credo che sia tutto giusto in quanto il motorino appena alimento la scheda si assesta... Ho scritto uno sketch per provare a afr girare il motore, chenneso', di 90 gradi... Lo sketch e' questo:

Code:
int servoPin = 9;

void setup() {
  pinMode(servoPin, OUTPUT);
}

void loop() {

  analogWrite(servoPin, 90);
  delay(500); //Per sicurezza, per mantenere in sync il motore
  analogWrite(servoPin, 0);
  delay(500);

}

Il risultato e' che il motore gira, ma non di 90 gradi! ad occhio saranno una decina... Ora io credo di essere stato un po' ingenuo a credere che un valore intero passato alla analogWrite fosse poi considerato dal motore come i gradi di cui girare... (mi sono ispirato alla documentazione di wiring... credo che guardero' come funziona dentro la classe Servo)! Ho provato ad eseguire del codice trovato qui http://www.tigoe.net/pcomp/code/archives/arduino/000741.shtml (opportunamente modificato), ma il risultato e' lo stesso, gira di un pelo... Qualche delucidazione in merito? Mi manca qualche conoscenza di base sui servo?

Grazie e ciao

Corrado
« Last Edit: March 16, 2006, 01:55:37 pm by Corrado » Logged

The message above is just this .sig's way of propagating itself

0
Offline Offline
Full Member
***
Karma: 0
Posts: 134
panta rei resist the resistors!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

ciao corrado,
non ho nessuna esperienza con servomotori...devo ancora procurarmene uno
( a proposito tu dove lo hai pescato?)

comunque per quel poco che vedo il problema potrebbe risidere nel fatto che usi il pwm
e sostanzialmente gli dai due comandi opposti in brevissimo tempo
cioè non fa neanche in tempo ad iniziare il movimento verso i 90° che già gli dici di tornare indietro smiley

se noti l'esempio che fa tom igoe, invece di un ANALOGWRITE (impulso analogico in uscita) come il tuo
usa DIGITALWRITE ( un impulso digitale in uscita) e quindi ha senso accendere e spegnere velocemente il segnale in uscita
per crearsi una frequenza personalizzata.

hai due alternative:
1- usa il pwm con analogWrite ma aumenta i tempi di attesa (prova 1-2 secondi = 1000 2000 ms)
non so se però questo funzionerà...credo di si, ma non ne sono certo al 100%

2- sostituisci analogWrite con digitalWrite come nell'esempio di tom igoe
  digitalWrite(servoPin, HIGH);   // Turn the motor on
  delayMicroseconds(pulse);       // Length of the pulse sets the motor position
  digitalWrite(servoPin, LOW);    // Turn the motor off
  delay(20);                      // 20 millisecond delay is needed between pulses

spero ti aiuti
ciao
b.
« Last Edit: March 16, 2006, 03:35:23 pm by beltran » Logged

Milano
Offline Offline
Newbie
*
Karma: 0
Posts: 16
fReE tHa kNoWlEdGe
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Mhhh sinceramente *pensavo* :smiley che il tempo dato fosse sufficiente, ho provato con un valore piu' alto ma non migliora... Per quanto riguarda il codice che utilizza la digitalWrite, ho un dubbio. La funzione mi mette a HIGH il pin, attende un tot, e poi mette a LOW il pin, che si traduce in: il motore inizia a girare, continua a farlo per un certo tot, e poi si ferma (ma riparte subito perche' ricomincia il ciclo). Non riesco a intravedere il modo per comandarlo, per dirgli "posizionati ad un certo angolo"! Ok mi metto a ragionare..

Grazie per l'aiuto!

Vi faccio sapere, ma ogni idea e' gradita

Corrado
Logged

The message above is just this .sig's way of propagating itself

Milano
Offline Offline
Newbie
*
Karma: 0
Posts: 16
fReE tHa kNoWlEdGe
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok da quello che ho capito il servo si apetta un impulso lungo tra i mille e 2000 microsecondi che equivalgono alla posizione iniziale e alla finale... quindi per settare il motore nella posizione intermedia bisogna teoricamente mandare un impulso di 1,5 millisecondi. Ho scritto questo codice per testare:

Code:
int servoPin = 9;
int pulse = 950;

void setup() {
  pinMode(servoPin, OUTPUT);
}

void loop() {

  pulse += 50;
  if(pulse > 2000)
    pulse = 1000;
  digitalWrite(servoPin, HIGH);
  delayMicroseconds(pulse);
  digitalWrite(servoPin, LOW);
  delay(1000);

}

Quindi inizia con un impulso di mille microsecodni e lo aumenta fino a 2000, quindi il motorino dovrebbe girare (a step lunghi un secondo) dalla posizione iniziale a quella finale, per poi ricominciare quando si superano i 2000 microsecondi.

Volete vedere il risultato? anche perche' a parole non riesco a descriverlo.

http://www.art3ch.org/corrado/motore.avi (2.5 Mb).

Cosa non ho ancora capito...  :'( Sospetto che sia ancora un problema di timings, magari il motore ci mette troppo tempo a tornare in posizione ed inizia a sfasare.

Un saluto
« Last Edit: March 16, 2006, 06:10:08 pm by Corrado » Logged

The message above is just this .sig's way of propagating itself

Forum Administrator
Offline Offline
Newbie
*****
Karma: 3
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

in teoria funziona mentre in pratica no:)

dovresti mandare un certo numero di impulsi della stessa lunghezza

metti un for loop che ripete lo stesso impulso 10 volte cosi il servo non si confonde smiley

se vuoi del codice di riferimento qui trovi del un esempio per i servo
http://www.grayfuse.com/blog/wp-content/code/simple_servo.pde

converti il codice in modo che non usi numeri con la virgola e vedrai che funziona
(i numeri con la virgola incasinano arduino, e' un problema del compilatore)

massimo
Logged

Milano
Offline Offline
Newbie
*
Karma: 0
Posts: 16
fReE tHa kNoWlEdGe
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Esatto! e' proprio quello che ho provato a fare, e sono arrivato a questa conclusione... Vi faccio un esempio pratico. Supponiamo che il motore sia in posizione iniziale, quindi ha ricevuto un impulso lungo 1000 microsecondi. Voglio farlo spostare in posizione finale, quindi devo inviargli un treno di segnali lunghi 2000 microsecondi. Solo che devo continuare a farlo finche' non raggiunge la posizione! E qui entra in gioco il for... ho pensato che l'indice del for (e quindi "per quanto tempo" continuare a spedirgli segnali lunghi 2000 microsecondi) deve essere in funzione di quanta strada deve percorrere diciamo... e di conseguenza e' in funzione della posizione attuale e della velocita' di rotazione del motore... a naso non mi sembra un conto tanto semplice (contando che questo significa anche tenere traccia della posizione corrente del motore, che complica un po' le cose). Secondo me tutti questi conti se li fa la classe Servo delle API di wiring, ma quando rilasciano il codice?? uff... carta e penna, ho capito!

Vi tengo aggiornati...

Ciau
Logged

The message above is just this .sig's way of propagating itself

0
Offline Offline
Newbie
*
Karma: 0
Posts: 1
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao di arduino non so niente, però ho già programmato servocomandi.
Il tuo codice non funziona perchè non tieni in considerazione il funzionamento del servo.
E' vero che devi mandare un impuso che va da 1ms a 2ms per settare la posizione del servo (1,5ms il servo è in posizione centrale), però il circuito di feedback del servo ha bisogno di una pausa tra un impulso e l'altro compresa tra 10ms e 40ms (solitamente si usano 20ms). Tu tra un impulso e l'altro fai passare 1 secondo..
Il loop per il controllo del servo deve ripetersi ogni 20ms in pratica (nessuna eccezione), poi sta a te via software farlo rimanere per un secondo in una determinata posizione, ma tanto per essere chiari, in quel secondo tu devi fare un "refresh" della posizione ogni 20ms. Spero di essere stato abbastanza chiaro.
In soldoni questo è richiesto perchè il servo altro non è che un semplice motoriduttore DC con un circuito di feedback (di controllo) che permette (tramite un potenziometro) di calcolare la posizione del servo. Come saprai un motore DC non è fatto per rimanere fermo in una posizione fissa (per quello ci sono i motori passo passo), quindi devi costantemente regolare la posizione per farlo rimanere "fermo".
Tieni in considerazione che a causa dello sforzo necessario è sconsigliabile far rimanere fermi i servo (questo accade solitamente per quelli economici) troppo a lungo specie se non sono a vuoto, altrimenti potrebbero bruciarsi.
Tornando all'esempio che hai citato, se ci fai caso è anche scritto "pulse the servo again if the refresh time (20 ms) have passed", e anche nell'esempio postato da Massimo Banzi era abbastanza evidente (c'è un delay esplicito di 20ms). Ovviamente tu non l'hai notato perchè non ne eri a conoscenza.
Riassumendo puoi modicare l'esempio che hai postato tu lasciando invariata la parte dove si genera l'impulso e cambiando solo la parte iniziale (dove si legge la posizione da un ingresso analogico), facendo in modo di incrementare la posizione di un certo valore ogni secondo.
Tiene presente che facendo così il servo si muoverà sempre alla massima velocità.
Se vuoi anche regolare la velocità le cose si complicano un po', in pratica devi incrementare la posizione poco alla volta, e non impostare direttamente la posizione desiderata.
Spero di esserti stato utile.
Logged

Roseville, CA - USA
Offline Offline
Newbie
*
Karma: 0
Posts: 27
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ottimo S3003!!! Ne ho usati decine (Ma sugli aeromodelli, non con Arduino).
Comunque, per pilotare un servo, e' decisamente piu' pratico usare la libreria per i servocomandi.
http://www.arduino.cc/playground/ComponentLib/Servo
Logged

Roseville, CA - USA
Offline Offline
Newbie
*
Karma: 0
Posts: 27
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Certo che rispondere a un thread vecchio di tre anni... Mah...
Che dite, mi vergogno un pochetto?
Logged

Campagne Aretine
Offline Offline
God Member
*****
Karma: 0
Posts: 810
Arduino è una figata
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

lol
Logged

Pages: [1]   Go Up
Jump to: