Skip to Content

Come controllare i servo motori con Arduino

Come controllare i servo motori con Arduino

In questo tutorial imparerai come funzionano i servo motori e come controllarli con Arduino. Ho incluso schemi di collegamento e diversi esempi di codice!

I servo motori sono spesso usati in progetti di robotica, ma li puoi trovare anche in auto RC, aerei, ecc. Sono molto utili quando serve un controllo preciso della posizione e/o una coppia elevata.

Nella prima parte di questo articolo, vedremo il funzionamento interno di un servo e che tipo di segnale di controllo utilizza. Spiegherò anche le differenze tra un servo standard e uno continuo. Successivamente, ti mostrerò come collegare un servo motore all’Arduino.

Con il primo esempio di codice potrai controllare sia la posizione che la velocità del servo motore. Dopo, vedremo come controllare un servo con un potenziometro e come modificare il codice per controllare più servo motori contemporaneamente. Infine, alla fine dell’articolo, troverai le specifiche e le dimensioni di alcuni dei servo motori più popolari sul mercato.

Materiale necessario

Componenti hardware

SG90 micro servo× 1Amazon
MG996R high-torque servo× 1Amazon
Arduino Uno Rev3× 1Amazon
Jumper wires× 15Amazon
Breadboard× 1Amazon
10 kΩ potentiometer (tipo breadboard)× 1Amazon
USB cable type A/B× 1Amazon
5V power supply (opzionale)× 1Amazon

Software

Arduino IDEArduino IDE

Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.

Come funziona un servo motore?

Un servo hobby standard è tipicamente composto da un piccolo motore elettrico, un potenziometro, l’elettronica di controllo e un riduttore. La posizione dell’albero di uscita è continuamente misurata dal potenziometro interno e confrontata con la posizione target impostata dal controller (es. Arduino).

In base all’errore, l’elettronica di controllo regola la posizione effettiva dell’albero di uscita affinché corrisponda alla posizione target. Questo è noto come sistema di controllo a ciclo chiuso.

Schema di un servo motore RC (Hwang et al. 2018)

Il riduttore diminuisce la velocità del motore, aumentando la coppia sull’albero di uscita. La velocità massima dell’albero di uscita è solitamente intorno a 60 RPM.

Controllo del servo

I servo motori sono controllati inviando un segnale PWM (modulazione di larghezza di impulso) alla linea di segnale del servo. La larghezza degli impulsi determina la posizione dell’albero di uscita. Quando invii al servo un segnale con un impulso di 1,5 millisecondi (ms), il servo si posizionerà nella posizione neutra (90 gradi). Le posizioni min (0 gradi) e max (180 gradi) corrispondono tipicamente a impulsi di 1 ms e 2 ms rispettivamente. Nota che questo può variare leggermente tra diversi tipi e marche di servo (es. 0,5 e 2,5 ms). Molti servo ruotano solo per circa 170 gradi (o anche solo 90), ma la posizione centrale è quasi sempre a 1,5 ms.

Per regolare la posizione minima e massima nel codice, vedi la sezione qui sotto.

Impulsi per controllare il servo

I servo motori generalmente richiedono un impulso ogni 20 millisecondi o 50 Hz, ma molti servo RC funzionano bene in un intervallo da 40 a 200 Hz.

Servo a 360 gradi (continuo) vs servo a 180 gradi (standard)

La maggior parte dei servo RC è del tipo a 180 gradi, cioè può ruotare solo da 0 a 180 gradi. Tuttavia, sono disponibili anche servo a rotazione continua, noti come servo a 360 gradi.

I servo a rotazione continua reagiscono diversamente al segnale di controllo rispetto ai servo standard a 180 gradi. Con un servo a rotazione continua non puoi controllare la posizione esatta dell’albero di uscita, ma solo la velocità e la direzione. Un impulso di 1 ms imposta la velocità massima in una direzione, mentre un impulso di 2 ms la imposta nella direzione opposta. Un valore vicino a 1,5 ms ferma il motore.

