ESP32 - Motor de Passo

Neste tutorial, vamos aprender como usar o ESP32 para controlar o motor de passo:

O tutorial vale para qualquer tipo de motor de passo bipolar (4 fios). O tutorial usa o motor de passo NEMA 17 como exemplo.

ESP32 Motor de passo

Sobre o Motor de Passo

Existem dois tipos comuns de motores de passo:

  • Bipolar: Estes motores vêm com 4 fios.
  • Unipolar: Motores unipolares podem ter 5 ou 6 fios. No caso de um motor de passo unipolar de 6 fios, você pode usar na prática quatro dos seis fios para controlá-lo como se fosse um motor de passo bipolar.

Se você está interessado especificamente em um motor de passo unipolar de 5 fios, pode consultar o tutorial ESP32 - Controlar o Motor de Passo 28BYJ-48 Usando o Driver ULN2003.

No entanto, este tutorial é dedicado exclusivamente a motores de passo bipolares.

Pinagem do Motor de Passo Bipolar

Um motor de passo bipolar tem quatro pinos, e esses pinos podem ter nomes diferentes dependendo do fabricante. Abaixo, você encontra uma tabela com alguns nomes comuns de pinos:

Nº DO PINO Nome 1 Nome 2 Nome 3
1 A+ A A
2 A- A C
3 B+ B B
4 B- B D
Pinagem do Motor de Passo Bipolar

A disposição dos pinos, os nomes dos fios e as cores dos fios podem variar de um fabricante para outro. Para entender como as cores dos fios correspondem aos nomes dos pinos, é essencial consultar o datasheet ou o manual do usuário fornecido pelo fabricante. A imagem acima mostra as especificações de dois motores distintos, cada um com suas próprias convenções de nomes e cores de fios.

Passos por Revolução

A especificação do motor informa o grau por passo (vamos chamar de DEG_PER_STEP). Dependendo do método de controle, os passos por revolução (vamos chamar de STEP_PER_REVOLUTION) são calculados como na tabela a seguir:

Método de controle Passos por Revolução Grau real por passo
Passo completo STEP_PER_REVOLUTION = 360 / DEG_PER_STEP DEG_PER_STEP
Meio passo STEP_PER_REVOLUTION = (360 / DEG_PER_STEP) * 2 DEG_PER_STEP / 2
Micropasso (1/n) STEP_PER_REVOLUTION = (360 / DEG_PER_STEP) * n DEG_PER_STEP / n

Por exemplo, se o datasheet do motor especifica 1,8 grau/passo:

Método de controle Passos por Revolução Grau real por passo
Passo completo 200 passos/revolução 1,8°
Meio passo 400 passos/revolução 0,9°
Micropasso (1/n) (200 * n) passos/revolução (1,8 / n)°

Como controlar um motor de passo usando o ESP32

O ESP32 consegue gerar sinais para comandar o motor de passo, mas esses sinais podem não ter os níveis de tensão e corrente que o motor de passo exige. Por isso, é preciso um driver de hardware intermediário para fazer a ponte entre o ESP32 e o motor de passo. Esse driver tem duas funções principais:

  • Amplificar os Sinais de Controle: Ele aumenta a corrente e a tensão dos sinais de controle vindos do ESP32, garantindo que atendam aos requisitos do motor de passo.
  • Proteger o ESP32: Ao mesmo tempo, ele protege o ESP32 dos níveis mais altos de corrente e tensão usados para alimentar o motor de passo, evitando qualquer possível dano.

Existem vários drivers de hardware para controlar motores de passo, e uma opção muito usada é o Driver L298N.

Sobre o Driver L298N

Um único Driver L298N pode ser usado para controlar dois motores DC ou um motor de passo. Neste tutorial, aprendemos como usá-lo para controlar o motor de passo.

Pinagem do Driver L298N

Pinagem do Driver L298N

O Driver L298N tem 11 pinos e três jumpers:

  • Pino VCC: fornece energia para o motor. Pode ser qualquer valor entre 5 e 35V.
  • Pino GND: é um pino de terra comum, deve ser conectado ao GND (0V).
  • Pino 5V: fornece energia para o módulo L298N. Pode ser alimentado com 5V do ESP32.
  • Pinos IN1, IN2, IN3, IN4: são conectados aos pinos do ESP32 para receber o sinal de controle do motor de passo.
  • Pinos OUT1, OUT2, OUT3, OUT4: são conectados ao motor de passo.
  • Jumpers ENA, ENB: são usados para habilitar o motor de passo. Você precisa manter os dois jumpers ENA e ENB no lugar.
  • Jumper 5V-EN: se mantivermos o jumper 5V-EN no lugar, a energia do módulo L298N vem do VCC, e não precisamos conectar nada ao pino 5V. Se removermos o jumper 5V-EN, precisamos alimentar o módulo L298N pelo pino 5V

