Este artículo incluye todo lo que necesitas saber sobre cómo controlar un 28BYJ-48 motor paso a paso con la placa controladora ULN2003 y Arduino. He incluido hojas de datos, un diagrama de conexiones y muchos ejemplos de código.
Primero echamos un vistazo a la fácil de usar biblioteca Arduino Stepper. Esta biblioteca es ideal cuando estás empezando, pero no tiene muchas funciones adicionales.
Te recomiendo encarecidamente que también revises los ejemplos de código para la biblioteca AccelStepper al final de este tutorial. Esta biblioteca es bastante fácil de usar y puede mejorar mucho el rendimiento de tu hardware.
Después de cada ejemplo, desgloso y explico cómo funciona el código, para que no tengas problemas en modificarlo según tus necesidades.
Materiales
Componentes de hardware
| 28BYJ-48 stepper motor | × 1 | Amazon | |
| ULN2003 driver board | × 1 | Amazon | |
| Arduino Uno Rev3 | × 1 | Amazon | |
| Jumper wires(macho a hembra) | × 10 | Amazon | |
| Breadboard(opcional, facilita el cableado) | × 1 | Amazon | |
| USB cable type A/B | × 1 | Amazon | |
| 5V power supply(alimentar el motor paso a paso directamente desde el Arduino puede dañarlo) | × 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.
Información sobre el motor paso a paso 28BYJ-48 y la placa controladora ULN2003
El 28BYJ-48 es uno de los motores paso a paso más baratos que puedes encontrar. Aunque no es muy preciso ni potente, es un motor excelente para proyectos pequeños o si solo quieres aprender sobre motores paso a paso.
Este motor se usa a menudo para ajustar automáticamente las aletas de una unidad de aire acondicionado. Tiene una caja de engranajes incorporada, que le proporciona un par extra y reduce drásticamente la velocidad.
A continuación puedes encontrar las especificaciones tanto del motor paso a paso como del controlador usados en este tutorial.
Especificaciones del motor paso a paso 28BYJ-48
| Voltaje nominal | 5 V |
| Resistencia de la bobina | 50 Ohmios |
| Tipo de bobina | Unipolar |
| Diámetro del eje | 0.197″ (5.00 mm) |
| Longitud del eje y cojinete | 0.394″ (10 mm) |
| Características | Eje plano |
| Tamaño/dimensión | Redondo – 1.100″ de diámetro (28.00 mm) |
| Separación de los orificios de montaje | Eje plano |
| Reducción de engranajes | 1/64 (ver nota) |
| Ángulo de paso | Modo medio paso (recomendado): 0.0879° Modo paso completo: 0.176° |
| Pasos por revolución | Modo medio paso: 4096 (ver nota) Modo paso completo: 2048 |
| Estilo de terminación | Cables con conector |
| Tipo de motor | Motor con engranajes y imán permanente |
| Número de fases | 4 |
| Precio | Check price |
Para más información puedes consultar la hoja de datos aquí.
Nota importante: Los fabricantes suelen especificar que los motores tienen una reducción de engranajes de 64:1. Algunos miembros de la Arduino Forum scomunidad notaron que esto no era correcto y desmontaron algunos motores para comprobar la relación real de engranajes. Determinaron que la relación exacta es de 63.68395:1, lo que resulta en aproximadamente 4076 pasos por revolución completa (en modo medio paso).
No estoy seguro si todos los fabricantes usan exactamente la misma caja de engranajes, pero puedes ajustar los pasos por revolución en el código para que coincidan con tu modelo.
El Adafruit Industries Small Reduction Stepper Motor usa el mismo factor de forma que el 28BYJ-48, pero tiene una relación de engranajes diferente. Tiene una reducción aproximada de 1/16, lo que resulta en 513 pasos por revolución (en modo paso completo). Puedes descargar su hoja de datos aquí.
Cableado – Conexión del motor paso a paso 28BYJ-48 y la placa ULN2003 al Arduino UNO
El diagrama de cableado/esquemático a continuación muestra cómo conectar la placa controladora ULN2003 al motor paso a paso 28BYJ-48 y al Arduino. Las conexiones también se indican en la tabla siguiente.