Se il tuo servo si comporta in modo inaspettato, potresti star usando un servo continuo invece di uno standard.

Per maggiori informazioni dai un’occhiata al nostro tutorial Positional versus Continuous Servos.

Come collegare un servo motore all’Arduino?

Collegare un servo motore è molto semplice perché servono solo tre fili: alimentazione, massa e segnale. Il filo di alimentazione è tipicamente rosso e va collegato a 5 V.

Un micro servo come il SG90 consuma circa 10 mA a riposo e 100 – 250 mA durante la rotazione, quindi puoi alimentarlo direttamente dall’uscita 5 V dell’Arduino. Tuttavia, devi fare attenzione se usi più servo o servo più grandi. Se il tuo/i tuoi motore/i consumano più di 300 mA, dovresti usare un’alimentazione esterna per evitare di danneggiare l’Arduino! Vedi lo schema qui sotto per l’uso di alimentazioni esterne.

Il filo di massa è tipicamente nero o marrone e va collegato al pin GND dell’Arduino. Quando usi un’alimentazione separata, collega il filo di massa sia all’Arduino che all’alimentazione.

Il filo di segnale è tipicamente giallo, arancione o bianco e può essere collegato a qualsiasi pin digitale dell’Arduino. In questo caso, l’ho collegato al pin digitale 9.

Servo motor with Arduino Uno wiring diagram.
Schema di collegamento servo motore con Arduino Uno

I collegamenti sono anche riportati nella tabella qui sotto.

Collegamenti servo motore

Servo motoreArduino
Alimentazione (rosso)5 V
Massa (nero o marrone)GND
Segnale (giallo, arancione o bianco)Pin 9

Come detto prima, se usi servo grandi o multipli dovresti usare un’alimentazione esterna. Collega semplicemente l’alimentazione come mostrato nello schema qui sotto. Assicurati di collegare insieme il pin GND dell’Arduino e quello dell’alimentazione.

Puoi usare questa configurazione anche se il tuo servo richiede una tensione diversa da quella fornita dall’Arduino, ad esempio 6 V o più. L’immagine seguente mostra come usare un’alimentazione esterna per alimentare il servo:

servo-motor-with-arduino-uno-and-external-power-supply-wiring-diagram-schematic-circuit-tutorial
Schema di collegamento servo con Arduino Uno e alimentazione esterna

Collegamenti per servo motore con alimentazione esterna

Servo motoreCollegamento
Alimentazione (rosso)Alimentazione 5 V
Massa (nero o marrone)Massa alimentazione e GND Arduino
Segnale (giallo, arancione o bianco)Pin 9 Arduino

Esempio di codice Arduino

Per controllare il servo motore useremo la libreria Servo.h che è preinstallata nell’IDE Arduino. Con il codice di esempio qui sotto puoi controllare la posizione esatta del servo motore e include anche un codice per far oscillare automaticamente il braccio del servo avanti e indietro.

Puoi caricare il codice di esempio sul tuo Arduino tramite l’IDE Arduino. Ora ti spiegherò come funziona il codice.

/* Servo motor with Arduino example code. Position and sweep. More info: https://www.makerguides.com/ */

// Include the servo library:
#include "Servo.h"

// Create a new servo object:
Servo myservo;

// Define the servo pin:
#define servoPin 9

void setup() {
  // Attach the Servo variable to a pin:
  myservo.attach(servoPin);
}

void loop() {
  // Tell the servo to go to a particular angle:
  myservo.write(90);
  delay(1000);
  myservo.write(180);
  delay(1000);
  myservo.write(0);
  delay(1000);

  // Sweep from 0 to 180 degrees:
  for (int angle = 0; angle <= 180; angle += 1) {
    myservo.write(angle);
    delay(15);
  }

  // And back from 180 to 0 degrees:
  for (int angle = 180; angle >= 0; angle -= 1) {
    myservo.write(angle);
    delay(15);
  }
  delay(1000);
}

