#16 – Controllare Servomotori con Arduino

Un aspetto certamente interessante della nostra scheda, è quello di poter comandare “piccoli” motori, oltre che leggere sensori. In particolare, i motori che con Arduino si possono comandare con facilità sono i servomotori.

Servomotori

Questi piccoli motori sono fatti per effettuare rotazioni controllate. Possiamo infatti impostare un angolo di rotazione rispetto al riferimento, oppure regolarne la velocità di rotazione.

Sono alimentati spesso a 4.8V o a 6V. Hanno forme e peso differenti, come possono esercitare forze differenti, tuttavia in linea di massima hanno le seguenti caratteristiche:

  • Presentano più “forza”, meglio definita come momento torcente (torque), a 6V rispetto che a 4.8V.
  • Serve un solo segnale a 5V per comandarli. Gli altri due sono per l’alimentazione (5V o 6V, e il GND).
  • Vengono comandati con una speciale onda quadra, con caratteristiche sempre uguali.

Leggere sempre le specifiche

Prima di mostrarvi il collegamento elettrico, è doveroso fare una precisazione che spesso rimane inosservata: leggete sempre le specifiche del motore.

Nel nostro esempio, utilizzeremo il servomotore SM-S2309S.

Specifiche servomotore SM-S2309S

Prestiamo particolare attenzione alla sezione TORQUE e CURRENT.

Non entriamo in questioni riguardanti la fisica, ma basti osservare che un momento torcente di 1.10Kg*cm, significa che il nostro motore più sollevare al massimo un corpo di 1.10Kg, utilizzando un braccetto collegato al rotore, lungo 1cm.

Il momento torcente è infatti il prodotto vettoriale tra forza e braccio:

$latex \tau = \stackrel{ \rightarrow }{F} x r = \stackrel{ \rightarrow }{F} r sen(\theta) $

Momento torcente, applicato al punto in rosso. Crediti

Inoltre si ricorda che 1Kg*cm = 9.8N*cm.

Questa precisazione serve, oltre che per dare un’idea di che modello possiate avere bisogno nel vostro progetto, anche per comprendere la sezione CURRENT.

In particolare, per questo motore osserviamo che la corrente normalmente assorbita è 440mA. Questo ad esempio ci fa capire che se prendiamo l’alimentazione dalla scheda, a sua volta alimentata con USB, siamo proprio al limite. Con una fonte di alimentazione di 1A invece non abbiamo problemi.

L’aspetto cruciale è pero la corrente di stallo (STALL CURRENT). Il motore entra in “stallo” quando non riesce più a sostenere il momento torcente. Nel nostro esempio, se il momento torcente supera 1.10Kg*cm.

Come possiamo osservare, in questo caso la corrente supera l’Ampere: bruceremo sicuramente la scheda, se lo stavamo alimentando con il pin del 5V.

Quando alimentiamo i servomotori, è meglio utilizzare una fonte di alimentazione esterna, o prestare attenzione a non creare situazioni di stallo.

Principio di funzionamento

La libreria Servo, utilizza il pin digitale selezionato per creare un segnale PWM. Questa tecnologia, che vedremo nello specifico in un articolo più avanzato, permette di creare un’onda quadra, con particolari caratteristiche.

Esempio di onda quadra a 5V e 500Hz

L’onda PWM si caratterizza per il “duty cycle”, ovvero:

Duty Cycle

Dove τ è il tempo in cui l’onda resta a 1 nel periodo T, mentre T è il periodo (l’inverso della frequenza).

I valori tipici di un duty cycle sono 0%, 25%, 50%, 75%, 100%:

Esempi di duty cycle (0%, 25%, 75%)

I servo lavorano a una frequenza di 50Hz, e associano tre diversi comportamenti a seconda del valore d:

  • Se τ = 1ms, il servomotore si posiziona a 0°
  • Con τ = 1.5ms, il servomotore si posiziona a 90°
  • Se τ = 2ms, il servomotore si posiziona a 180°

Poiché la relazione tra τ e i gradi è lineare, è molto semplice trovare il valore dati i gradi desiderati:

$latex \tau = gradi * \frac{1}{180} + 1 [ms] $

Tipologie di Servomotori

