Este artigo inclui tudo o que precisa de saber sobre como controlar um 28BYJ-48 motor de passo com a placa driver ULN2003 e Arduino. Incluí datasheets, um diagrama de ligações e muitos exemplos de código!
Primeiro, vamos analisar a fácil de usar biblioteca Arduino Stepper. Esta biblioteca é ótima para iniciantes, mas não tem muitas funcionalidades extra.
Recomendo vivamente que também veja os exemplos de código para abiblioteca AccelStepperno final deste tutorial. Esta biblioteca é relativamente fácil de usar e pode melhorar muito o desempenho do seu hardware.
Após cada exemplo, explico detalhadamente como o código funciona, para que não tenha problemas em modificá-lo conforme as suas necessidades.
Materiais necessários
Componentes de hardware
| 28BYJ-48 stepper motor | × 1 | Amazon | |
| ULN2003 driver board | × 1 | Amazon | |
| Arduino Uno Rev3 | × 1 | Amazon | |
| Jumper wires(macho para fêmea) | × 10 | Amazon | |
| Breadboard(opcional, facilita as ligações) | × 1 | Amazon | |
| USB cable type A/B | × 1 | Amazon | |
| 5V power supply(alimentar o motor de passo diretamente pelo Arduino pode danificá-lo!) | × 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.
Informações sobre o motor de passo 28BYJ-48 e a placa driver ULN2003
O 28BYJ-48 é um dos motores de passo mais baratos que pode encontrar. Embora não seja muito preciso nem potente, é um ótimo motor para projetos pequenos ou para aprender sobre motores de passo.
Este motor é frequentemente usado para ajustar automaticamente as lâminas de unidades de ar condicionado. Tem uma caixa de engrenagens incorporada, que lhe confere mais torque e reduz drasticamente a velocidade.
Abaixo pode encontrar as especificações tanto do motor de passo como do driver usados neste tutorial.
Especificações do motor de passo 28BYJ-48
| Tensão nominal | 5 V |
| Resistência da bobina | 50 Ohms |
| Tipo de bobina | Unipolar |
| Diâmetro do eixo | 0,197″ (5,00 mm) |
| Comprimento do eixo e rolamento | 0,394″ (10 mm) |
| Características | Eixo chato |
| Dimensões | Redondo – 1,100″ diâmetro (28,00 mm) |
| Espaçamento dos furos de montagem | Eixo chato |
| Redução da engrenagem | 1/64 (ver nota) |
| Ângulo de passo | Modo meio passo (recomendado): 0,0879° Modo passo completo: 0,176° |
| Passos por revolução | Modo meio passo: 4096 (ver nota) Modo passo completo: 2048 |
| Tipo de terminação | Fios com conector |
| Tipo de motor | Motor de engrenagem com íman permanente |
| Número de fases | 4 |
| Custo | Check price |
Para mais informações pode consultar o datasheet aqui.
Nota importante: Os fabricantes normalmente especificam que os motores têm uma redução de engrenagem de 64:1. Alguns membros da Arduino Forums comunidade notaram que isto não estava correto e desmontaram alguns motores para verificar a relação real da engrenagem. Determinaram que a relação exata é de facto 63,68395:1, o que resulta em aproximadamente 4076 passos por revolução completa (em modo meio passo).
Não tenho a certeza se todos os fabricantes usam exatamente a mesma caixa de engrenagens, mas pode simplesmente ajustar os passos por revolução no código para corresponder ao seu modelo.
OAdafruit Industries Small Reduction Stepper Motor usa o mesmo formato do 28BYJ-48, mas tem uma relação de engrenagem diferente. Tem uma redução de cerca de 1/16, o que resulta em 513 passos por revolução (em modo passo completo). Pode descarregar o datasheet aqui.
Ligações – Conectar o motor de passo 28BYJ-48 e a placa driver ULN2003 ao Arduino UNO
O diagrama/esquema de ligações abaixo mostra como ligar a placa driver ULN2003 ao motor de passo 28BYJ-48 e ao Arduino. As ligações estão também indicadas na tabela abaixo.

