Questo articolo include tutto ciò che devi sapere per controllare un 28BYJ-48 motore passo-passo con la scheda driver ULN2003 e Arduino. Ho incluso datasheet, uno schema di collegamento e molti esempi di codice!
Per prima cosa diamo un’occhiata alla facile libreria Arduino Stepper. Questa libreria è ottima per chi inizia, ma non offre molte funzionalità extra.
Consiglio vivamente di dare un’occhiata anche agli esempi della libreria AccelStepper alla fine di questo tutorial. Questa libreria è abbastanza semplice da usare e può migliorare notevolmente le prestazioni del tuo hardware.
Dopo ogni esempio, spiego come funziona il codice, così non avrai problemi a modificarlo secondo le tue esigenze.
Materiale necessario
Componenti hardware
| 28BYJ-48 stepper motor | × 1 | Amazon | |
| ULN2003 driver board | × 1 | Amazon | |
| Arduino Uno Rev3 | × 1 | Amazon | |
| Jumper wires(maschio-femmina) | × 10 | Amazon | |
| Breadboard(opzionale, facilita il cablaggio) | × 1 | Amazon | |
| USB cable type A/B | × 1 | Amazon | |
| 5V power supply(alimentare direttamente il motore passo-passo dall’Arduino può danneggiarlo!) | × 1 | Amazon |
Software
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.
Informazioni sul motore passo-passo 28BYJ-48 e sulla scheda driver ULN2003
Il 28BYJ-48 è uno dei motori passo-passo più economici che puoi trovare. Anche se non è molto preciso o potente, è un ottimo motore per progetti piccoli o per imparare a conoscere i motori passo-passo.
Questo motore è spesso usato per regolare automaticamente le alette di un condizionatore. Ha un riduttore integrato che aumenta la coppia e riduce drasticamente la velocità.
Di seguito trovi le specifiche sia del motore passo-passo che del driver usati in questo tutorial.
Specifiche motore passo-passo 28BYJ-48
| Tensione nominale | 5 V |
| Resistenza della bobina | 50 Ohm |
| Tipo di bobina | Unipolare |
| Diametro dell’albero | 0,197″ (5,00 mm) |
| Lunghezza dell’albero e cuscinetto | 0,394″ (10 mm) |
| Caratteristiche | Albero piatto |
| Dimensioni | Rotondo – diametro 1,100″ (28,00 mm) |
| Distanza tra i fori di montaggio | Albero piatto |
| Riduzione ingranaggi | 1/64 (vedi nota) |
| Angolo di passo | Modalità mezzo passo (consigliata): 0,0879° Modalità passo intero: 0,176° |
| Passi per rivoluzione | Modalità mezzo passo: 4096 (vedi nota) Modalità passo intero: 2048 |
| Tipo di terminazione | Cavi con connettore |
| Tipo di motore | Motore a magnete permanente con ingranaggi |
| Numero di fasi | 4 |
| Costo | Check price |
Per maggiori informazioni puoi consultare il datasheet qui.
Nota importante: I produttori solitamente indicano una riduzione degli ingranaggi di 64:1. Alcuni membri della Arduino Forums community hanno notato che questo non era corretto e hanno smontato alcuni motori per verificare il rapporto reale. Hanno determinato che il rapporto esatto è in realtà 63,68395:1, che corrisponde a circa 4076 passi per rivoluzione completa (in modalità mezzo passo).
Non sono sicuro che tutti i produttori usino lo stesso riduttore, ma puoi semplicemente regolare i passi per rivoluzione nel codice per adattarlo al tuo modello.
Il Adafruit Industries Small Reduction Stepper Motor usa lo stesso formato del 28BYJ-48, ma ha un rapporto di ingranaggi diverso. Ha una riduzione di circa 1/16, che porta a 513 passi per rivoluzione (in modalità passo intero). Puoi scaricare il datasheet qui.
Collegamenti – Connessione del motore passo-passo 28BYJ-48 e scheda driver ULN2003 ad Arduino UNO
Lo schema di collegamento qui sotto mostra come connettere la scheda driver ULN2003 al motore passo-passo 28BYJ-48 e all’Arduino. Le connessioni sono anche riportate nella tabella sottostante.