Come funziona il codice

Il primo passo è includere la libreria Arduino necessaria. Puoi trovarla anche sotto Sketch > Include Library > Servo.

// Include the servo library:
#include "Servo.h"

Poi devi creare un nuovo oggetto della classe Servo. In questo caso ho chiamato il servo ‘myservo’, ma puoi usare altri nomi. Nota che dovrai cambiare il nome del servo anche nel resto del codice.

// Create a new servo object:
Servo myservo;

Dopodiché ho definito a quale pin Arduino è collegato il servo motore.

// Define the servo pin:
#define servoPin 9

L’istruzione #define serve per dare un nome a un valore costante. Il compilatore sostituirà ogni riferimento a questa costante con il valore definito quando il programma viene compilato. Quindi ovunque menzioni servoPin, il compilatore lo sostituirà con il valore 9 durante la compilazione.

Nella sezione setup del codice colleghiamo l’oggetto servo creato al pin che controllerà il servo. La funzione attach() ha anche due parametri opzionali, di cui parlo nella sezione seguente.

void setup() {
  // Attach the Servo variable to a pin:
  myservo.attach(servoPin);
}

Controllo angolo/posizione:

Nella prima parte del loop diciamo semplicemente al servo motore di muoversi a un angolo specifico con la funzione write(). Nota che serve un ritardo tra i comandi per dare al servo il tempo di raggiungere la posizione impostata.

  // Tell the servo to go to a particular angle:
  myservo.write(90);
  delay(1000);
  myservo.write(180);
  delay(1000);
  myservo.write(0);
  delay(1000);

Controllo velocità:

Nell’ultima parte del codice ho usato due cicli for per far oscillare il servo avanti e indietro. Questo codice può essere utile anche per controllare la velocità del servo. Modificando il valore del delay alla fine del ciclo for puoi regolare la velocità del braccio del servo.

  // Sweep from 0 to 180 degrees:
  for (int angle = 0; angle <= 180; angle += 1) {
    myservo.write(angle);
    delay(15);
  }
  // And back from 180 to 0 degrees:
  for (int angle = 180; angle >= 0; angle -= 1) {
    myservo.write(angle);
    delay(15);
  }

Perché il mio servo non ruota per tutti i 0 – 180 gradi?

Come detto nell’introduzione, l’angolo dell’albero di uscita del servo motore è determinato dalla larghezza dell’impulso elettrico applicato al filo di controllo. Generalmente, un impulso di circa 1 ms corrisponde alla posizione minima, 2 ms alla posizione massima e 1,5 ms a 90° (posizione neutra). Tuttavia, questo può variare leggermente tra marche e anche tra servo diversi della stessa marca. Questo significa che dovrai regolare i valori minimi e massimi nel codice per adattarli al servo che stai usando.

La libreria Arduino Servo rende molto facile regolare l’angolo minimo e massimo del servo specificando due parametri opzionali nella funzione attach(). In questa funzione, il primo parametro è il numero del pin a cui è collegato il servo. Il secondo parametro è la larghezza dell’impulso, in microsecondi (μs), corrispondente all’angolo minimo (0 gradi) del servo. Il terzo parametro è la larghezza dell’impulso, in microsecondi, corrispondente all’angolo massimo (180 gradi) del servo.

Di default, la larghezza minima e massima dell’impulso è impostata a 544 e 2400 microsecondi. Questi valori funzionano per la maggior parte dei servo comuni, ma a volte è necessario regolarli leggermente.

Consiglio di regolare i valori min e max in piccoli incrementi (10-20 microsecondi) per evitare di danneggiare il servo. Se il braccio del servo tocca i limiti fisici del motore, aumenta il valore minimo e diminuisci quello massimo.

#define servoPin 9
int min = 480;
int max = 2500;
Servo myservo;

void setup() {
  myservo.attach(servoPin, min, max);
}

Controllare un servo motore con un potenziometro e Arduino