Usei uma breadboard e alguns fios jumper para ligar a placa driver a uma fonte de alimentação externa.
Ligações ULN2003 e 28BYJ-48 ao Arduino
| Placa driver ULN2003 | Ligação |
|---|---|
| IN1 | Pino 8 do Arduino |
| IN2 | Pino 9 do Arduino |
| IN3 | Pino 10 do Arduino |
| IN4 | Pino 11 do Arduino |
| – | GND lógico do Arduino |
| – | GND da fonte de alimentação |
| + | 5 V da fonte de alimentação |
Note que: É possível alimentar diretamente o motor de passo a partir da saída de 5 V do Arduino. No entanto, não é recomendado. Quando o motor de passo puxa muita corrente podedanificar o Arduino. Também notei que ao alimentar o Arduino apenas por USB, o motor de passo apresentava comportamento inconsistente e mau desempenho.
Recomendo alimentar a placa driver/motor de passo com uma fonte de 5 V externa, como esta. Deve ter um conector DC fêmea, para ligar facilmente a fios jumper. Note que também precisa de ligar o GND do Arduino ao pino – da placa driver ULN2003.
Após carregar o códigotambém precisa de alimentar o Arduino, seja com um cabo USB tipo B ou através da ficha de alimentação de 5,5 mm.
O jumper ao lado das ligações de alimentação na placa driver pode ser usado para desligar a alimentação do motor de passo.
Exemplo básico de código Arduino para controlar um motor de passo 28BYJ-48
Pode carregar o seguinte exemplo de código no seu Arduino usando o Arduino IDE.
Este exemplo usa abiblioteca Stepper.h, que já vem pré-instalada no Arduino IDE. Este sketch faz o motor de passo dar uma revolução numa direção, pausa, e depois dá uma revolução na direção oposta.
/*
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);
}
Explicação do código:
O sketch começa por incluir a biblioteca Arduino Stepper.h. Mais informações sobre esta biblioteca podem ser encontradas em Arduino website.
// Include the Arduino Stepper.h library: #include "Stepper.h"
De seguida, defini quantos passos o motor dá para rodar 1 revolução. Neste exemplo usaremos o motor emmodo passo completo. Isto significa que são necessários 2048 passos para rodar 360 graus (veja as especificações do motor acima).
// Define number of steps per rotation: const int stepsPerRevolution = 2048;
Depois, precisa criar uma nova instância da classe Stepper, que representa um motor de passo específico ligado ao Arduino. Para isso usamos a funçãoStepper(steps, pin1, pin2, pin3, pin4)onde steps é o número de passos por revolução e pin1 a pin4 são os pinos aos quais o motor está ligado. Para obter a sequência correta de passos, temos de definir os pinos na seguinte ordem: 8, 10, 9, 11.
// Create stepper object called 'myStepper', note the pin order: Stepper myStepper = Stepper(stepsPerRevolution, 8, 10, 9, 11);
Neste caso chamei o motor de passo ‘myStepper’, mas pode usar outros nomes, como ‘z_motor’ ou ‘liftmotor’, etc.Stepper liftmotor = Stepper(stepsPerRevolution, 8, 10, 9, 11);Pode criar múltiplos objetos de motor de passo com nomes e pinos diferentes. Isto permite controlar facilmente 2 ou mais motores de passo ao mesmo tempo.
No setup, pode definir a velocidade em rpm com a funçãosetSpeed(rpm). Avelocidade máximapara um motor 28BYJ-48 é aproximadamente10-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);
}
Na secção loop do código, chamamos simplesmente a funçãostep(steps)que roda o motor um número específico de passos a uma velocidade determinada pela funçãosetSpeed(rpm). Passar um número negativo a esta função inverte a direção de rotação do 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);
}
Exemplos de código para motor de passo 28BYJ-48 com Arduino e biblioteca AccelStepper
Nos três exemplos seguintes vou mostrar como controlar a velocidade, direção e número de passos que o motor de passo deve dar. Nestes exemplos usarei abiblioteca AccelStepper.
A biblioteca AccelStepper, escrita por Mike McCauley, é uma excelente biblioteca para usar no seu projeto. Uma das vantagens é que suporta aceleração e desaceleração, além de muitas outras funções úteis.
Pode instalar a biblioteca indo aSketch > Include Library > Add .ZIP Library…no Arduino IDE.
Pode instalar a biblioteca indo aTools > Manage Libraries…ou pressionar Ctrl + Shift + I no Windows. O Gestor de Bibliotecas abrirá e atualizará a lista de bibliotecas instaladas.

Pode procurar por ‘accelstepper’ e procurar a biblioteca do Mike McCauley. Selecione a versão mais recente e clique em Instalar.

1. Exemplo de código para rotação contínua
O seguinte sketch pode ser usado para fazer um ou mais motores de passo rodarem continuamente a uma velocidade constante. (Não é usada aceleração nem desaceleração).
Pode copiar o código clicando no botão no canto superior direito do 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();
}
Como o código funciona:
O primeiro passo é incluir a biblioteca com#include "AccelStepper.h“.
// Include the AccelStepper library: #include "AccelStepper.h"
O passo seguinte é definir as ligações do ULN2003 ao Arduino.
A instrução#defineé usada para dar um nome a um valor constante. O compilador substituirá todas as referências a esta constante pelo valor definido quando o programa for compilado. Assim, sempre que mencionarmotorPin1, o compilador substituirá pelo valor 8 quando o programa for compilado.
// 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
O passo seguinte é especificar o tipo de interface do motor para a biblioteca AccelStepper. Neste caso vamos controlar um motor de passo de 4 fios emmodo meio passo, por isso definimos o interface type para ‘8’. Se quiser usar o motor em modo passo completo (menos passos por revolução), basta mudar o 8 para 4.
// Define the AccelStepper interface type: 4 wire motor in half step mode: #define MotorInterfaceType 8
Depois, precisa criar uma nova instância da classe AccelStepper com o tipo de interface do motor e as ligações apropriadas. Para obter a sequência correta de passos, temos de definir os pinos na seguinte ordem:motorPin1, motorPin3, motorPin2, motorPin4.
Neste caso chamei o motor de passo ‘stepper’, mas pode usar outros nomes, como ‘z_motor’ ou ‘liftmotor’, etc.AccelStepper liftmotor = AccelStepper(MotorInterfaceType, motorPin1, motorPin3, motorPin2, motorPin4);Pode criar múltiplos objetos de motor de passo com nomes e pinos diferentes. Isto permite controlar facilmente 2 ou mais motores de passo ao mesmo tempo.
// Initialize with pin sequence IN1-IN3-IN2-IN4 AccelStepper stepper = AccelStepper(MotorInterfaceType, motorPin1, motorPin3, motorPin2, motorPin4);
Na secção setup do código, definimos a velocidade máxima em passos/segundo com a funçãosetMaxSpeed(). Velocidades superiores a 1000 passos por segundo podem ser instáveis, por isso defini este valor como máximo. Note que especifico o nome do motor de passo (‘stepper’) para o qual quero definir a velocidade máxima. Se tiver vários motores ligados, pode definir velocidades diferentes para cada um:stepper2.setMaxSpeed(500);.
void setup() {
// Set the maximum steps per second:
stepper.setMaxSpeed(1000);
}
No loop, primeiro definimos a velocidade a que queremos que o motor rode com a funçãosetSpeed(). (também pode colocar isto na secção setup do código).
stepper.runSpeed()polls o motor e, quando é altura de dar um passo, executa 1 passo. Isto depende da velocidade definida e do tempo desde o último passo. Se quiser mudar a direção do motor, pode definir uma velocidade negativa:stepper.setSpeed(-400);faz o motor rodar no sentido contrário.
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();
}
Em modo meio passo, uma revolução demora 4096 passos, por isso 500 passos/segundo correspondem a cerca de7 rpm.
2. Sketch para controlar número de passos ou revoluções
Com o seguinte sketch pode controlar a velocidade, direção e número de passos/revoluções.
Neste caso, o motor de passo roda 1 revolução no sentido horário a 500 passos/segundo, depois 1 revolução no sentido anti-horário a 1000 passos/segundo, e por fim 2 revoluções no sentido horário a 1000 passos/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);
}
Explicação do código:
A primeira parte do código até à secção loop() é exatamente igual ao exemplo anterior.
No loop uso um ciclo while em combinação com a funçãocurrentPosition(). Primeiro, defino a posição atual do motor de passo para zero comstepper.setCurrentPosition(0).
// Set the current position to 0: stepper.setCurrentPosition(0);
De seguida, usamos o ciclo while. Um ciclo while repete-se continuamente e infinitamente até que a expressão dentro dos parênteses () se torne falsa. Neste caso verifico se a posição atual do motor de passo é diferente de 4096 passos (!= significa: é diferente de). Enquanto isto for verdade, fazemos o motor rodar a uma velocidade constante definida 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();
}
No resto do loop, fazemos exatamente o mesmo, só que com velocidades e posições alvo diferentes.
3. Exemplo de código com aceleração e desaceleração
Com o seguinte sketch pode adicionar aceleração e desaceleração aos movimentos do motor de passo, sem código complicado. A primeira parte deste sketch é igual ao exemplo 1, mas o setup e o loop são diferentes.
O motor fará duas revoluções para frente e para trás a uma velocidade de 1000 passos por segundo e uma aceleração de 200 passos/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);
}
Como o código funciona:
No setup, além da velocidade máxima, também definimos a aceleração/desaceleração com a funçãosetAcceleration().
void setup() {
// Set the maximum steps per second:
stepper.setMaxSpeed(1000);
// Set the maximum acceleration in steps per second^2:
stepper.setAcceleration(200);
}
Na secção loop do código, usei uma forma diferente de fazer o motor rodar um número pré-definido de passos. Primeiro defino a posição alvo com a funçãomoveTo(). Depois, usamos simplesmente a funçãorunToPosition()para fazer o motor rodar até à posição alvo com a velocidade e aceleração definidas. O motor desacelera antes de chegar à posição alvo.
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, definimos a nova posição alvo para 0, para voltar à origem.
Conclusão
Neste artigo mostrei como controlar um motor de passo 28BYJ-48 com um driver ULN2003 e Arduino. Vimos 4 exemplos, usando as bibliotecas Stepper e AccelStepper. Espero que tenha sido útil e informativo.
Se quiser aprender mais sobre como controlar motores de passo maiores, com mais torque e velocidade, veja os artigos abaixo. Nestes artigos ensino como controlar motores NEMA 17 com drivers como o A4988.
Outros tutoriais de motores de 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 tiver alguma dúvida, deixe um comentário abaixo.