Ho usato una breadboard e alcuni jumper per collegare la scheda driver a un’alimentazione esterna.
Connessioni ULN2003 e 28BYJ-48 ad Arduino
| Scheda driver ULN2003 | Connessione |
|---|---|
| IN1 | Pin 8 Arduino |
| IN2 | Pin 9 Arduino |
| IN3 | Pin 10 Arduino |
| IN4 | Pin 11 Arduino |
| – | GND logica Arduino |
| – | GND alimentazione |
| + | 5 V alimentazione |
Nota bene: È possibile alimentare direttamente il motore passo-passo dall’uscita 5 V dell’Arduino, ma non è consigliato. Quando il motore assorbe troppa corrente puoi danneggiare l’Arduino. Ho anche notato che alimentando l’Arduino solo via USB, il motore si comportava in modo irregolare e con prestazioni scadenti.
Consiglio di alimentare la scheda driver/motore passo-passo con un’alimentazione esterna da 5 V, come questa. Dovrebbe avere un connettore DC femmina, così puoi collegarlo facilmente con dei jumper. Ricorda di collegare anche il GND dell’Arduino al pin – della scheda driver ULN2003.
Dopo aver caricato il codice devi anche alimentare l’Arduino, sia con un cavo USB tipo B sia tramite il jack di alimentazione da 5,5 mm.
Il jumper accanto ai collegamenti di alimentazione sulla scheda driver può essere usato per scollegare l’alimentazione al motore passo-passo.
Esempio base di codice Arduino per controllare un motore passo-passo 28BYJ-48
Puoi caricare il seguente esempio di codice sul tuo Arduino usando l’IDE Arduino.
Questo esempio usa la libreria Stepper.h, che dovrebbe essere preinstallata nell’IDE Arduino. Questo sketch fa ruotare il motore passo-passo di 1 rivoluzione in una direzione, si ferma, poi ruota di 1 rivoluzione nell’altra direzione.
/*
Example sketch to control a 28BYJ-48 stepper motor
with ULN2003 driver board and Arduino UNO.
More info: https://www.makerguides.com
*/
// Include the Arduino Stepper.h library:
#include "Stepper.h"
// Define number of steps per rotation:
const int stepsPerRevolution = 2048;
// Wiring:
// Pin 8 to IN1 on the ULN2003 driver
// Pin 9 to IN2 on the ULN2003 driver
// Pin 10 to IN3 on the ULN2003 driver
// Pin 11 to IN4 on the ULN2003 driver
// Create stepper object called 'myStepper', note the pin order:
Stepper myStepper = Stepper(stepsPerRevolution, 8, 10, 9, 11);
void setup() {
// Set the speed to 5 rpm:
myStepper.setSpeed(5);
// Begin Serial communication at a baud rate of 9600:
Serial.begin(9600);
}
void loop() {
// Step one revolution in one direction:
Serial.println("clockwise");
myStepper.step(stepsPerRevolution);
delay(500);
// Step one revolution in the other direction:
Serial.println("counterclockwise");
myStepper.step(-stepsPerRevolution);
delay(500);
}
Spiegazione del codice:
Lo sketch inizia includendo la libreria Arduino Stepper.h. Maggiori informazioni su questa libreria si trovano su Arduino website.
// Include the Arduino Stepper.h library: #include "Stepper.h"
Poi definisco quanti passi il motore compie per fare una rivoluzione completa. In questo esempio useremo il motore in modalitàpasso intero. Ciò significa che servono 2048 passi per ruotare di 360 gradi (vedi specifiche motore sopra).
// Define number of steps per rotation: const int stepsPerRevolution = 2048;
Successivamente, devi creare una nuova istanza della classe Stepper, che rappresenta un motore passo-passo collegato all’Arduino. Per questo usiamo la funzioneStepper(steps, pin1, pin2, pin3, pin4)dove steps è il numero di passi per rivoluzione e pin1 fino a pin4 sono i pin a cui il motore è collegato. Per ottenere la sequenza corretta, dobbiamo impostare i pin nell’ordine: 8, 10, 9, 11.
// Create stepper object called 'myStepper', note the pin order: Stepper myStepper = Stepper(stepsPerRevolution, 8, 10, 9, 11);
In questo caso ho chiamato il motore ‘myStepper’, ma puoi usare altri nomi come ‘z_motor’ o ‘liftmotor’ ecc.Stepper liftmotor = Stepper(stepsPerRevolution, 8, 10, 9, 11);. Puoi creare più oggetti motore passo-passo con nomi e pin diversi. Questo ti permette di controllare facilmente 2 o più motori contemporaneamente.
Nel setup puoi impostare la velocità in rpm con la funzionesetSpeed(rpm). La velocità massima per un motore 28BYJ-48 è circa 10-15 rpm a 5 V.
void setup() {
// Set the speed to 5 rpm:
myStepper.setSpeed(5);
// Begin Serial communication at a baud rate of 9600:
Serial.begin(9600);
}
Nella sezione loop del codice, chiamiamo semplicemente la funzionestep(steps)che fa ruotare il motore di un numero specifico di passi a una velocità determinata dalla funzionesetSpeed(rpm). Passare un numero negativo a questa funzione inverte il senso di rotazione del motore.
void loop() {
// Step one revolution in one direction:
Serial.println("clockwise");
myStepper.step(stepsPerRevolution);
delay(500);
// Step one revolution in the other direction:
Serial.println("counterclockwise");
myStepper.step(-stepsPerRevolution);
delay(500);
}
Esempi di codice per motore passo-passo 28BYJ-48 con Arduino e libreria AccelStepper
Nei seguenti tre esempi ti mostrerò come controllare velocità, direzione e numero di passi che il motore deve compiere. In questi esempi userò la libreria AccelStepper.
La libreria AccelStepper scritta da Mike McCauley è fantastica per i tuoi progetti. Uno dei vantaggi è che supporta accelerazione e decelerazione, ma ha anche molte altre funzioni utili.
Puoi scaricare l’ultima versione di questa libreria cliccando il pulsante qui sotto.
Puoi installare la libreria andando su Sketch > Include Library > Add .ZIP Library… nell’IDE Arduino.
Un’altra opzione è andare suTools > Manage Libraries…o premere Ctrl + Shift + I su Windows. Si aprirà il Library Manager che aggiornerà la lista delle librerie installate.