servo-motor-with-arduino-uno-and-potentiometer-wiring-diagram-schematic-circuit
Schema di collegamento per controllare un servo motore con un potenziometro e Arduino.

Controllare la posizione di un servo motore con un potenziometro è molto semplice e può essere molto utile se vuoi regolare la posizione del motore manualmente. Come vedi nello schema sopra, il servo motore è collegato come prima. L’unica differenza è che ho usato una breadboard per distribuire l’alimentazione dall’Arduino.

Il potenziometro ha tre pin, collega i pin esterni a 5 V e GND. Il pin centrale del potenziometro è collegato al pin analogico A0 dell’Arduino.

Esempio di codice Arduino per servo motore con potenziometro

Il codice di esempio qui sotto ti permette di controllare un servo motore con un potenziometro.

/* Servo motor with potentiometer and Arduino example code. More info: https://www.makerguides.com/ */

#include "Servo.h" // include the required Arduino library

#define servoPin 9 // Arduino pin for the servo
#define potPin A0 // Arduino pin for the potentiometer

int angle = 0; // variable to store the servo position in degrees
int reading = 0; // variable to store the reading from the analog input

Servo myservo; // create a new object of the servo class

void setup() {
  myservo.attach(servoPin);
}

void loop() {
  reading = analogRead(potPin); // read the analog input
  angle = map(reading, 0, 1023, 0, 180); // map the input to a value between 0 and 180 degrees
  myservo.write(angle); // tell the servo to go to the set position
  delay(15); // wait 15 ms for the servo to reach the position
}

Nota che prima delle sezioni setup e loop del codice è stata aggiunta una nuova variabile reading e definito il pin di input del potenziometro.

Nella sezione loop del codice leggiamo il valore dal pin analogico A0 con la funzione analogRead().

reading = analogRead(potPin); // read the analog input

Le schede Arduino contengono un convertitore analogico-digitale (ADC) a 10 bit, quindi otteniamo un valore tra 0 e 1023 a seconda della posizione del potenziometro.

Poiché il servo motore può ruotare solo tra 0 e 180 gradi, dobbiamo ridimensionare i valori con la funzione map(). Questa funzione rimappa un numero da un intervallo a un altro.

angle = map(reading, 0, 1023, 0, 180); // map the input to a value between 0 and 180 degrees

Infine, scriviamo l’angolo al servo motore:

myservo.write(angle); // tell the servo to go to the set position
delay(15); // wait 15 ms for the servo to reach the position

Controllare più servo motori

Controllare più servo è semplice come controllarne uno solo, ma spesso ricevo domande su come modificare il codice. Per questo ho aggiunto un esempio semplice qui sotto.

how-to-control-multiple-servo-motors-with-arduino-wiring-diagram-schematic-circuit-tutorial-1
Più servo motori collegati ad Arduino Uno e a un’alimentazione esterna.

Nota che dovrai usare un’alimentazione esterna per alimentare i servo perché l’Arduino non può fornire abbastanza corrente per tutti i motori.

Per questo esempio usiamo più pin Arduino per i servo aggiuntivi. Tuttavia, questo significa che sei limitato a 12 servo con un Arduino Uno e potresti non avere abbastanza pin per altri componenti.

Un’altra opzione è usare uno o più PCA9685 PWM/servo drivers. Questo driver ti permette di controllare 16 servo con soli 2 pin dell’Arduino usando I2C. Adafruit li vende anche sotto forma di Arduino shield.

Poiché la configurazione di questi driver è un po’ più complessa, la tratterò in un tutorial separato.

Esempio di codice Arduino con più servo

Come vedi nell’esempio qui sotto, devi solo creare più oggetti della classe Servo con nomi diversi. Puoi indirizzare ogni servo usando il nome corretto nelle sezioni setup e loop del codice.

/* Arduino with multiple servos example code. More info: https://www.makerguides.com/ */

#include "Servo.h"

Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;