Como descrito acima, o driver L298N tem duas alimentações de entrada:

  • Uma para o motor de passo (pinos VCC e GND): de 5 a 35V.
  • Uma para o funcionamento interno do módulo L298N (pinos 5V e GND): de 5 a 7V. Se o jumper 5V-EN for mantido no lugar, não precisamos conectar este pino a nada.

Diagrama de Ligação

Diagrama de Ligação do Motor de Passo ESP32 com Driver L298N

This image is created using Fritzing. Click to enlarge image

Se você não sabe como alimentar o ESP32 e outros componentes, veja as instruções no tutorial a seguir: Como alimentar o ESP32.

※ Nota:

  • Mantenha os três jumpers do módulo L298N no lugar (caso a alimentação do motor seja ≤ 12V)
  • A ordem dos pinos nos motores de passo pode variar entre fabricantes. Confira a tabela abaixo para a ligação correta.

Tabela de ligação entre o ESP32 e o Driver L298N

Pinos do ESP32 Pinos do L298N
7 IN1
6 IN2
5 IN3
4 IN4

Tabela de ligação entre o Driver L298N e o Motor de Passo

Importante!: Não se preocupe com a ordem dos fios do motor de passo na imagem do diagrama de ligação acima. Ela é apenas um exemplo. A ordem dos pinos nos motores de passo pode variar entre fabricantes. Garanta que a sua ligação siga a tabela abaixo.

Pinos do L298N Pinos do motor de passo Ou Ou
OUT1 A+ A A
OUT2 A- A C
OUT3 B+ B B
OUT4 B- B D

Antes de comprar um motor de passo, recomendamos que você confira o datasheet, a especificação ou o manual do motor de passo. Garanta que eles forneçam o mapeamento entre a cor e o nome do pino. Por exemplo, este motor de passo fornece o mapeamento como na imagem abaixo:

Mapeamento de cores das bobinas do Motor de Passo

Com base nesse mapeamento, a tabela de ligação fica assim:

Pinos do L298N pinos do motor de passo cor do fio
OUT1 A fio preto
OUT2 C fio verde
OUT3 B fio vermelho
OUT4 D fio azul

※ Nota:

Em todas as tabelas de ligação acima entre o motor de passo e o Driver L298N, podemos trocar OUT1 com OUT2, e OUT3 com OUT4. Portanto, há mais maneiras de fazer a ligação. No entanto, se trocarmos, o sentido de rotação do motor pode mudar (de horário para anti-horário, e vice-versa).

Como controlar um Motor de passo usando um driver L298N.

Controlar um motor de passo não é uma tarefa simples, principalmente quando queremos controlá-lo de forma não bloqueante. Felizmente, graças à biblioteca AccelStepper, controlar o motor de passo fica muito fácil.

O Arduino IDE também tem uma biblioteca Stepper integrada. No entanto, não recomendamos que você use essa biblioteca porque:

  • A biblioteca fornece funções bloqueantes. Isso significa que ela impede o ESP32 de fazer outras tarefas enquanto controla o motor de passo.
  • Ela não tem funções suficientes.

Em vez disso, recomendamos que você use a biblioteca AccelStepper. Esta biblioteca suporta:

  • Aceleração
  • Desaceleração.
  • Acionamento em passo completo e meio passo.
  • Vários motores de passo simultâneos, com passos independentes e concorrentes em cada motor.
  • Desvantagem: NÃO suporta acionamento em micropasso

Como Controlar a Posição do Motor de Passo via Driver L298N

Podemos mover o motor de passo para a posição desejada usando:

stepper.moveTo(desiredPosition); // move motor one revolution

※ Nota:

