Nel precedente articolo hai preso confidenza con la classe Servo per pilotare i servo motori ad uso modellistico in tutte le tue applicazioni con Arduino.
In questo articolo vedrai come impartire i comandi di rotazione utilizzando un potenziometro.
Nello schema in alto puoi osservare come eseguire i collegamenti, il servo è di tipo modellistico funzionante a 4-6v per cui puoi alimentarlo con i +5v di Arduino, se i servo dovessero essere più di uno devi calcolare il loro assorbimento sapendo che Arduino NON è illimitato.
Come potenziometro puoi utilizzarne uno da 10KΩ collegando i pin esterni, quelli ai cui capi misuri una resistenza di 10KΩ indipendentemente dalla rotazione dell’alberino, al positivo (+5v) e al negativo (Gnd) di Arduino.
Non preoccuparti di quale dei terminali colleghi al positivo e quale al negativo, l’importante è che la resistenza misurata tra i due non vari ruotando l’albero del potenziometro.
Il collegamento centrale del potenziometro, quello che varia in funzione della rotazione dell’albero rispetto ad entrambi i contatti esterni, aumentando la resistenza dall’uno e diminuendola dall’altro, devi collegarlo ad uno dei pin analogici di Arduino, nello schema il pin scelto è A0.
Fatto ciò passiamo all’esempio, preso dal sito Arduino:
// Controlling a servo position
// using a potentiometer (variable resistor)
// by Michal Rinott
//
#include
Servo myservo;
int potpin = 0;
int val;
void setup()
{
myservo.attach(9);
}
void loop()
{
val = analogRead(potpin);
val = map(val, 0, 1023, 0, 179);
myservo.write(val);
delay(15);
}
Analizziamo linea per linea ciò che Michal Rinott ha scrito come esempio:
linea 6: include la libreria esterna Servo che contiene una classe Servo() il cui utilizzo è descritto in questo articolo;
linea 8: crea l’oggetto myservo di tipo Servo, ossia inizializza la classe.
linea 10: imposta una nuova variabile di tipo integer potpin che indica a quale pin è collegato il potenziometro, in questo caso è il pin 0 ossia il primo pin analogico, il segnale letto da questo pin avrà valori che variano da 0 a 1023 dove 0 indica la minima resistenza e 1023 la massima;
linea 11: imposta la variabile val senza darle alcun valore, questa variabile sarà poi utilizzata per memorizzare il valore letto sul pin 0 analogico;
linee 13-16: definiscono la funzione setup(), fondamentale per inizializzare lo sketch, al suo interno utilizzando il metodo attach() già visto impostiamo che il pin per comunicare con il servo è il pin 9;
linea 18: definisce la funzione loop(), quella eseguita ciclicamente da Arduino durante il suo funzionamento.
linea 20: con la funzione di Arduino analogRead() leggi il valore proveniente dal potenziometro e lo memorizzi nella variabile int, i valori come detto saranno la variazione da 0 a 1023 in funzione della rotazione dell’albero;
linea 21: introduce una funzione molto interessante map() capace di eseguire una mappatura tra valori minimi e massimi, nell’esempio gli dici che la variabile val contiene il valore da mappare e che l’intervallo 0-1023 (secondo e terzo parametro) deve essere mappato sull’intervallo 0-179 (quarto e quinto parametro), per essere più chiari riporto questo esempio: immagina di leggere dal potenziometro il valore 512, non puoi passarlo direttamente al server in quanto il range di funzionamento è 0-179 gradi, per cui un valore 512 posizionerebbe il servo al 180 grado, ma farebbero altrettanto tutti i valori da 180 a 1023 non riuscendo ad ottenere il risultato sperato, per questo dovrestii convertire proporzionalmente il valore diciamo con la seguente equazione: 1023:179 = 512:x da cui x = (512 x 179 ) / 1023 = 89,58 arrotondando 90°, per eseguire ad ogni ciclo di eseguzione questo calcolo viene in contro la funzione map(9 che si occupa di tutto, arrotondamenti incusi. Al termine della nostra elaborazione di riga val varrà il valore corrispettivo tra 0 e 179 proporzionalmente a quello impostato sul potenziomentro.
linea 22: non resta che posizionare il servo con il metodo write() della classe Servo;
linea 23: imposta un tempo di attesa i 15 millesimi di secondo prima di ripartire con il ciclo della funzione loop(), questo tempo serve mediamente al servo per raggiungere la posizione desiderata.
Aggiungo una considerazione proprio sull’ultima linea di codice vista (23), il tempo impostato è generico ed è stato impostato su un valore abbastanza grande da consentire il corretto funzionamento con la maggior parte dei servo modellistici in commercio, tuttavia se il servo che stai utilizzando fosse di quelli molto rapidi a raggiungere un determinato angolo il mio consigio è di ridurre questo tempo per avere delle variazioni più immediate. Per calcolare il tempo di ritardo puoi fare riferimento alle caratteristiche del server, solitamente è indicata la velocità angolare, per capire meglio cosa intendo apri la pagina del servo futaba S3016 mini e guarda le caratteristiche tecniche riportate dal costruttore, troverai:
Speed: 0.25 sec/60° @ 4.8V
che a 4,8 v ( ˜5v a cui lo hai alimentato ) indica una velocità di rotazione di 0,25 sec per 60° che corrisponde a 1/4 di secondo per 60° e nel caso di rotazione a 180° 0,75 sec ( 180 / 60 = 3 -> 0,25 x 3 = 0,75) e quindi 0,0041666667 sec per ciacun grado che corrisponde a circa 4 millesimi di secondo per grado, considerando le dovute approssimazioni sia in alimentazione che per arrotondamenti possiamo dire che il nostro servo, alimentato a 5v, si muove di un grado ogni 5 millesimi di secondo.
Buon lavoro






25 comments
3 pings
danilog
6 marzo 2012 a 18:07 (UTC 2) Link to this comment
ciao! questo tutorial è utilissimo.Sono nuovo nel mondo di arduino,e sto facendo il mio secondo progettino utilizzando due servomotori. Il mio progetto consiste nel creare un piccolo faretto a led ad alta luminosità(circa 6) che tramite due servomotori si muovo su due piani ortogonali,controllato da due potenziometri. Per adesso sono riuscito solo a scrivere il codice per comandare i due servi con i due potenziometri in modo indipendente,però non riesco ad aggiungere l istruzione per far lampeggiare i 6 led ad intermittenza! mi da un errore di compilazione.Potresti dirmi o scrivermi come far ad aggiungere alla libreria dei servo un istruzione per far lampeggiare i led? grazie in anticipo. Sito fantastico
Mauro Alfieri
6 marzo 2012 a 19:23 (UTC 2) Link to this comment
Ciao Danilo,
Grazie x i complimenti, che tipo di errore ti restituisce? Xchè vuoi usare la libreria server per far lampeggiare dei led?
Io ti consiglio di far lampeggiare i faretti in modo indipendente dai servo.
Ma potrei aver male interpretato il tuo progetto.
Mauro
danilog
7 marzo 2012 a 19:01 (UTC 2) Link to this comment
ciao! comunque ho risolto il problema,ho scovato un due errori nella scrittura del codice, adesso funziona tutto. il mio progetto consiste in un Pan e tilt comandato da due mini servomotori.però adesso invece di applicarci un faretto led ,voglio metterci una webcam con 3 led per illuminare.Il tutto comandato da due potenziomentri.Adesso però stavo pensando ad usare un pulsante normalmente chiuso per spegnere o accnedere i 3 led per la webcam. Non so da dove iniziare a scrivere il codice però ,cioè al premere del pulsante vorrei accendere i 3 led e al suo rilascio che li mantenga accesi. per poi ripremerlo per spegnerli.è fattibile come cosa?
Mauro Alfieri
8 marzo 2012 a 07:01 (UTC 2) Link to this comment
Ciao Danilo, posta le correzioni così tutti gli amici del blog le possono usare come hai fatto tu.
Se mi autorizzi io pubblico le correzioni allo sketch a tuo nome.
Per il pulsante e i led si può fare, puoi memorizzare in una variabile “stato” la condizione del pulsante e verificare stato per accendere o spegnere i led.
Mauro
danilog
8 marzo 2012 a 17:13 (UTC 2) Link to this comment
questo è il listato per comandare due servo con due potenziometri.Ho aggiunto anche 5 led (IR per vedere con la webcam anche in assenza di luce)accessi.Vorrei aggiungerci appunto un interuttore,per i led
————————————-
#include
Servo myservo; // create servo object to control a servo
Servo myservo2;
int potpin = 0;
int potpin2= 1;// analog pin used to connect the potentiometer
int val;
int val2; // variable to read the value from the analog pin
void setup(){{
pinMode(1, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
}
myservo.attach(9); // attaches the servo on pin 9 to the servo object
myservo2.attach(8);
}
void loop()
{{
digitalWrite(1, HIGH); // set the LED on // wait for a second
digitalWrite(2, HIGH); // set the LED on
digitalWrite(3, HIGH); // set the LED on
digitalWrite(4, HIGH); // set the LED on
delay(50);}
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
val2=analogRead(potpin2);
val = map(val, 0, 1023, 0, 179); // scale it to use it with the servo (value between 0 and 180)
val2=map(val2,0, 1023, 0, 179);
myservo.write(val); // sets the servo position according to the scaled value
myservo2.write(val2); // waits for the servo to get there
}
davide
29 giugno 2012 a 18:42 (UTC 2) Link to this comment
ciao, hai spiegato benissimo ma purtroppo io ho incontrato un problema
… ho montato il circuito e inserito il codice ( controllato 50 volte ed è perfetto ormai : )sicurissimo.)… poi quando finalmente do tensione il mio arduino si disconnette e riconnette da solo, appena tolgo i 5v oppure stacco il motore dal pin 9 l’arduino funziona correttamente…. premessa io ho appena acquistato l’arduino e gli altri circuiti sul libro mi osno usciti subito ma in questo mi sono bloccato…. secondo te cosa può essere che mi fa succedere questo problema?
cavetti collegati correttamente sia su arduino che su basetta : ) helpppp : (
dimenticavo di dirti che da internet ho guardato delle pagine che collega solo il motore e trovo sempre lo stesso problema anche se devo solo colelgare motore a 5v-gnd e un pin….ma l’arduino con questo motore si comporta sempre nello stesso modo : )
Mauro Alfieri
1 luglio 2012 a 07:51 (UTC 2) Link to this comment
Ciao Davide,
Da quello che scrivi sembra che il problema sia di natura elettrica, verifica che i contatti del servo siano corretti, che modello di servo hai?
La seconda ipotesi è che il tuo servo sia difettoso,hai modo di provarlo indipendentemente da Arduino o di sostituirlo con un altro modello?
Mauro
zanna
3 settembre 2012 a 14:09 (UTC 2) Link to this comment
ciao, ho scoperto da poco il tuo blog e l’ho trovato molto interessante. volevo un consiglio se possibile…
sto costruendo un cavalletto a giraffa (camera crane) per riprese video di 4mt. ( su youtube ci sono moltissimi esempi di come funzionano) utilizzando due servo ed arduino ruoto la telecamera sugli assi x y con un joystick. e fin qui niente di complicato…
a questo punto per migliorare le riprese e l’effetto vorrei aggiungere un sistema che mantenga la telecamera fissa sul soggetto, anche cambiando l’angolazione della ripresa.(muovendo il braccio cella giraffa) pensavo ad un sistema di due potenziometri che leggessero la posizione degli assi sul cavalletto, i quali interagissero con i servo montati sulla telecamera mantenendo sempre l’inquadratura fissa.
il problema è che non capisco come far interagire due potenziometri ( un asse del joystick e il sensore sul cavalletto) su un singolo asse… e come fare ad inserire e disinserire il sistema bloccando l’inquadratura…
in pratica dovrebbe aggiungere o sottrarre un angolazione ai servo che pilotano la telecamera.. è coretto?
Mauro Alfieri
4 settembre 2012 a 17:57 (UTC 2) Link to this comment
Ciao Zanna,
ho visto su internet cos’è una giraffa (camera crane) non ho capito il tuo dubbio è di tipo meccanico o di programmazione?
Mauro
zanna
5 settembre 2012 a 14:53 (UTC 2) Link to this comment
ciao,
)
allora il mio problema è a livello di programmazione, (non ho ancora ben chiara la logica di programmazione…ma mi sto impegnando
in pratica la giraffa è snodata su 4 assi (2 sulla telecamera comandati dal joystick e 2 sul cavalletto), quindi,
una volta impostata l’inquadratura sul soggetto, per far rimanere fissa l’inquadratura della telecamera muovendo il cavalletto, il sistema dovrà modificare la rotazione degli assi della telecamera. così da ottenere una angolazione diversa per lo stesso soggetto.
http://www.youtube.com/watch?v=oGIHC8N9ZRc&feature=related
nel primo minuto di questo video si vede come dovrebbe funzionare…
pensavo di installare due potenziometri sugli assi del cavalletto che mi forniscano i dati dello spostamento degli assi, i quali interagiscano con il movimento della telecamera dopo la pressione di un pulsante. e tutto ritorni manuale alla seconda pressione del pulsante.
però a livello di programmazione ho delle difficoltà a metterlo in pratica…
Mauro Alfieri
5 settembre 2012 a 15:10 (UTC 2) Link to this comment
Ciao Zanna,
bel progetto !!!
Da quanto vedo non è semplicissimo ma neppure infattibile se limiti le funzioni della giraffa rispetto a quelle del video.
Se ho capito il tuo problema è che non riesci a spostare il comando dei servo dalla prima coppia di potenziometri alla seconda coppia, quella legata agli assi.
Per capirci:
supponi di chiamare A la coppia di potenziometri mossi manualmente;
supponi di chiamare B la coppia di potenziometri legati agli assi;
così come lo immagino dovresti collegare un bottone o interruttore ad un ingresso, analogico o digitale scegli tu.
Con un if leggi il suo valore e definisci:
valore 0 passi ai servo i valori della coppia A;
valore 1 passi ai servo i valori della coppia B;
Dovrebbe funzionare.
Fammi sapere se ho scritto una cavolata o se ho interpretato male il problema, mi piacerebbe pubblicare il tuo progetto una volta concluso.
Mauro
zanna
5 settembre 2012 a 15:31 (UTC 2) Link to this comment
da quel poco che ci capisco di logica, penso che il procedimento dovrebbe funzionare in questo modo:
- imposto la posizione della telecamera sul soggetto tramite joystick manualmente
- premo un pulsante e il sistema memorizza la posizione attuale della telecamera (pot A) e abilito la lettura dei pot B.
- muovendo il braccio i potenziometri B andranno a sommare o sottrarre i valori di A memorizzati e di conseguenza sposteranno la telecamera facendole mantenere la stessa inquadratura.
-premendo nuovamente il pulsante si disabilitano i pot B e ritorna tutto in manuale.
Mauro Alfieri
5 settembre 2012 a 21:50 (UTC 2) Link to this comment
Potresti ovviare al problema stabilendo che la posizione dei potenziometri B al momento della pressione del pulsante sia lo 0 virtuale dei due assi e regolare il valore di rotazione dei servo in funzione del valore calcolato partendo da questo 0.
Potresti utilizzare in questo modo i 2 gruppi di potenziometri A e B in modo differente tra loro:
i pot. A funzionano come joystick: il valore proporzionale agisce sulla velocità di movimento e direzione e non sulla posizione 1 a 1;
i pot. B funzionano proporzionalmente in modo da mantenere la posizione sull’oggetto.
Se acquisti questa shield:
http://www.robot-domestici.it/joomla/component/virtuemart/Arduino/arduino-shield/input-shield-for-arduino
potresti usare il joystick per i potenziometri A e i pulsanti per memorizzare i valori o altre funzioni.
Mauro
anvi
3 gennaio 2013 a 21:46 (UTC 2) Link to this comment
salve e complimenti.
mi puoi consigliare dove posso leggere qualcosa su: arduino, encoder, lcd.
avrei un piccolo progettino da realizzare.
detto in due parole vorrei visualizzare sul lcd avanti e indietro i conteggi dell’encoder.
grazie
Mauro Alfieri
3 gennaio 2013 a 22:52 (UTC 2) Link to this comment
Ciao Anvi,
puoi trovare tutto quello che ti occorre su questo blog o sul forum ufficiale Arduino.
Mauro
Fabio
18 marzo 2013 a 11:57 (UTC 2) Link to this comment
Ciao Mauro, la tua guida è fantastica, ho una domanda su come comandare i servi, se voglio far ruotare un servo di 360° come posso fare?
Grazie
Mauro Alfieri
18 marzo 2013 a 14:20 (UTC 2) Link to this comment
Ciao Fabio,
non possiedo un servo in grado di compiere questo tipo di rotazione.
I servomotori che possiedo si spostano al massimo di 180à.
Spero di potermene procurare presto uno e scrivere una articolo.
Mauro
Fabio
19 marzo 2013 a 16:57 (UTC 2) Link to this comment
Ciao, quindi non mi sai dire come scrivere il software, per far ruotare un servo piu di 180°, non si può dare un impulso di una certa durata per far ruotare il servo in continuazione?
Grazie Fabio
Mauro Alfieri
19 marzo 2013 a 17:45 (UTC 2) Link to this comment
Ciao Fabio,
alcuni servo, ho letto, regolano solo la velocità di rotazione con il PWM, altri sembrano più simili ai servo da 180gradi, ossia gli imposti il grado a cui vuoi che vadano ed il servo si posiziona.
Non avendoli provati non so dirti se si comportino come desiderato.
Mauro
Fabio
20 marzo 2013 a 11:57 (UTC 2) Link to this comment
Ok grazie mille, continuero comunque a seguirti i tuoi consigli sono molto utili continua così
Mauro Alfieri
20 marzo 2013 a 16:46 (UTC 2) Link to this comment
Ciao Fabio,
grazie per la fiducia.
Magari riuscirò a procurarmi un servo da 360° e farne un tutorial
Mauro
DARIO MAMONE
8 maggio 2013 a 17:57 (UTC 2) Link to this comment
Ti chiedo cortesemente di dirmi se l’Arduino può pilotare questo tipo servomotore
Ringraziandoti in anticipo ti porgo i miei saluti
Savox SV-0235MG Super Torque Steel Gear Digital Servo.
Features:
•Combines leading edge technology with super high 12 bit (4096) resolution and unique steel gears.
•Super light-weight.
•High speed, incredible efficiency, and low power consumption.
•Extremely strong metal steel gears ensure long-life and durability.
•The full aluminum case design not only looks good but also allows for cooler and smoother operating temps.
•Our servos are totally green – from materials to production, these servos are environmentally friendly.
•Ideal for 5th scale vehicles
Dimensions(mm): 65.8x30x57.4
Weight(g): 200
Speed(@6.0V sec/60): .16
Torque(@6.0V oz-in): 388.8
Speed(@7.4V sec/60): .13
Torque(@7.4V oz-in): 486.1
Gear: Metal
Bearing: 2BB
Case: Full Aluminum
15 Tooth Spline
Mauro Alfieri
9 maggio 2013 a 07:47 (UTC 2) Link to this comment
Ciao Dario,
non ho ancora provato con servo digitali, hai cercato in internet se qualcuno li ha utilizzati e cosa dice?
Mauro
giacomo
13 maggio 2013 a 21:17 (UTC 2) Link to this comment
scusa se sono fuori tema, ma mi potresti dire come crei le immagini schematichedei collegamenti dell’arduino?
Mauro Alfieri
14 maggio 2013 a 07:43 (UTC 2) Link to this comment
Ciao Giacomo,
uso Fritzing un programma open source.
Mauro
Mauro Alfieri » Blog Archive » Tutotorial Arduino e i servo III
7 ottobre 2011 a 10:44 (UTC 2) Link to this comment
[...] servomotori in modo parallelo ( articoli precedenti su questo argomento Tutoria Arduino e i servo e Tutorial Arduino e i servo II ) prova a pilotare 6 servomotori [...]
Mauro Alfieri » Blog Archive » Arduino, led e pulsante
9 marzo 2012 a 09:15 (UTC 2) Link to this comment
[...] leggere la nostra conversazione come commento all’articolo Tutotorial Arduino e i servo II in cui Danilo ha postato il suo [...]
Vorrei realizzare un indicatore di rpm motore... - Pagina 3 - BaroneRosso.it - Forum Modellismo
22 dicembre 2012 a 14:12 (UTC 2) Link to this comment
[...] il potenziometro col segnale che pilota l'innalzamento o l'abbassamento del suono del motore. Tutotorial Arduino e i servo II – Mauro Alfieri Elettronica Sugo __________________ Un ottimista invento' l'aeroplano, un pessimista invento' il [...]