void setup()
{
  servo1.attach(9);
  servo2.attach(10);
  servo3.attach(11);
  servo4.attach(12);
  servo5.attach(13);
}

void loop()
{
  servo1.write(0);
  servo2.write(0);
  servo3.write(0);
  servo4.write(0);
  servo5.write(0);
  delay(2000);
  servo1.write(90);
  servo2.write(90);
  servo3.write(90);
  servo4.write(90);
  servo5.write(90);
  delay(1000);
  servo1.write(180);
  servo2.write(180);
  servo3.write(180);
  servo4.write(180);
  servo5.write(180);
  delay(1000);
}

Specifiche dei servo motori

Qui sotto trovi le specifiche di alcuni dei servo motori più popolari sul mercato. Il produttore originale di questi servo è Tower Pro Pte Ltd. ma modelli simili possono essere acquistati da molti altri fornitori.

SG90 analog micro servo

tower-pro-sg90-analog-micro-servo-motor-9g-1
[Fonte: towerpro.com.tw]

Pinout

MarroneGND
RossoVCC
GialloSegnale (PWM)

Specifiche

Tensione di funzionamento4.8 V
Peso9 g
Coppia di stallo1.8 kg/cm (4.8 V)
Tipo di ingranaggiIngranaggi in POM
Velocità di funzionamento0.12 sec/60° (4.8 V)
Temperatura di funzionamento0 – 55 °C
CostoCheck price

Dimensioni

A34.5 mm
B22.8 mm
C26.7 mm
D12.6 mm
E32.5 mm
F16 mm
sg90-micro-servo-motor-dimensions-2
[Fonte: towerpro.com.tw]

MG90S digital micro servo

tower pro mg90s digital micro servo
[Fonte: towerpro.com.tw]

Pinout

MarroneGND
RossoVCC
GialloSegnale (PWM)

Specifiche

Tensione di funzionamento4.8 V
Peso13.4 g
Coppia di stallo1.8 kg/cm (4.8 V), 2.2 kg/cm (6.6 V)
Tipo di ingranaggiAlluminio 6061-T6
Velocità di funzionamento0.10 sec/60° (4.8 V), 0.08 sec/60° (6.0 V)
Temperatura di funzionamento0 – 55 °C
CostoCheck price

Dimensioni

A32.5 mm
B22.8 mm
C28.4 mm
D12.4 mm
E32.1 mm
F18.5 mm
sg90-micro-servo-motor-dimensions-2
[Fonte: towerpro.com.tw]

MG996R high torque digital servo

[Fonte: towerpro.com.tw]

Pinout

MarroneGND
RossoVCC
GialloSegnale (PWM)

Specifiche

Tensione di funzionamento4.8 – 6.6 V
Assorbimento a riposo10 mA
Assorbimento a vuoto170 mA
Assorbimento a stallo1400 mA
Peso55 g
Coppia di stallo9.4 kg/cm (4.8 V), 11 kg/cm (6.0 V)
Tipo di ingranaggiIngranaggi in metallo
Velocità di funzionamento0.19 sec/60° (4.8 V), 0.15 sec/60° (6.0 V)
Temperatura di funzionamento0 – 55 °C
CostoCheck price

Dimensioni

A42.7 mm
B40.9 mm
C37 mm
D20 mm
E54 mm
F26.8 mm
sg90-micro-servo-motor-dimensions-2
[Fonte: towerpro.com.tw]

Conclusione

In questo tutorial ti ho mostrato come usare i servo motori con Arduino. Abbiamo visto le basi per controllare posizione e velocità dei servo, come controllare un servo con un potenziometro e come controllare più servo contemporaneamente.

Se vuoi imparare di più su altri tipi di motori, dai un’occhiata agli articoli qui sotto:

Ho anche un articolo su How To Control Servo Motors using ESP32 se vuoi lavorare con un microcontrollore ESP32.

Se hai domande, suggerimenti o pensi che manchi qualcosa in questo tutorial, lascia un commento qui sotto.