A função stepper.moveTo() é não bloqueante. Esse é um ótimo ponto da biblioteca. No entanto, temos de prestar atenção ao usar esta função:

  • Chame 'stepper.run()' o mais frequentemente possível. Ela deve ser chamada na função void loop().
  • NÃO use a função delay() enquanto o motor estiver se movendo.
  • NÃO se deve usar as funções Serial.print() e Serial.println() enquanto o motor estiver se movendo. Essas funções fazem o motor de passo se mover mais devagar.

Como Controlar a Velocidade do Motor de Passo via Driver L298N

Podemos controlar não só a velocidade, mas também a aceleração e a desaceleração, usando algumas funções simples.

stepper.setAcceleration(50.0); // set acceleration/deceleration stepper.setSpeed(200); // set desired speed

Como Controlar a Direção do Motor de Passo via Driver L298N

Se você fizer a ligação como acima, o motor vai girar no:

  • Sentido horário: se controlarmos o motor de uma posição para uma posição maior (incremento de posição)
  • Sentido anti-horário: se controlarmos o motor de uma posição para uma posição menor (decremento de posição)

Por exemplo:

  • Se a posição atual é 100 e controlamos o motor para 200, o motor gira no sentido horário
  • Se a posição atual é -200 e controlamos o motor para -100, o motor gira no sentido horário
  • Se a posição atual é 200 e controlamos o motor para 100, o motor gira no sentido anti-horário
  • Se a posição atual é -100 e controlamos o motor para -200, o motor gira no sentido anti-horário

※ Nota:

Como mencionado antes, se você trocar OUT1 com OUT2, ou OUT3 com OUT4, o incremento da posição pode ser anti-horário e o decremento da posição pode ser horário.

Como Parar o Motor de Passo

  • O motor de passo para automaticamente depois de chegar à posição desejada.
  • O motor de passo pode ser forçado a parar imediatamente a qualquer momento usando a função stepper.stop().

Código ESP32 - Código do Motor de Passo

O código abaixo faz o seguinte:

  • Gira o motor uma revolução no sentido horário
  • Para o motor por 5 segundos
  • Gira o motor de volta uma revolução no sentido anti-horário
  • Para o motor por 5 segundos
  • Esse processo se repete indefinidamente
/* * Este código de ESP32 foi desenvolvido por pt.newbiely.com * Este código de ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/esp32/esp32-stepper-motor */ #include <AccelStepper.h> #define DEG_PER_STEP 1.8 #define STEP_PER_REVOLUTION (360 / DEG_PER_STEP) AccelStepper stepper(AccelStepper::FULL4WIRE, 19, 18, 17, 16); // ESP32 pin: GPIO19, GPIO18, GPIO17, GPIO16 long moveToPosition = STEP_PER_REVOLUTION; void setup() { Serial.begin(9600); stepper.setAcceleration(200.0); // set acceleration stepper.setSpeed(200); // set initial speed stepper.setCurrentPosition(0); // set position to 0 stepper.moveTo(STEP_PER_REVOLUTION); // move motor one revolution, in clockwise direction Serial.println("Motor moving in clockwise direction"); } void loop() { if (stepper.distanceToGo() == 0) { Serial.println("Motor is stopped"); delay(5000); // stop 5 seconds stepper.setCurrentPosition(0); // reset position to 0 moveToPosition = -1 * moveToPosition; // reverse direction stepper.moveTo(moveToPosition); // move motor one revolution if (stepper.distanceToGo() > 0) Serial.println("Motor moving in clockwise direction"); else if (stepper.distanceToGo() < 0) Serial.println("Motor moving in anticlockwise direction"); } // Serial.print(F("position: ")); // Serial.println(stepper.currentPosition()); stepper.run(); // MUST be called as frequently as possible }

Passos Rápidos

  • Se esta é a primeira vez que você usa o ESP32, veja como configurar o ambiente do ESP32 no Arduino IDE.
  • Faça a ligação como na imagem acima.
  • Conecte a placa ESP32 ao seu PC por um cabo micro USB
  • Abra o Arduino IDE no seu PC.
  • Selecione a placa ESP32 correta (por exemplo, ESP32 Dev Module) e a porta COM.
  • Clique no ícone Libraries na barra à esquerda do Arduino IDE.
  • Pesquise “AccelStepper” e encontre a biblioteca AccelStepper de Mike McCauley
  • Clique no botão Install para instalar a biblioteca AccelStepper.