Puoi cercare ‘accelstepper’ e trovare la libreria di Mike McCauley. Seleziona l’ultima versione e clicca su Install.

1. Esempio di rotazione continua
Lo sketch seguente può essere usato per far girare uno o più motori passo-passo continuamente a velocità costante. (Non si usa accelerazione o decelerazione).
Puoi copiare il codice cliccando il pulsante in alto a destra nel campo del codice.
/*
Example sketch to control a 28BYJ-48 stepper motor
with ULN2003 driver board, AccelStepper and Arduino UNO:
continuous rotation. More info: https://www.makerguides.com
*/
// Include the AccelStepper library:
#include "AccelStepper.h"
// Motor pin definitions:
#define motorPin1 8 // IN1 on the ULN2003 driver
#define motorPin2 9 // IN2 on the ULN2003 driver
#define motorPin3 10 // IN3 on the ULN2003 driver
#define motorPin4 11 // IN4 on the ULN2003 driver
// Define the AccelStepper interface type: 4 wire motor in half step mode:
#define MotorInterfaceType 8
// Initialize with pin sequence IN1-IN3-IN2-IN4
AccelStepper stepper = AccelStepper(MotorInterfaceType, motorPin1, motorPin3, motorPin2, motorPin4);
void setup() {
// Set the maximum steps per second:
stepper.setMaxSpeed(1000);
}
void loop() {
// Set the speed of the motor in steps per second:
stepper.setSpeed(500);
// Step the motor with constant speed as set by setSpeed():
stepper.runSpeed();
}
Come funziona il codice:
Il primo passo è includere la libreria con#include "AccelStepper.h“.
// Include the AccelStepper library: #include "AccelStepper.h"
Il passo successivo è definire le connessioni ULN2003-Arduino.
La dichiarazione#defineserve per dare un nome a un valore costante. Il compilatore sostituirà ogni riferimento a questa costante con il valore definito durante la compilazione. Quindi ovunque menzionimotorPin1, il compilatore lo sostituirà con il valore 8 durante la compilazione.
// Motor pin definitions: #define motorPin1 8 // IN1 on the ULN2003 driver #define motorPin2 9 // IN2 on the ULN2003 driver #define motorPin3 10 // IN3 on the ULN2003 driver #define motorPin4 11 // IN4 on the ULN2003 driver
Il passo successivo è specificare il tipo di interfaccia motore per la libreria AccelStepper. In questo caso guideremo un motore passo-passo a 4 fili in modalità mezzo passo, quindi impostiamo interface type a ‘8’. Se vuoi far girare il motore in modalità passo intero (meno passi per rivoluzione), cambia l’8 in 4.
// Define the AccelStepper interface type: 4 wire motor in half step mode: #define MotorInterfaceType 8
Poi devi creare una nuova istanza della classe AccelStepper con il tipo di interfaccia motore e le connessioni appropriate. Per ottenere la sequenza corretta, dobbiamo impostare i pin nell’ordine: motorPin1, motorPin3, motorPin2, motorPin4.
In questo caso ho chiamato il motore ‘stepper’, ma puoi usare altri nomi come ‘z_motor’ o ‘liftmotor’ ecc.AccelStepper liftmotor = AccelStepper(MotorInterfaceType, motorPin1, motorPin3, motorPin2, motorPin4);. Puoi creare più oggetti motore passo-passo con nomi e pin diversi. Questo ti permette di controllare facilmente 2 o più motori contemporaneamente.
// Initialize with pin sequence IN1-IN3-IN2-IN4 AccelStepper stepper = AccelStepper(MotorInterfaceType, motorPin1, motorPin3, motorPin2, motorPin4);
Nel setup definiamo la velocità massima in passi/secondo con la funzionesetMaxSpeed(). Velocità superiori a 1000 passi al secondo possono essere inaffidabili, quindi ho impostato questo valore come massimo. Nota che specifico il nome del motore (‘stepper’) per cui voglio definire la velocità massima. Se hai più motori collegati, puoi impostare velocità diverse per ciascuno:stepper2.setMaxSpeed(500);.
void setup() {
// Set the maximum steps per second:
stepper.setMaxSpeed(1000);
}
Nel loop, prima impostiamo la velocità a cui vogliamo far girare il motore con la funzionesetSpeed(). (puoi anche metterla nel setup).
stepper.runSpeed() controlla il motore e quando è il momento di fare un passo, esegue 1 passo. Questo dipende dalla velocità impostata e dal tempo trascorso dall’ultimo passo. Per cambiare direzione puoi impostare una velocità negativa:stepper.setSpeed(-400); fa girare il motore nell’altra direzione.
void loop() {
// Set the speed of the motor in steps per second:
stepper.setSpeed(500);
// Step the motor with constant speed as set by setSpeed():
stepper.runSpeed();
}
In modalità mezzo passo, una rivoluzione richiede 4096 passi, quindi 500 passi/sec corrispondono a circa7 rpm.
2. Sketch per controllare numero di passi o rivoluzioni
Con questo sketch puoi controllare velocità, direzione e numero di passi/rivoluzioni.
In questo caso, il motore ruota 1 rivoluzione in senso orario a 500 passi/sec, poi 1 rivoluzione antioraria a 1000 passi/sec, e infine 2 rivoluzioni orarie a 1000 passi/sec.
/* Example sketch to control a 28BYJ-48 stepper motor with
ULN2003 driver board, AccelStepper and Arduino UNO
More info: https://www.makerguides.com */
#include "AccelStepper.h"
// Motor pin definitions:
#define motorPin1 8 // IN1 on the ULN2003 driver
#define motorPin2 9 // IN2 on the ULN2003 driver
#define motorPin3 10 // IN3 on the ULN2003 driver
#define motorPin4 11 // IN4 on the ULN2003 driver
// Define the AccelStepper interface type; 4 wire motor in half step mode:
#define MotorInterfaceType 8
// Initialize with pin sequence IN1-IN3-IN2-IN4 for using the AccelStepper library with 28BYJ-48 stepper motor:
AccelStepper stepper = AccelStepper(MotorInterfaceType, motorPin1, motorPin3, motorPin2, motorPin4);
void setup() {
// Set the maximum steps per second:
stepper.setMaxSpeed(1000);
}
void loop() {
// Set the current position to 0:
stepper.setCurrentPosition(0);
// Run the motor forward at 500 steps/second until the motor reaches 4096 steps (1 revolution):
while (stepper.currentPosition() != 4096) {
stepper.setSpeed(500);
stepper.runSpeed();
}
delay(1000);
// Reset the position to 0:
stepper.setCurrentPosition(0);
// Run the motor backwards at 1000 steps/second until the motor reaches -4096 steps (1 revolution):
while (stepper.currentPosition() != -4096) {
stepper.setSpeed(-1000);
stepper.runSpeed();
}
delay(1000);
// Reset the position to 0:
stepper.setCurrentPosition(0);
// Run the motor forward at 1000 steps/second until the motor reaches 8192 steps (2 revolutions):
while (stepper.currentPosition() != 8192) {
stepper.setSpeed(1000);
stepper.runSpeed();
}
delay(3000);
}
Spiegazione del codice:
La prima parte del codice fino alla sezione loop() è identica all’esempio precedente.
Nel loop uso un ciclo while in combinazione con la funzionecurrentPosition(). Prima imposto la posizione corrente del motore a zero constepper.setCurrentPosition(0).
// Set the current position to 0: stepper.setCurrentPosition(0);
Poi usiamo il ciclo while. Un ciclo while ripete continuamente, all’infinito, finché l’espressione tra parentesi () diventa falsa. Qui controllo se la posizione corrente del motore non è uguale a 4096 passi (!= significa: non è uguale a). Finché è vero, facciamo girare il motore a velocità costante impostata dasetSpeed().
// Run the motor forward at 500 steps/second until the motor reaches 4096 steps (1 revolution):
while (stepper.currentPosition() != 4096) {
stepper.setSpeed(500);
stepper.runSpeed();
}
Nel resto del loop facciamo esattamente lo stesso, ma con velocità e posizione target diverse.
3. Esempio di codice con accelerazione e decelerazione
Con questo sketch puoi aggiungere accelerazione e decelerazione ai movimenti del motore passo-passo senza codici complicati. La prima parte dello sketch è uguale all’esempio 1, ma setup e loop sono diversi.
Il motore farà due rivoluzioni avanti e indietro a 1000 passi al secondo con un’accelerazione di 200 passi/secondo².
/*
Example sketch to control a 28BYJ-48 stepper motor with ULN2003 driver board,
AccelStepper and Arduino UNO: acceleration and deceleration.
More info: https://www.makerguides.com
*/
#include "AccelStepper.h"
// Motor pin definitions:
#define motorPin1 8 // IN1 on the ULN2003 driver
#define motorPin2 9 // IN2 on the ULN2003 driver
#define motorPin3 10 // IN3 on the ULN2003 driver
#define motorPin4 11 // IN4 on the ULN2003 driver
// Define the AccelStepper interface type; 4 wire motor in half step mode:
#define MotorInterfaceType 8
// Initialize with pin sequence IN1-IN3-IN2-IN4
AccelStepper stepper = AccelStepper(MotorInterfaceType, motorPin1, motorPin3, motorPin2, motorPin4);
void setup() {
// Set the maximum steps per second:
stepper.setMaxSpeed(1000);
// Set the maximum acceleration in steps per second^2:
stepper.setAcceleration(200);
}
void loop() {
// Set target position:
stepper.moveTo(8192);
// Run to position with set speed and acceleration:
stepper.runToPosition();
delay(1000);
// Move back to original position:
stepper.moveTo(0);
// Run to position with set speed and acceleration:
stepper.runToPosition();
delay(1000);
}
Come funziona il codice:
Nel setup, oltre alla velocità massima, dobbiamo definire anche accelerazione e decelerazione. Per questo usiamo la funzionesetAcceleration().
void setup() {
// Set the maximum steps per second:
stepper.setMaxSpeed(1000);
// Set the maximum acceleration in steps per second^2:
stepper.setAcceleration(200);
}
Nel loop uso un metodo diverso per far ruotare il motore di un numero predefinito di passi. Prima imposto la posizione target con la funzionemoveTo(). Poi uso semplicemente la funzionerunToPosition()per far muovere il motore verso la posizione target con la velocità e accelerazione impostate. Il motore rallenterà prima di raggiungere la posizione.
void loop() {
// Set target position:
stepper.moveTo(8192);
// Run to position with set speed and acceleration:
stepper.runToPosition();
delay(1000);
// Move back to original position:
stepper.moveTo(0);
// Run to position with set speed and acceleration:
stepper.runToPosition();
delay(1000);
}
Infine imposto la nuova posizione target a 0, così torniamo all’origine.
Conclusione
In questo articolo ti ho mostrato come controllare un motore passo-passo 28BYJ-48 con un driver ULN2003 e Arduino. Abbiamo visto 4 esempi, usando sia la libreria Stepper che AccelStepper. Spero ti sia stato utile e interessante.
Se vuoi imparare a controllare motori passo-passo più grandi, con più coppia e velocità, dai un’occhiata agli articoli qui sotto. In questi articoli ti insegno come controllare motori NEMA 17 con driver come l’A4988.
Altri tutorial sui motori passo-passo:
- Control a stepper motor with L298N motor driver and Arduino
- How to control a Stepper Motor with Arduino Motor Shield Rev3
- How to control a stepper motor with A4988 driver and Arduino
- How to control a stepper motor with DRV8825 driver and Arduino
Se hai domande, lascia un commento qui sotto.

