El 28BYJ-48 con su driver ULN2003 es la forma más barata de tener un motor que se mueve a una posición exacta. Con un Arduino Nano basta con encender las cuatro bobinas en el orden correcto.
También te puede interesar

El programa
// Motor de pasos 28BYJ-48 con driver ULN2003 y Arduino Nano.
// Medio paso: 8 fases por ciclo, unos 4096 pasos por vuelta del eje.
const int PINES[4] = {2, 3, 4, 5}; // IN1..IN4 del ULN2003
const byte FASES[8][4] = {
{1, 0, 0, 0},
{1, 1, 0, 0},
{0, 1, 0, 0},
{0, 1, 1, 0},
{0, 0, 1, 0},
{0, 0, 1, 1},
{0, 0, 0, 1},
{1, 0, 0, 1},
};
const long PASOS_POR_VUELTA = 4096;
const unsigned int ESPERA_US = 1200; // si el motor vibra pero no gira, sube este valor
int fase = 0;
void aplicarFase(int f) {
for (int i = 0; i < 4; i++) {
digitalWrite(PINES[i], FASES[f][i]);
}
}
void girar(long pasos) { // positivo: un sentido; negativo: el otro
int sentido = pasos > 0 ? 1 : -1;
for (long i = 0; i < abs(pasos); i++) {
fase = (fase + sentido + 8) % 8;
aplicarFase(fase);
delayMicroseconds(ESPERA_US);
}
}
void soltar() { // sin corriente en las bobinas: no se calientan
for (int i = 0; i < 4; i++) {
digitalWrite(PINES[i], LOW);
}
}
void setup() {
for (int i = 0; i < 4; i++) {
pinMode(PINES[i], OUTPUT);
}
}
void loop() {
girar(PASOS_POR_VUELTA); // una vuelta
soltar();
delay(1000);
girar(-PASOS_POR_VUELTA / 4); // un cuarto de vuelta hacia atrás
soltar();
delay(1000);
}arduino-cli compile --fqbn arduino:avr:nanoSketch uses 1294 bytes (4%) of program storage space. Maximum is 30720 bytes. Global variables use 51 bytes (2%) of dynamic memory, leaving 1997 bytes for local variables. Maximum is 2048 bytes.
Cómo funciona
La secuencia de medio paso. Ocho fases que van encendiendo una bobina, luego dos, luego la siguiente. Recorrerlas hacia delante gira el eje en un sentido; hacia atrás, en el otro. Por eso girar acepta pasos negativos.
Paso completo o medio paso. La versión anterior de esta página usaba solo cuatro fases, siempre con dos bobinas encendidas: es el paso completo. Da más fuerza, pero la mitad de resolución: unos 2048 pasos por vuelta en lugar de 4096. Las dos formas son válidas.
int ESTADOS[8][4] y solo rellenaba cuatro filas: las otras cuatro existían, a cero, ocupando memoria sin uso. En un Nano, con 2 KB de RAM, conviene ajustar: aquí la tabla es de byte y tiene las ocho filas que se usan. Compilado, el programa anterior ocupaba 75 bytes de RAM y este 51, aunque hace más cosas.soltar() apaga las cuatro bobinas al terminar cada movimiento. Sin ella, el motor se queda con corriente aunque esté quieto y se calienta, igual que el driver. Mientras está suelto, el eje se puede girar con la mano: si necesitas que mantenga la posición contra una fuerza, no lo sueltes.
Con la librería Stepper
#include <Stepper.h>
const int PASOS_POR_VUELTA = 2048;
Stepper motor(PASOS_POR_VUELTA, 2, 4, 3, 5); // ¡IN1, IN3, IN2, IN4!
void setup() {
motor.setSpeed(10); // vueltas por minuto
}
void loop() {
motor.step(PASOS_POR_VUELTA);
delay(1000);
}Arduino trae una librería, Stepper, que hace lo mismo en paso completo. Tiene una trampa conocida con este motor: los pines se pasan en el orden 1, 3, 2, 4. Con el orden natural, el motor vibra pero no gira.
Revisada en octubre de 2026. Los dos programas se compilaron con arduino-cli 1.5.1 para el Arduino Nano (arduino:avr:nano) sin ningún aviso; las cifras de memoria son las del compilador. No se han probado con el motor físico.