Usé una protoboard y algunos cables jumper para conectar la placa controladora a una fuente de alimentación externa.
Conexiones ULN2003 y 28BYJ-48 al Arduino
| Placa controladora ULN2003 | Conexión |
|---|---|
| IN1 | Pin 8 Arduino |
| IN2 | Pin 9 Arduino |
| IN3 | Pin 10 Arduino |
| IN4 | Pin 11 Arduino |
| – | GND lógica Arduino |
| – | GND fuente de alimentación |
| + | 5 V fuente de alimentación |
Ten en cuenta: Es posible alimentar directamente el motor paso a paso desde la salida de 5 V del Arduino. Sin embargo, no se recomienda. Cuando el motor paso a paso consume demasiada corriente puedes dañar el Arduino. También he comprobado que al alimentar el Arduino solo por USB, el motor paso a paso se comporta de forma inconsistente y con bajo rendimiento.
Recomiendo alimentar la placa controladora/motor paso a paso con una fuente de alimentación externa de 5 V, como esta. Debería venir con un conector DC hembra, para que puedas conectarlo fácilmente a cables jumper. Ten en cuenta que también debes conectar el GND del Arduino al pin – de la placa ULN2003.
Después de subir el código también necesitas alimentar el Arduino, ya sea con un cable USB tipo B o mediante el conector de alimentación de 5.5 mm.
El jumper junto a las conexiones de alimentación en la placa controladora puede usarse para desconectar la alimentación al motor paso a paso.
Código básico de ejemplo para controlar un motor paso a paso 28BYJ-48 con Arduino
Puedes subir el siguiente código de ejemplo a tu Arduino usando el IDE de Arduino.
Este ejemplo usa la librería Stepper.h, que debería venir preinstalada con el IDE de Arduino. Este sketch hace girar el motor paso a paso 1 revolución en una dirección, pausa, y luego gira 1 revolución en la dirección opuesta.
/*
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);
}
Explicación del código:
El sketch comienza incluyendo la biblioteca Stepper.h de Arduino. Más información sobre esta biblioteca se puede encontrar en Arduino website.
// Include the Arduino Stepper.h library: #include "Stepper.h"
Luego, definí cuántos pasos da el motor para girar 1 revolución. En este ejemplo usaremos el motor en modopaso completo. Esto significa que toma 2048 pasos para girar 360 grados (ver especificaciones del motor arriba).
// Define number of steps per rotation: const int stepsPerRevolution = 2048;
A continuación, necesitas crear una nueva instancia de la clase Stepper, que representa un motor paso a paso conectado al Arduino. Para esto usamos la funciónStepper(steps, pin1, pin2, pin3, pin4)donde steps es el número de pasos por revolución y pin1 a pin4 son los pines a los que está conectado el motor. Para obtener la secuencia correcta de pasos, debemos configurar los pines en el siguiente orden: 8, 10, 9, 11.
// Create stepper object called 'myStepper', note the pin order: Stepper myStepper = Stepper(stepsPerRevolution, 8, 10, 9, 11);
En este caso llamé al motor paso a paso ‘myStepper’ pero puedes usar otros nombres, como ‘z_motor’ o ‘liftmotor’, etc.Stepper liftmotor = Stepper(stepsPerRevolution, 8, 10, 9, 11);. Puedes crear múltiples objetos de motor paso a paso con diferentes nombres y pines. Esto te permite controlar fácilmente 2 o más motores paso a paso al mismo tiempo.
En el setup, puedes establecer la velocidad en rpm con la funciónsetSpeed(rpm). La velocidad máxima para un motor paso a paso 28BYJ-48 es aproximadamente 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);
}
En la sección loop del código, simplemente llamamos a la funciónstep(steps)que gira el motor un número específico de pasos a una velocidad determinada por la funciónsetSpeed(rpm). Pasar un número negativo a esta función invierte la dirección de giro del motor.
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);
}
Ejemplos de código para motor paso a paso 28BYJ-48 con Arduino y biblioteca AccelStepper
En los siguientes tres ejemplos te mostraré cómo controlar la velocidad, la dirección y el número de pasos que debe dar el motor paso a paso. En estos ejemplos usaré la biblioteca AccelStepper.
La biblioteca AccelStepper, escrita por Mike McCauley, es una biblioteca excelente para usar en tu proyecto. Una de sus ventajas es que soporta aceleración y desaceleración, además de muchas otras funciones útiles.
Puedes instalar la biblioteca yendo a Sketch > Include Library > Add .ZIP Library…en el IDE de Arduino.
También puedes instalar la biblioteca yendo a Tools > Manage Libraries…o presionando Ctrl + Shift + I en Windows. Se abrirá el Library Manager y actualizará la lista de bibliotecas instaladas.

Puedes buscar ‘accelstepper’ y buscar la biblioteca de Mike McCauley. Selecciona la última versión y haz clic en Instalar.

1. Código de ejemplo para rotación continua
El siguiente sketch puede usarse para hacer girar uno o más motores paso a paso continuamente a una velocidad constante. (No se usa aceleración ni desaceleración).
Puedes copiar el código haciendo clic en el botón en la esquina superior derecha del campo de código.
/*
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();
}
Cómo funciona el código:
De nuevo, el primer paso es incluir la biblioteca con#include "AccelStepper.h«.
// Include the AccelStepper library: #include "AccelStepper.h"
El siguiente paso es definir las conexiones ULN2003 a Arduino.
La instrucción#definese usa para dar un nombre a un valor constante. El compilador reemplazará cualquier referencia a esta constante con el valor definido cuando se compile el programa. Así que donde mencionesmotorPin1, el compilador lo reemplazará por el valor 8 al compilar el programa.
// 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
El siguiente paso es especificar el tipo de interfaz del motor para la biblioteca AccelStepper. En este caso controlaremos un motor paso a paso de 4 cables en modo medio paso, así que configuramos el interface type en ‘8’. Si quieres usar el motor en modo paso completo (menos pasos por revolución), solo cambia el 8 por 4.
// Define the AccelStepper interface type: 4 wire motor in half step mode: #define MotorInterfaceType 8
Luego, necesitas crear una nueva instancia de la clase AccelStepper con el tipo de interfaz y conexiones apropiadas. Para obtener la secuencia correcta de pasos, debemos configurar los pines en el siguiente orden: motorPin1, motorPin3, motorPin2, motorPin4.
En este caso llamé al motor paso a paso ‘stepper’ pero puedes usar otros nombres, como ‘z_motor’ o ‘liftmotor’, etc.AccelStepper liftmotor = AccelStepper(MotorInterfaceType, motorPin1, motorPin3, motorPin2, motorPin4);. Puedes crear múltiples objetos de motor paso a paso con diferentes nombres y pines. Esto te permite controlar fácilmente 2 o más motores paso a paso al mismo tiempo.
// Initialize with pin sequence IN1-IN3-IN2-IN4 AccelStepper stepper = AccelStepper(MotorInterfaceType, motorPin1, motorPin3, motorPin2, motorPin4);
En la sección setup del código, definimos la velocidad máxima en pasos/segundo con la funciónsetMaxSpeed(). Velocidades superiores a 1000 pasos por segundo pueden ser poco fiables, así que establecí este valor como máximo. Ten en cuenta que especifico el nombre del motor paso a paso (‘stepper’) para el que quiero definir la velocidad máxima. Si tienes varios motores conectados, puedes definir una velocidad diferente para cada uno:stepper2.setMaxSpeed(500);.
void setup() {
// Set the maximum steps per second:
stepper.setMaxSpeed(1000);
}
En el loop, primero establecemos la velocidad a la que queremos que gire el motor con la funciónsetSpeed(). (también puedes poner esto en la sección setup del código).
stepper.runSpeed()poll()§
§poll()§
§§consulta el motor y cuando toca dar un paso ejecuta 1 paso. Esto depende de la velocidad establecida y del tiempo desde el último paso. Si quieres cambiar la dirección del motor, puedes establecer una velocidad negativa:stepper.setSpeed(-400);setSpeed()§
§gira el motor en sentido contrario.
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();
}
En modo medio paso, una revolución toma 4096 pasos, así que 500 pasos/segundo resultan en aproximadamente7 rpm.
2. Sketch para controlar número de pasos o revoluciones
Con el siguiente sketch puedes controlar la velocidad, dirección y número de pasos/revoluciones.
En este caso, el motor paso a paso gira 1 revolución en sentido horario a 500 pasos/segundo, luego 1 revolución en sentido antihorario a 1000 pasos/segundo, y finalmente 2 revoluciones en sentido horario a 1000 pasos/segundo.
/* 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);
}
Explicación del código:
La primera parte del código hasta la sección loop() es exactamente igual que en el ejemplo anterior.
En el loop uso un bucle while combinado con la funcióncurrentPosition(). Primero, establezco la posición actual del motor paso a paso a cero constepper.setCurrentPosition(0).
// Set the current position to 0: stepper.setCurrentPosition(0);
Luego usamos el bucle while. Un bucle while se ejecuta continuamente e infinitamente hasta que la expresión dentro de los paréntesis () se vuelve falsa. Así que en este caso compruebo si la posición actual del motor paso a paso no es igual a 4096 pasos (!= significa: no es igual a). Mientras esto sea cierto, hacemos girar el motor a una velocidad constante establecida porsetSpeed().
// 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();
}
En el resto del loop hacemos exactamente lo mismo, solo que con una velocidad y posición objetivo diferentes.
3. Código de ejemplo con aceleración y desaceleración
Con el siguiente sketch puedes añadir aceleración y desaceleración a los movimientos del motor paso a paso, sin codificación complicada. La primera sección de este sketch es igual que en el ejemplo 1, pero el setup y el loop son diferentes.
El motor girará dos revoluciones de ida y vuelta con una velocidad de 1000 pasos por segundo y una aceleración de 200 pasos/segundo².
/*
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);
}
Cómo funciona el código:
En el setup, además de la velocidad máxima, también definimos la aceleración/desaceleración. Para esto usamos la funciónsetAcceleration().
void setup() {
// Set the maximum steps per second:
stepper.setMaxSpeed(1000);
// Set the maximum acceleration in steps per second^2:
stepper.setAcceleration(200);
}
En la sección loop del código, usé una forma diferente para hacer que el motor gire un número predefinido de pasos. Primero establezco la posición objetivo con la funciónmoveTo(). Luego simplemente usamos la funciónrunToPosition()para que el motor se mueva a la posición objetivo con la velocidad y aceleración establecidas. El motor desacelerará antes de llegar a la posición objetivo.
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);
}
Finalmente, establecemos la nueva posición objetivo a 0, para volver al origen.
Conclusión
En este artículo te he mostrado cómo controlar un motor paso a paso 28BYJ-48 con un controlador ULN2003 y Arduino. Hemos visto 4 ejemplos, usando tanto las bibliotecas Stepper como AccelStepper. Espero que te haya resultado útil e informativo.
Si quieres aprender más sobre cómo controlar motores paso a paso más grandes con más par y velocidad, echa un vistazo a los artículos siguientes. En ellos te enseño cómo controlar motores NEMA 17 con controladores como el A4988.
Otros tutoriales de motores paso a paso:
- 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
Si tienes alguna pregunta, por favor deja un comentario abajo.