La maggior parte dei servomotori lavora tra 0° e 180°, coprendo quindi mezzo giro di circonferenza. Questi servomotori vengono comandati spesso utilizzando i gradi, come visto in precedenza.

Esistono poi servomotori a rotazione continua. Questi possono essere comandati anche in modo alternativo: il duty cycle può essere utilizzato per comandarli in velocità e direzione. In questo caso:

  • Con τ = 1.5ms il servomotore è fermo.
  • Se usiamo τ compresa tra 1.0ms e 1.5ms, abbiamo rotazione antioraria.
  • Con τ compresa tra 1.5ms e 2.0ms, abbiamo rotazione oraria.

Collegamenti e Codice

Il collegamento risulta molto semplice:

Collegamento Arduino con Servomotore

Il segnale di controllo deve essere collegato ad un pin digitale qualsiasi. Controllate le specifiche del vostro servomotore per distinguere i tre fili. Prestare particolare attenzione a non invertire la polarità.

Per quanto riguarda il codice:

#include <Servo.h> //Includiamo la libreria per gestire i servomotori
#define SERVO_PIN 3
//Definiamo l'istanza dell'oggetto Servo
Servo Servo1;
void setup() {
  pinMode(SERVO_PIN, OUTPUT); //Impostiamo il pin come uscita
  Servo1.attach(SERVO_PIN);    
}
/*
 * Muoviamo il servo dal suo angolo minimo, al suo angolo massimo
 * e viceversa
 */
int i = 0;
bool positive = 1;
void loop() {
   //Test delle condizione di inversione
   if (i > 180){
      positive = 0;
      i = 180;
   }else if (i < 0){
      positive = 1;
      i = 0;
   }
   //Comandiamo il servo in quella posizione
   Servo1.write(i);
   if (positive) //Incrementiamo o decrementiamo i gradi
     i++;
   else
     i--;
   delay(10); //Diamo il tempo al motore di posizionarsi
}

Otterremo un risultato simile:

Simulazione Servomotore (0°-180°)

Funzioni libreria Servo

Le seguenti funzioni sono tratte dalla guida ufficiale della libreria, che potete trovare qui.

– attach

Abilita il pin per il controllo del servomotore. Da questo momento i comandi verranno eseguiti.

Sintassi
// servo: variabile di tipo Servo
servo.attach(pin) 
servo.attach(pin, min, max)
Parametri
  • pin: numero del pin dove il servomotore è collegato
  • min (opzionale): la larghezza dell’impulso, in microsecondi, corrispondente al minimo angolo (0 gradi) per il servomotore (di default 544)
  • max (opzionale): la larghezza dell’impulso, in microsecondi, corrispondente al massimo angolo (180 gradi) per il servomotore (di default 2400)

– attached

Resititusce se il servomotore è attualmente controllato tramite il pin

Sintassi
// servo: variabile di tipo Servo
servo.attached()
Restituisce

true se il pin attualmente è utilizzato per il controllo del servomotore; false altrimenti.

– detach

Smette di controllare il servomotore tramite il pin indicato. Il pin può essere quindi controllato direttamente con altri comandi quali digitalWrite, analogWrite, etc.

Può tornare utile per mettere in folle il servomotore ed evitare di consumare energia per via di continue correzioni/disturbi.

Sintassi
// servo: variabile di tipo Servo
servo.detach()

– write

Scrive un valore di comando al servomotore. In un servomotore standard (limitato in rotazione tra 0° e 180°), imposta l’angolo dell’albero del motore (in gradi) al valore impostato. In servomotori a rotazione continua, imposta la velocità di rotazione del servomotore (0 corrisponde a velocità di rotazione massima in una direzione, 180 rotazione a velocità massima in direzione opposta, valori vicino a 90 a nessuna rotazione).

Sintassi
// servo: variabile di tipo Servo
servo.write(angle)
Parametri
  • angle: valore da scrivere al servomotore, da 0 a 180

– writeMicroseconds

Permette di impostare direttamente la larghezza dell’impulso per il servomotore, in microsecondi. Questa funzione è chiamata sotto la funzione precedente (write), che effettua la conversione gradi-microsecondi per noi.

