Neste tutorial, aprenderemos tudo o que precisamos saber sobre como controlar motores de passo com Arduino. Vamos abordar como controlar um motor de passo NEMA17 em combinação com os drivers de motor de passo A4988, DRV8825 e TMC2208. Essa combinação de motores de passo e drivers é usada em inúmeras aplicações onde é necessário controle de posição, como Impressoras 3D, Máquinas CNC, Robótica, Máquinas de Automação e assim por diante.
Eu explicarei em detalhes como eles funcionam, como conectar motores de passo ao Arduino, como ajustar o limite de corrente dos drivers e como programá-los com ou sem o uso de uma biblioteca para Arduino. Além disso, mostrarei como podemos controlar facilmente múltiplos motores de passo usando um CNC Shield para Arduino em qualquer tipo de projeto com Arduino.
Portanto, temos bastante coisa para abordar neste tutorial. Você pode assistir ao vídeo a seguir ou ler o tutorial escrito abaixo, que também inclui todos os códigos de exemplo e diagramas de ligação.
O que é um Motor de Passo e Como Ele Funciona?
Vou começar explicando brevemente o que é um motor de passo e como ele funciona, pois isso nos ajudará a entender melhor todo o restante deste tutorial.
Um motor de passo é um tipo único de motor DC sem escovas cuja posição pode ser controlada com precisão mesmo sem nenhum feedback.
O princípio de funcionamento de um motor de passo é baseado em campos magnéticos. Ele possui dois componentes principais: o estator e o rotor. O rotor geralmente é um ímã permanente e é rodeado por algumas bobinas no estator.
Quando energizamos ou deixamos a corrente passar pelas bobinas, campos magnéticos específicos são gerados no estator que atraem ou repelem o rotor. Ao ativar as bobinas, passo a passo, uma após a outra em uma ordem específica, podemos obter um movimento contínuo do rotor, mas também podemos fazê-lo parar em qualquer posição.
É por isso que esses motores são chamados de motores de passo — eles se movem em passos discretos.
Ao aumentar o número de polos magnéticos no rotor, podemos aumentar o número de posições possíveis de parada, aumentando assim a resolução ou a precisão do motor. Por favor, note que esta é apenas uma explicação básica e você pode encontrar mais detalhes no meu tutorial “Como Funcionam os Motores de Passo”.
Um motor de passo típico, como o NEMA17, por exemplo, possui 50 pontos de parada ou passos no rotor. Por outro lado, o estator pode ter várias bobinas organizadas em duas fases, que fornecem quatro diferentes orientações ou posições de campo magnético.
Assim, os 50 passos do rotor multiplicados pelas 4 diferentes orientações de campo magnético resultam em um total de 200 passos para completar uma rotação completa. Ou, se dividirmos 360 graus por 200 passos, temos uma resolução de 1,8 graus por passo.
Mencionei que as bobinas do estator são organizadas em duas fases, e também podemos notar isso ao observar o número de fios de um motor de passo. Ele possui quatro fios, dois para cada fase. As quatro diferentes orientações de campo magnético são possíveis porque podemos fazer a corrente fluir pelas fases em ambas as direções.
Também existem motores de passo com 5, 6 ou até 8 fios, mas eles ainda funcionam com duas fases ou os controlamos usando apenas quatro terminais.
O detalhe é que eles podem oferecer diferentes características de desempenho, como mais torque ou mais velocidade, dependendo de como conectamos esses fios aos quatro terminais de controle.
No entanto, com essa breve explicação, agora entendemos que, para acionar um motor de passo, não podemos simplesmente ligar a energia, pois nada acontecerá. Em vez disso, precisamos energizar as duas fases do motor em ambas as direções e ativá-las ou enviar pulsos para elas em uma ordem específica, seguindo uma sequência temporal. Por isso, precisamos de drivers para controlar motores de passo.
Existem muitos tipos e tamanhos de drivers, correspondentes aos diversos tipos e tamanhos de motores de passo. No entanto, o princípio básico de funcionamento de todos eles é que possuem duas pontes H que permitem energizar as fases do motor em ambas as direções.
Claro, eles possuem muitas outras funções, como micropassos, limitação de corrente e assim por diante, que nos permitem controlar facilmente os motores de passo — o que é exatamente o propósito deles.
Como Controlar Motor de Passo NEMA17 com Arduino e Driver de Passo A4988
Tudo certo, agora podemos dar uma olhada no primeiro exemplo deste tutorial: como controlar um motor de passo NEMA17 com um driver de passo A4988.
O NEMA17 é o motor de passo mais popular entre os makers, pois oferece ótimo desempenho e, ao mesmo tempo, é acessível. Ele também pode ser encontrado em praticamente qualquer impressora 3D de mesa e gravadora a laser.
Geralmente, o motor de passo NEMA17 possui 200 passos, ou uma resolução de 1,8 graus por passo, mas também existem modelos com 400 passos e resolução de 0,9 graus por passo. Devemos observar aqui que a designação NEMA17 descreve, na verdade, apenas o tamanho do motor em relação ao tamanho da placa frontal.
O número representa o tamanho da placa frontal em polegadas quando dividido por 10, ou seja, neste caso, 17 dividido por 10 é igual a 1,7 polegadas de placa frontal, ou 2,3 polegadas de placa frontal no caso do NEMA23.
Portanto, o tamanho da placa frontal é fixo, mas o comprimento dos motores NEMA17 pode variar de 20 mm a 60 mm e, com isso, a exigência de potência do motor também varia. A exigência de potência é geralmente definida pela quantidade de corrente que o motor pode consumir, e a faixa para esses motores de passo NEMA17 varia de 0,3 A até 2,5 A.
Agora, de acordo com a corrente nominal do motor de passo, precisamos escolher um driver adequado que possa suportar essa quantidade de corrente. O driver mais popular para controlar motores de passo NEMA17 é o driver de motor de passo A4988.
O A4988 possui uma corrente máxima nominal de 2 A por bobina, mas isso é, na verdade, um valor de pico. Recomenda-se manter a corrente em torno de 1 A, mas, é claro, também é possível chegar até 2 A se for fornecido um bom resfriamento para o CI.
Uma ótima funcionalidade que o driver de passo A4988 possui — na verdade, todos os outros drivers também têm — é a limitação de corrente. Com isso, podemos definir facilmente quanta corrente o motor vai consumir, independentemente da corrente nominal do motor. Por exemplo, podemos conectar até mesmo um motor de passo com corrente nominal de 2,5 A, mas limitar a corrente do driver para 1,5 A. Assim, embora o motor não opere em sua capacidade máxima, ainda seremos capazes de utilizá-lo.
Por outro lado, se o motor tiver uma corrente nominal inferior ao limite de corrente definido no driver, ele pode superaquecer. É claro que, sempre que possível, é recomendado combinar a corrente nominal do motor com a corrente suportada pelo driver.
Conexão do A4988 com o Arduino
Tudo certo, então agora vamos ver como conectar o driver A4988 com o motor de passo e o controlador Arduino.
No canto superior direito do driver, temos os pinos VMOT e GND, onde conectamos a fonte de alimentação para o motor, que pode variar de 8 a 36 V. Também é recomendado usar um capacitor de desacoplamento entre esses dois pinos para proteger a placa contra picos de tensão. Devemos usar um capacitor eletrolítico de grande capacidade, com pelo menos 47 μF.
Em seguida, temos os quatro pinos onde conectamos o motor de passo. Uma fase do motor vai nos pino.s 1A e 1B, e a outra fase nos pinos 2A e 2B.
Às vezes, pode ser um pouco difícil identificar quais dois fios do motor correspondem a uma fase, mas existem várias formas de identificá-los. A maneira mais simples é girar o eixo do motor de passo com a mão e, em seguida, conectar dois fios entre si. Se você conectar dois fios que formam uma fase, a rotação do eixo ficará um pouco mais difícil.
Outra forma é usar um multímetro e verificar a continuidade entre os dois fios. Se você conectar dois fios que formam uma fase, haverá um curto-circuito entre eles e o multímetro começará a apitar.
Uma vez que identificamos uma fase, podemos conectá-la a qualquer uma das duas posições correspondentes no driver — a ordem não importa.
Em seguida, temos os pinos de alimentação lógica do CI, VDD e GND, que podem variar de 3 V a 5 V. Do outro lado, temos os pinos Step e Direction, que podem ser conectados a qualquer pino da placa Arduino. Com o pino Direction, selecionamos a direção de rotação do motor, e com o pino Step controlamos os passos do motor. A cada pulso enviado ao pino Step, o motor avança um passo na direção selecionada.
Logo acima desses pinos, temos os pinos Sleep e Reset, que servem, como os nomes sugerem, para colocar o driver em modo de espera (sleep) ou reiniciá-lo (reset). Devemos observar que ambos os pinos são ativos em nível baixo (active low). O pino Sleep, por padrão, está em nível alto (HIGH), mas o pino RST fica flutuando. Isso significa que, para manter o driver habilitado, a forma mais simples é apenas conectar esses dois pinos entre si, assumindo que não utilizaremos as funções específicas deles.
O pino Enable também é ativo em nível baixo, então, a menos que o coloquemos em nível alto (HIGH), o driver permanecerá habilitado.
Por exemplo, se selecionarmos a resolução de um quarto de passo (quarter-step), os 200 passos do motor se transformarão em 200 multiplicado por 4, ou seja, 800 micropassos por rotação. O driver usará quatro níveis diferentes de corrente nas bobinas para alcançar isso.
O driver A4988 possui uma resolução máxima de 16 micropassos, o que faria com que um motor NEMA17 de 200 passos tivesse 3200 passos por rotação, ou seja, 0,1125 graus por passo. Isso é uma precisão realmente impressionante, e é por isso que esse tipo de motor de passo e driver é utilizado em tantas aplicações. Na verdade, existem drivers de motor de passo com até 256 micropassos, o que significa incríveis 51.200 passos por rotação, ou 0,007 graus por passo.
De qualquer forma, esses três pinos (MS1, MS2 e MS3) possuem resistores pull-down, portanto, se os deixarmos desconectados, o driver funcionará no modo de passo completo (full-step). Para selecionar uma resolução de micropasso diferente, precisamos conectar 5 V aos pinos apropriados de acordo com esta tabela.
Limitação de Corrente no A4988
Tudo certo, então agora que já sabemos como conectar o motor de passo e o driver à placa Arduino, podemos seguir para a explicação de como programar ou codificar o Arduino para controlar o motor de passo. No entanto, antes de fazermos isso — ou antes mesmo de energizarmos o motor — ainda há uma etapa muito importante que precisamos realizar: ajustar o limite de corrente do driver.
Como já explicamos, precisamos ajustar o limite de corrente do driver para que ele seja inferior à corrente nominal do motor, caso contrário, o motor poderá superaquecer.
Há um pequeno trimpot (potenciômetro) no driver A4988 por meio do qual podemos ajustar o limite de corrente. Girando o potenciômetro no sentido horário, o limite de corrente aumenta, e no sentido anti-horário, ele diminui. Existem dois métodos que podem ser usados para determinar o valor real do limite de corrente.
O primeiro método envolve a medição da tensão de referência (Vref) entre o potenciômetro e o GND. Podemos medir essa tensão com um multímetro e utilizar o valor obtido na seguinte fórmula para calcular o limite de corrente do driver:
Limite de Corrente = Vref / (8 x Rcs)
O Rcs é a resistência de detecção de corrente (current sense), ou seja, o valor dos resistores de detecção de corrente localizados bem ao lado do chip. Dependendo do fabricante, esses valores geralmente são de 0,05, 0,1 ou 0,2 ohms. Portanto, precisamos observar de perto o valor desses resistores para calcular corretamente o limite de corrente usando esse método.
No meu caso, esses resistores estavam marcados como R100, o que significa 0,1 ohm.
Como exemplo, se medirmos uma tensão de referência de 0,7 V e tivermos resistores de 0,1 ohm, o limite de corrente será de aproximadamente 0,875 A. Ou, se quisermos limitar a corrente para, digamos, 1 A, devemos ajustar a tensão de referência para 0,8 V.
O segundo método para ajustar o limite de corrente é medir diretamente a corrente que passa pelas bobinas. Para isso, precisamos conectar o motor de passo e o driver conforme explicado anteriormente. Podemos ignorar a conexão com o controlador e, em vez disso, conectar 5 V aos pinos Direction e Step para que o motor permaneça ativo e parado em uma posição. Os pinos MS1, MS2 e MS3 devem ser deixados desconectados, para que o driver opere no modo de passo completo (full-step).
Em seguida, podemos desconectar um dos fios da bobina do motor e conectá-lo em série com um amperímetro. Dessa forma, ao alimentar o driver tanto com a tensão lógica (5 V) quanto com a alimentação do motor (12 V, no meu caso), poderemos ler diretamente no amperímetro quanta corrente está passando pela bobina.
Contudo, devemos observar aqui que, quando o driver opera no modo de passo completo (full-step), a corrente nas bobinas pode atingir apenas cerca de 70% do limite real de corrente. Portanto, ao usar o driver em outros modos de micropasso (microstepping), a leitura obtida no amperímetro deve ser multiplicada por 1,3 para se obter o valor real do limite de corrente do driver.
Eu testei ambos os métodos para ajustar o limite de corrente do driver, e eles me forneceram resultados aproximadamente iguais.
Motores de Passo e Arduino – Códigos de Exemplo
De qualquer forma, agora podemos seguir com a programação do Arduino ou analisar vários códigos de exemplo para controlar um motor de passo com uma placa Arduino.
Vamos começar com um exemplo de código bem básico de como controlar um motor de passo sem utilizar nenhuma biblioteca.
Código de Exemplo 1
/*
* Exemplo básico de código para controlar um motor de passo sem biblioteca
*
* por Prototipando, https://labprototipando.com.br
*/
// define os pinos
#define stepPin 2
#define dirPin 5
void setup() {
// Define os dois pinos como saídas
pinMode(stepPin,OUTPUT);
pinMode(dirPin,OUTPUT);
}
void loop() {
digitalWrite(dirPin,HIGH); // Ativa o motor para girar em uma direção específica
// Gera 200 pulsos para realizar uma rotação completa
for(int x = 0; x < 800; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(700); // alterando esse tempo entre os passos podemos mudar a velocidade de rotação
digitalWrite(stepPin,LOW);
delayMicroseconds(700);
}
delay(1000); // Pausa de um segundo
digitalWrite(dirPin,LOW); // Altera a direção da rotação
// Gera 400 pulsos para realizar duas rotações completas
for(int x = 0; x < 1600; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(500);
digitalWrite(stepPin,LOW);
delayMicroseconds(500);
}
delay(1000);
}
Descrição do código:
Aqui, tudo o que precisamos fazer é definir a qual número de pino estão conectados os pinos STEP e DIR, e declará-los como saídas. No loop, primeiro definimos a direção de rotação do motor configurando o pino de direção (DIR) como HIGH. Em seguida, usando um loop “for”, enviamos 200 pulsos para o pino STEP, o que fará o motor girar um ciclo completo, considerando que ele esteja operando no modo de passo completo (full-step).
Os pulsos são gerados simplesmente alternando o estado do pino STEP de HIGH para LOW com um pequeno atraso entre eles. Esse tempo de atraso, na verdade, define a velocidade de rotação: se diminuirmos o tempo, a velocidade aumenta, pois os passos acontecem mais rapidamente, e vice-versa.
Depois, alteramos a direção de rotação e, usando outro loop “for”, enviamos 400 pulsos, o que faria o motor girar duas voltas completas.
No entanto, se mudarmos o modo de micropasso (microstepping) do driver — por exemplo, para um quarto de passo — o motor passará a ter 800 passos por rotação. Nesse caso, o primeiro loop fará o motor girar apenas 90 graus, e o segundo loop apenas meia volta.
Código de Exemplo 2
Aqui está outro exemplo simples: controlando a velocidade do motor de passo usando um potenciômetro.
Para isso, basta conectar o potenciômetro ao Arduino e ler seu valor usando a função analogRead().
/*
* Exemplo básico de código para controlar um motor de passo sem biblioteca
*
* por Prototipando, https://labprototipando.com.br
*/
// define os pinos
#define stepPin 2
#define dirPin 5
int customDelay, customDelayMapped;
void setup() {
// Define os dois pinos como saídas
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
}
void loop() {
speedControl();
// Gera pulsos com atraso personalizado, dependendo do potenciômetro, do qual depende a velocidade do motor
digitalWrite(stepPin, HIGH);
delayMicroseconds(customDelayMapped);
digitalWrite(stepPin, LOW);
delayMicroseconds(customDelayMapped);
}
// Função personalizada para ler o potenciômetro e mapear seu valor de 300 a 3000, adequado para o atraso em microssegundos
void speedControl() {
customDelay = analogRead(A0); // Lê o valor do potenciômetro
customDelayMapped = map(customDelay, 0, 1023, 300, 3000); // Converte a entrada analógica de 0 a 1023 para 300 a 3000
}
Descrição do código:
Podemos então mapear ou converter os valores do potenciômetro, que vão de 0 a 1023, para valores adequados para serem usados como tempo de atraso, em microssegundos, entre os pulsos de Step. Eu descobri que o valor mínimo de atraso entre os passos é em torno de 300 microssegundos. Ao diminuir abaixo disso, o motor de passo começou a perder passos.
No geral, controlar motores de passo com esse método é simples e funciona, mas somente se o controle necessário for básico, como mostrado nos exemplos. Caso precisemos de um controle mais complexo, a melhor maneira é utilizar uma biblioteca para Arduino.
Controlando Motores de Passo com Arduino e a Biblioteca AccelStepper – Exemplos
A biblioteca mais popular para controlar motores de passo com Arduino é a AccelStepper, criada por Mike McCauley. É uma biblioteca extremamente versátil, que oferece controle de velocidade, aceleração e desaceleração, definição de posições-alvo, controle simultâneo de múltiplos motores de passo, entre outras funcionalidades.
A biblioteca possui uma excelente documentação que explica como cada função funciona. Eu já utilizei essa biblioteca em vários projetos meus com Arduino, como no controle do movimento do meu Slider de Câmera DIY, da máquina de dobra de fios 3D, do braço robótico SCARA e alguns outros. Caso tenha interesse, há detalhes e explicações dos códigos de cada projeto no site.
Agora, vamos conferir alguns exemplos de código utilizando essa biblioteca.
Código de exemplo – Controle de velocidade do motor de passo usando um potenciômetro
O primeiro exemplo mostrará como controlar a velocidade do motor usando o potenciômetro.
/*
* Exemplo básico de código para controlar um motor de passo com a biblioteca AccelStepper
*
* por Prototipando, https://labprototipando.com.br
*/
#include <AccelStepper.h>
// Define o motor de passo e os pinos aos quais ele está conectado
AccelStepper stepper1(1, 2, 5); // (Tipo de driver: com 2 pinos, STEP, DIR)
void setup() {
// Define o valor máximo de velocidade para o motor de passo
stepper1.setMaxSpeed(1000);
}
void loop() {
stepper1.setSpeed((analogRead(A0));
// Move o motor com a velocidade constante definida anteriormente pelo setSpeed();
stepper1.runSpeed();
}
Descrição do código:
Aqui, primeiro precisamos incluir a biblioteca AccelStepper. Claro, antes disso, precisamos instalar a biblioteca, e isso pode ser feito pelo gerenciador de bibliotecas da IDE Arduino. Basta buscar por “AccelStepper”, a biblioteca aparecerá e poderemos instalá-la.
Depois, precisamos criar uma instância da classe AccelStepper para o nosso motor. O primeiro parâmetro é o tipo de driver; neste caso, para um driver com dois pinos de controle, o valor é 1. Os outros dois parâmetros são os números dos pinos aos quais nosso driver está conectado no Arduino. Se tivermos vários motores de passo, precisamos definir cada um assim, e podemos nomeá-los como quisermos — neste caso, nomeei meu motor como stepper1.
Na seção setup, só precisamos definir a velocidade máxima do motor, que é dada em passos por segundo. Esse valor pode chegar até 4000, mas na documentação da biblioteca está indicado que velocidades acima de 1000 passos por segundo podem não ser confiáveis.
Na seção loop, usamos a função setSpeed() para definir a velocidade atual do motor, que neste caso é a entrada analógica do potenciômetro, variando de 0 a 1023.
Para que o motor se mova e mantenha essa velocidade constante, precisamos chamar a função runSpeed() a cada intervalo. Um valor negativo, ou simplesmente colocar o sinal de menos antes do valor, fará com que o motor de passo gire na direção oposta.
Código de exemplo – Controle de dois motores de passo com aceleração e desaceleração
Aqui está outro exemplo de controle de dois motores de passo, implementando aceleração e desaceleração, usando a biblioteca AccelStepper.
/*
Controlando dois motores de passo com a biblioteca AccelStepper
por Prototipando, https://labprototipando.com.br
*/
#include <AccelStepper.h>
// Define o motor de passo e os pinos aos quais ele está conectado
AccelStepper stepper1(1, 2, 5); // (Tipo de driver: com 2 pinos, STEP, DIR)
AccelStepper stepper2(1, 3, 6);
void setup() {
stepper1.setMaxSpeed(1000); // Define a velocidade máxima para o motor de passo
stepper1.setAcceleration(500); // Define o valor de aceleração para o motor de passo
stepper1.setCurrentPosition(0); // Define a posição atual como 0 passos
stepper2.setMaxSpeed(1000);
stepper2.setAcceleration(500);
stepper2.setCurrentPosition(0);
}
void loop() {
stepper1.moveTo(800); // Define o movimento desejado: 800 passos (na resolução de um quarto de passo, isso equivale a uma rotação)
stepper1.runToPosition(); // Move o motor até a posição alvo com aceleração/desaceleração e bloqueia o código até chegar na posição
stepper2.moveTo(1600);
stepper2.runToPosition();
// Retorna para a posição 0, usando run(), que não bloqueia – ambos os motores irão se mover ao mesmo tempo
stepper1.moveTo(0);
stepper2.moveTo(0);
while (stepper1.currentPosition() != 0 || stepper2.currentPosition() != 0) {
stepper1.run(); // Move o motor implementando aceleração e desaceleração para alcançar a posição alvo. Função não bloqueante
stepper2.run();
//
//
}
}
Descrição do código:
Então, precisamos definir os dois motores de passo, e no setup, usando a função setAcceleration(), configuramos o valor da aceleração para os motores. Com a função setCurrentPosition() definimos que a posição atual dos motores será zero passos.
Na seção loop, começamos com a função moveTo(), pela qual indicamos para o motor a posição para onde ele deve ir ou quantos passos deve mover. No caso de resolução em quarto de passo, 800 passos correspondem a uma rotação completa. Depois, a função runToPosition() move o motor até essa posição, implementando aceleração e desaceleração. Contudo, essa função é bloqueante, ou seja, a execução do código fica parada até que o motor alcance a posição desejada.
Com o mesmo método, movemos o segundo motor 1600 passos, ou duas rotações completas na resolução de quarto de passo.
Se não quisermos que o código fique bloqueado enquanto o motor alcança a posição alvo, em vez de usar runToPosition() devemos usar a função run(). Essa função também implementa aceleração e desaceleração, mas realiza apenas um passo a cada chamada. Por isso, precisamos chamá-la o mais frequentemente possível. Por esse motivo, colocamos as funções run() para os dois motores dentro de um laço while, que será executado até que ambos os motores atinjam a posição zero. Anteriormente, configuramos os dois motores para se moverem até essa posição usando as funções moveTo().
Também poderíamos adicionar mais código dentro desse laço while e realizar outras tarefas enquanto os motores estão em movimento. Na verdade, existem várias maneiras de rodar os motores e executar outras funções simultaneamente. Recomendo estudar a documentação detalhada da biblioteca para entender melhor como cada função funciona e poder implementá-las conforme suas necessidades.
Código de exemplo – Controlando múltiplos motores de passo com a biblioteca AccelStepper
Agora, quero mostrar mais um exemplo usando a biblioteca AccelStepper, que é o controle coordenado de múltiplos motores de passo. Isso significa que podemos definir posições alvo para cada motor e eles chegarão a essas posições ao mesmo tempo, independentemente da distância diferente que cada um precise percorrer.
Isso pode ser feito facilmente usando a classe MultiStepper, que já vem incluída na biblioteca AccelStepper.
/*
Controlando múltiplos motores de passo com as bibliotecas AccelStepper e MultiStepper
por Prototipando, https://labprototipando.com.br
*/
// Define o motor de passo e os pinos aos quais ele está conectado
AccelStepper stepper1(1, 2, 5); // (Tipo de driver: com 2 pinos, STEP, DIR)
AccelStepper stepper2(1, 3, 6);
AccelStepper stepper3(1, 4, 7);
MultiStepper steppersControl; // Cria uma instância do MultiStepper
long gotoposition[3]; // Um array para armazenar as posições alvo para cada motor de passo
void setup() {
stepper1.setMaxSpeed(1000); // Define a velocidade máxima para o motor de passo
stepper2.setMaxSpeed(1000);
stepper3.setMaxSpeed(1000);
// Adicionando os 3 motores à instância steppersControl para controle múltiplo
steppersControl.addStepper(stepper1);
steppersControl.addStepper(stepper2);
steppersControl.addStepper(stepper3);
}
void loop() {
// Armazena as posições alvo no array "gotoposition"
gotoposition[0] = 800; // 800 passos - rotação completa com resolução de quarto de passo
gotoposition[1] = 1600;
gotoposition[2] = 3200;
steppersControl.moveTo(gotoposition); // Calcula a velocidade necessária para todos os motores
steppersControl.runSpeedToPosition(); // Bloqueia até que todos os motores estejam na posição
delay(1000);
gotoposition[0] = 0;
gotoposition[1] = 0;
gotoposition[2] = 0;
steppersControl.moveTo(gotoposition);
steppersControl.runSpeedToPosition();
delay(1000);
}
Descrição do código:
Aqui também precisamos incluir a classe MultiStepper e criar uma instância dela. Depois, definimos um array do tipo long, que será usado para armazenar as posições-alvo dos motores.
Na seção setup, definimos as velocidades máximas dos motores e adicionamos esses motores à instância do MultiStepper, que no meu caso chamei de steppersControl.
No loop, começamos armazenando os valores das posições-alvo no array criado. Configurei o primeiro motor para uma rotação, o segundo para duas rotações e o terceiro para três rotações. Em seguida, passamos esse array para a função moveTo(), que calcula as velocidades necessárias para que todos os motores cheguem às posições ao mesmo tempo. Depois, chamamos a função runSpeedToPosition(), que move os motores para as posições definidas.
Vale lembrar que essa função bloqueia a execução do código até que os motores alcancem suas posições. Caso não queiramos bloquear o código, podemos usar a função run(). Também é importante destacar que a classe MultiStepper não suporta aceleração nem desaceleração.
Se quiser aprender mais com exemplos mais avançados, recomendo conferir meus projetos com Arduino que já mencionei — todos os detalhes e códigos estão disponíveis no site.
CNC Shield para controle de múltiplos motores de passo em qualquer projeto Arduino
Ainda falando sobre controle de múltiplos motores de passo, vale a pena mencionar e conhecer a Arduino CNC Shield.
O principal objetivo da Arduino CNC Shield é controlar máquinas CNC de 2 ou 3 eixos, mas na verdade ela é uma ótima opção para qualquer projeto que precise controlar múltiplos motores de passo, pois é compacta e oferece conexões fáceis para os drivers e motores.
Esse shield é encaixado sobre uma placa Arduino UNO e pode controlar até 4 motores de passo independentes, deixando todos os demais pinos do Arduino disponíveis para uso. Eu utilizei essa combinação do Arduino UNO com a CNC Shield para controlar meu braço robótico SCARA de 4 eixos.
Em breve, atualizarei esta seção do artigo com mais detalhes sobre como usar a CNC Shield com Arduino.
DRV8825 vs A4988
Agora vamos avançar e ver como controlar motores de passo usando o outro driver que mencionei no início, o DRV8825.
Na verdade, tudo que explicamos até agora sobre o controle de motores de passo com o driver A4988 também se aplica ao DRV8825. O princípio de funcionamento, as conexões e a programação são praticamente os mesmos para os dois drivers. A diferença está nas características técnicas, e agora vamos analisá-las e compará-las.
O DRV8825 é um driver de motor de passo da Texas Instruments que pode ser usado como substituto direto do driver A4988 da Allegro, pois suas conexões são as mesmas. As três principais diferenças entre eles são que o DRV8825 pode fornecer mais corrente que o A4988 sem refrigeração adicional (1,5A vs 1A), tem uma tensão máxima de alimentação mais alta (45V vs 35V) e oferece uma resolução de micropassos maior (32 vs 16 micropassos).
Claro, eles também têm algumas outras diferenças menores. Por exemplo, o potenciômetro de ajuste de corrente fica em uma posição diferente, e a relação entre o ajuste de corrente e a tensão no pino de referência é diferente. O DRV8825 não precisa de alimentação lógica, e o local desse pino é usado como saída de FALHA (FAULT).
No entanto, é seguro conectar o pino FAULT diretamente ao 5V, então o DRV8825 pode ser usado como um substituto direto em sistemas projetados para o driver A4988.
Vale lembrar, porém, que ao substituir um driver A4988 por um DRV8825 é muito importante garantir que a orientação do driver esteja correta. Já mencionei que seus potenciômetros estão em locais diferentes — no A4988 ele fica abaixo do chip, e no DRV8825 fica acima do chip —, e isso pode, às vezes, causar confusão, fazendo com que o driver seja facilmente inserido do lado errado.
Para ajustar o limite de corrente, podemos medir a tensão de referência com uma ponta do multímetro no GND e a outra diretamente no potenciômetro.
A fórmula para calcular o limite de corrente do driver de motor de passo DRV8825 é a seguinte:
Limite de Corrente = Vref x 2
Quanto à seleção da resolução de micropassos, podemos usar a tabela a seguir.
No geral, o DRV8825 é um driver de motor de passo melhor que o A4988, pois oferece classificações mais altas de corrente e tensão, além de uma resolução de micropassos superior, o que resulta em um funcionamento mais suave e silencioso do motor de passo.
Driver de Motor de Passo TMC2208
Falando em funcionamento mais suave e silencioso, vamos dar uma olhada no driver de motor de passo TMC2208. O chip TMC2208 é fabricado pela Trinamic, uma empresa alemã especializada em eletrônica de controle de movimento. O TMC2208 é um driver silencioso de motor de passo que também pode ser usado como substituto direto em sistemas projetados para os drivers A4988 ou DRV8825. Ele é amplamente utilizado em impressoras 3D de mesa, gravadores a laser, scanners, entre outros.
O que diferencia esse driver dos outros dois é sua unidade de interpolação integrada, que fornece 256 subdivisões ou micropassos. Isso permite um controle senoidal perfeito, gerado internamente dentro do próprio chip. Isso significa que o driver enviará 256 micropassos para o motor de passo, independentemente da resolução de micropassos que tenhamos selecionado por meio dos dois pinos MS — seja 2, 4, 8 ou 16 micropassos. Isso proporciona um funcionamento mais suave e reduz significativamente a carga de trabalho do microcontrolador.
Esse recurso do driver, em combinação com sua tecnologia de controle de corrente silencioso StealthChop2, proporciona um controle ultra silencioso dos motores de passo. Aqui está uma comparação dos níveis de ruído entre os três drivers.
Níveis de ruído dos drivers de motor de passo: A4988 cerca de 65 dB, DRV8825 cerca de 67 dB e TMC2208 cerca de 41 dB. O TMC2208 aciona os motores de passo de forma completamente silenciosa, o que é realmente impressionante.
A corrente nominal do TMC2208 é ligeiramente maior que a do driver A4988, sendo 1,2 A com pico de 2 A. Para ajustar o limite de corrente do driver, podemos novamente usar o mesmo método explicado para os outros drivers: precisamos medir a tensão de referência com uma ponta do multímetro no GND e a outra no orifício logo ao lado do pino Enable.
A fórmula para calcular o limite de corrente é a seguinte:
Limite de corrente = Vref x 0,71
Embora possa ser usado como substituto direto, o driver TMC2208 possui um pinout ligeiramente diferente em comparação com o driver A4988. Aqui, temos apenas dois pinos para seleção da resolução de micropassos e, para habilitar o driver, precisamos conectar o pino Enable ao GND.
Em termos de programação, é igual aos outros dois drivers.
O driver TMC2208 também possui alguns outros recursos mais avançados em comparação com os dois outros drivers, como, por exemplo, uma interface UART de fácil utilização, que permite controlar o driver com apenas uma linha, em vez dos dois pinos Step e Dir. Além disso, ele oferece mais opções de ajuste e controle.
No geral, o TMC2208 é um driver melhor que o A4988 e o DRV8825, mas isso é normal, já que ele vem com um preço mais elevado. No entanto, se você não precisa desses recursos extras e níveis de ruído não forem um problema, os outros dois drivers ainda são excelentes escolhas.
Conclusão
Portanto, cobrimos praticamente tudo o que precisamos saber sobre o controle de motores de passo com Arduino. O NEMA17 e os três drivers — A4988, DRV8825 e TMC2208 — são extremamente versáteis e podem ser usados em uma enorme variedade de aplicações onde o controle de posição é necessário. Você sempre pode aprender mais explorando alguns dos meus projetos com Arduino.
Se você tiver interesse em aprender como controlar motores de passo maiores, como NEMA23 ou NEMA34, em breve terei um tutorial dedicado a isso também.
Espero que você tenha gostado deste tutorial e aprendido algo novo. Não se esqueça de se inscrever e fique à vontade para deixar qualquer dúvida na seção de comentários abaixo.