Biblioteca AccelStepper para ESP32
  • Copie o código acima e abra no Arduino IDE
  • Clique no botão Upload no Arduino IDE para carregar o código no ESP32
  • Você vai ver:
    • O motor de passo gira uma revolução no sentido horário
    • O motor de passo para por 5 segundos
    • O motor de passo gira de volta uma revolução no sentido anti-horário
    • O motor de passo para por 5 segundos
    • O processo acima é executado repetidamente.
  • Veja o resultado no Serial Monitor
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32 Dev Module' on 'COM15')
New Line
9600 baud
Motor moving in clockwise direction Motor is stopped Motor moving in anticlockwise direction Motor is stopped Motor moving in clockwise direction Motor is stopped Motor moving in anticlockwise direction Motor is stopped Motor moving in clockwise direction Motor is stopped Motor moving in anticlockwise direction Motor is stopped
Ln 11, Col 1
ESP32 Dev Module on COM15
2

Explicação do Código

Leia a explicação linha por linha nas linhas de comentário do código-fonte!

Vídeo

O vídeo de demonstração abaixo usa o código a seguir:

O código abaixo faz o motor de passo tocar o tema do Super Mario, mudando sua velocidade a cada nota:

/* * Este código de ESP32 foi desenvolvido por pt.newbiely.com * Este código de ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/esp32/esp32-stepper-motor */ #include <AccelStepper.h> // L298N Motor Driver Pins #define IN1_PIN 19 #define IN2_PIN 18 #define IN3_PIN 17 #define IN4_PIN 16 AccelStepper stepper( AccelStepper::FULL4WIRE, IN1_PIN, IN2_PIN, IN3_PIN, IN4_PIN ); struct Note { int speed; // Steps per second int duration; // Duration in milliseconds }; const Note melody[] = { // Intro {330, 150}, {330, 150}, {0, 150}, {330, 150}, {0, 150}, {262, 150}, {330, 150}, {392, 300}, {0, 300}, // Next part {196, 300}, {0, 300}, {262, 200}, {0, 150}, {196, 200}, {0, 150}, {165, 200}, {0, 150}, {220, 200}, {247, 200}, {233, 150}, {220, 200}, // Main melody {196, 150}, {330, 150}, {392, 150}, {440, 200}, {349, 150}, {392, 150}, {330, 200}, {262, 150}, {294, 150}, {247, 300}, {0, 250}, // Fast repeat {262, 150}, {196, 150}, {165, 150}, {220, 150}, {247, 150}, {233, 150}, {220, 200}, {0, 100}, // Ending {196, 150}, {330, 150}, {392, 150}, {440, 200}, {349, 150}, {392, 150}, {330, 200}, {262, 150}, {294, 150}, {247, 400} }; const int melodyLength = sizeof(melody) / sizeof(melody[0]); void playNote(int speed, int duration) { if (speed == 0) { delay(duration); return; } stepper.setSpeed(speed); unsigned long startTime = millis(); while (millis() - startTime < (unsigned long)duration) { stepper.runSpeed(); } } void setup() { Serial.begin(115200); stepper.setMaxSpeed(500); stepper.setSpeed(200); Serial.println("NEMA 17 - Mario Theme"); Serial.println("Playing melody..."); } void loop() { for (int i = 0; i < melodyLength; i++) { Serial.print("Speed: "); Serial.print(melody[i].speed); Serial.print(" steps/s, Duration: "); Serial.println(melody[i].duration); playNote(melody[i].speed, melody[i].duration); } delay(2000); }

O código abaixo faz o motor de passo tocar Ode à Alegria:

/* * Este código de ESP32 foi desenvolvido por pt.newbiely.com * Este código de ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/esp32/esp32-stepper-motor */ #include <AccelStepper.h> // L298N Motor Driver Pins #define IN1_PIN 19 #define IN2_PIN 18 #define IN3_PIN 17 #define IN4_PIN 16 AccelStepper stepper( AccelStepper::FULL4WIRE, IN1_PIN, IN2_PIN, IN3_PIN, IN4_PIN ); struct Note { int speed; // Steps per second int duration; // Duration in milliseconds }; const Note melody[] = { // Part 1 {330, 300}, {330, 300}, {349, 300}, {392, 300}, {392, 300}, {349, 300}, {330, 300}, {294, 300}, {262, 300}, {262, 300}, {294, 300}, {330, 300}, {330, 450}, {294, 150}, {294, 600}, {0, 200}, // Part 2 {330, 300}, {330, 300}, {349, 300}, {392, 300}, {392, 300}, {349, 300}, {330, 300}, {294, 300}, {262, 300}, {262, 300}, {294, 300}, {330, 300}, {294, 450}, {262, 150}, {262, 600}, {0, 250}, // Part 3 {294, 300}, {294, 300}, {330, 300}, {262, 300}, {294, 300}, {330, 150}, {349, 150}, {330, 300}, {262, 300}, {294, 300}, {330, 150}, {349, 150}, {330, 300}, {294, 300}, {262, 300}, {294, 600}, {0, 200}, // Ending {330, 300}, {330, 300}, {349, 300}, {392, 300}, {392, 300}, {349, 300}, {330, 300}, {294, 300}, {262, 300}, {262, 300}, {294, 300}, {330, 300}, {262, 450}, {0, 150}, {262, 700} }; const int melodyLength = sizeof(melody) / sizeof(melody[0]); void playNote(int speed, int duration) { if (speed == 0) { delay(duration); return; } stepper.setSpeed(speed); unsigned long startTime = millis(); while (millis() - startTime < (unsigned long)duration) { stepper.runSpeed(); } } void setup() { Serial.begin(115200); stepper.setMaxSpeed(500); stepper.setSpeed(200); Serial.println("NEMA 17 - Ode to Joy"); Serial.println("Playing melody..."); } void loop() { for (int i = 0; i < melodyLength; i++) { Serial.print("Speed: "); Serial.print(melody[i].speed); Serial.print(" steps/s, Duration: "); Serial.println(melody[i].duration); playNote(melody[i].speed, melody[i].duration); } delay(2000); }

O código abaixo faz o motor de passo tocar Twinkle Twinkle Little Star:

/* * Este código de ESP32 foi desenvolvido por pt.newbiely.com * Este código de ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/esp32/esp32-stepper-motor */ #include <AccelStepper.h> // L298N Motor Driver Pins #define IN1_PIN 19 #define IN2_PIN 18 #define IN3_PIN 17 #define IN4_PIN 16 AccelStepper stepper( AccelStepper::FULL4WIRE, IN1_PIN, IN2_PIN, IN3_PIN, IN4_PIN ); struct Note { int speed; // Steps per second int duration; // Duration in milliseconds }; const Note melody[] = { // Twinkle, twinkle, little star {262, 350}, {262, 350}, {392, 350}, {392, 350}, {440, 350}, {440, 350}, {392, 650}, {0, 180}, // How I wonder what you are {349, 350}, {349, 350}, {330, 350}, {330, 350}, {294, 350}, {294, 350}, {262, 650}, {0, 250}, // Up above the world so high {392, 350}, {392, 350}, {349, 350}, {349, 350}, {330, 350}, {330, 350}, {294, 650}, {0, 250}, // Like a diamond in the sky {392, 350}, {392, 350}, {349, 350}, {349, 350}, {330, 350}, {330, 350}, {294, 650}, {0, 250}, // Twinkle, twinkle, little star {262, 350}, {262, 350}, {392, 350}, {392, 350}, {440, 350}, {440, 350}, {392, 650}, {0, 180}, // How I wonder what you are {349, 350}, {349, 350}, {330, 350}, {330, 350}, {294, 350}, {294, 350}, {262, 900}, {0, 300} }; const int melodyLength = sizeof(melody) / sizeof(melody[0]); void playNote(int speed, int duration) { if (speed == 0) { delay(duration); return; } stepper.setSpeed(speed); unsigned long startTime = millis(); while (millis() - startTime < (unsigned long)duration) { stepper.runSpeed(); } } void setup() { Serial.begin(115200); stepper.setMaxSpeed(500); stepper.setSpeed(200); Serial.println("NEMA 17 - Twinkle Twinkle Little Star"); Serial.println("Playing melody..."); } void loop() { for (int i = 0; i < melodyLength; i++) { Serial.print("Speed: "); Serial.print(melody[i].speed); Serial.print(" steps/s, Duration: "); Serial.println(melody[i].duration); playNote(melody[i].speed, melody[i].duration); } delay(2000); }

※ NOSSAS MENSAGENS

  • Fique à vontade para compartilhar o link deste tutorial. Porém, por favor, não use nosso conteúdo em outros sites. Investimos muito esforço e tempo para criar este conteúdo, por favor respeite nosso trabalho!