Per il valore da utilizzare, fare riferimento alla prima parte di questa guida, considerando che 1ms = 1000us. Questo valore oscilla tipicamente tra 700 e 2300.

Utilizzare valori fuori dalla finestra consentita del servomotore non produrrà un cambiamento visibile, ma potrebbe portare ad un consumo più elevato di corrente da parte del servomotore.

Sintassi
// servo: variabile di tipo Servo
servo.writeMicroseconds(us)
Parametri
  • us: microsecondi per la larghezza dell’impulso (da 0 a 32767)

– read

Legge l’ultimo valore passato alla funzione write (angolo dell’albero del motore).

Sintassi
// servo: variabile di tipo Servo
servo.read()

Limitazioni sul numero, e soluzione

La scheda Arduino supporta al massimo 12 servomotori. Arriviamo fino a 48 con Arduino Mega.

Se si devono gestire parecchi servomotori, è meglio utilizzare delle schede di espansione apposite.

Scheda di espansione per 16 servomotori

Queste schede di espansione utilizzano uno speciale protocollo di comunicazione chiamato I2C, che affronteremo prossimamente.

Adesso che abbiamo capito come controllare i servomotori, prima di proseguire e vedere come utilizzare i motori a corrente continua, dobbiamo imparare come funzionano i transistor.

4 comments

  1. Von Fitze M.

    Buongiorno vorrei sapere come fare a bloccare il servo a 180 gradi e 0 gradi per un certo numero di secondi ???
    praticamente il servo deve spostarsi tutto a destra e fermarsi per il tempo che voglio io ( 1/2/3 secondi ) e rispostarsi a sinistra e fare lo stesso lavoro .
    tenga presente che sono 3 mesi che mi dedico all’elettronica e quindi le mie basi sono pari a zero
    Grazie
    Von Fitze M.

    1. Andrea Aspesi

      Suppongo che ci sia anche un controllore (Arduino). Con Arduino, un modo semplice per fare quello che dici è il seguente:

      // Example 1
      #include <Servo.h>
      #define PIN_SERVO 9
      Servo myservo;
      void setup() 
      { 
        pinMode(PIN_SERVO, OUTPUT);
        myservo.attach(PIN_SERVO);
      } 
      void loop() {
        myservo.write(0);
        delay(1000); //1000ms = 1s
        myservo.write(180);
        delay(1000); //1000ms = 1s
      }
      

      Puoi trovare i metodi per lavorare con i servo nella documentazione ufficiale: https://www.arduino.cc/reference/en/libraries/servo/, sotto “Methods”.
      In particolare, il metodo write, ha la seguente definizione:
      Syntax
      servo.write(angle)
      Parameters
      servo: a variable of type Servo
      angle: the value to write to the servo, from 0 to 180

      Se ti interessa capire meglio cosa fa il codice, ti invito a sfogliare la parte iniziale di questa guida in cui tratto a grandi linee la programmazione su Arduino

  2. Paolo D'Armento

    Ciao,
    sono alle prese con un aeromodello, con trasmittente e ricevente basate su arduino e nrf24. funziona tutto correttamente ma vorrei incrementarne il funzionamento con l’aggiunta dell’assetto da atterraggio: questo dovrebbe consistere in un pulsante che alla prima pressione muove un servocomando di alcuni gradi ed alla seconda pressione lo riporta alla posizione iniziale. Quali elementi dovrei inserire negli sketch tx ed rx?
    Grazie, un saluto

    1. Andrea Aspesi

      Ciao Paolo,
      ho aggiornato l’articolo con i metodi della libreria.
      Una volta collegato il servomotore al pin di Arduino, abilita il controllo con servo.attach(PIN), poi per controllarlo usa servo.write(angolo).
      Per sapere l’angolo di comando, o lo misuri, oppure gioca con i valori.
      Dato che immagino il consumo sia importante per te, considera di staccare la libreria con servo.detach() quando hai finito (il servo va in folle, ma se è abbastanza ridotto non dovrebbe modificare l’assetto). Al ciclo successivo, usa nuovamente servo.attach(PIN) prima di lanciare il write.
      Se non stacchi la libreria, il servomotore rimane in coppia, ma continua a correggersi, e quindi consuma anche quando non lo usi.

Comments are closed.