Uso da biblioteca AccelStepper para controlar motores de passo com o Arduino

Uso da biblioteca AccelStepper para controlar motores de passo com o Arduino

O Arduino vem com uma biblioteca, Stepper.h, que facilita o controle de motores de passo. Ela é bem simples de usar, conforme pode-se ver no exemplo abaixo:

#include <Stepper.h>

// seta o número de passos por volta do motor que estiver sendo usado

#define STEPS 100

// cria uma instância do Stepper definindo os pinos do Arduino aos quais serão conectados ao circuito do motor.

Stepper stepper(STEPS, 8, 9, 10, 11);

void setup()

{

// seta a velocidade do motor para 30 RPM

    stepper.setSpeed(30);

}

void loop()

{

    stepper.step(100);

    delay(100);

    stepper.step(-100);

    delay(100);

}

Esse programa fará o motor girar cem passos em uma direção e em seguida cem passos na direção contrária.

Também é possível variar a velocidade de giro do motor, sendo possível gerenciar o giro de mais de um motor.

Ocorre que a a Stepper tem algumas limitações: suporta um número limitado de tipos de drivers e motores, além de não suportar velocidades muito baixas nem muito altas. E a principal delas: a função step() bloqueia o Arduino, isso é, a cada chamada da função o Arduino "congela". Isso faz com que misturar código de controle do motor com outras funcionalidades (incluindo o controle de outros motores simultaneamente) fique bem complicado. Para rodar um motor de um carrinho-robô ainda vai, mas se vc quiser manter um movimento preciso em termos de velocidade e posicionamento, aí que complica de vez.

No meu caso, estou trabalhando em um projeto de um CNC tipo robô cartesiano (no meu blog tem posts a respeito do projeto), então eu preciso acionar dois motores simultaneamente com controle absoluto de velocidade e posicionamento. Além disso o troço vai ter um display LCD, duas chaves de fim de curso, um leitor de código de barras e dois acionadores pneumáticos, para manipular as peças. Também vai ter uma correia transportadora. Ou seja um monte coisa funcionando ao mesmo tempo, o que tornaria virtualmente impossível controlar os motores com a lib Stepper.

Pesquisa dali e daqui, achei a lib AccelStepper. Ela é muito mais "parruda" que a Stepper, resolvendo todas as questões que citei na Stepper e mais algumas tais como:

- Suporte muito simples para aceleração e desaceleração

- Controle de mais de um stepper muito simplificado, fazendo com que manter controle de velocidade, posicionamento e aceleração seja muuuuito mais fácil.

- Suporte a motores de 2, 3 e quatro fios (na realidade até de unipolares de 6 fios, que são os que eu estou usando), através de um driver.

- Suporte a alguns drivers "proprietários", ou seja, com bibliotecas específicas desenvolvidas pelo fabricante mas não tão boas.

- etc (lá no site tem outras)

A documentação é prá lá de boa no site (em inglês), embora seja bem "técnica" para um iniciante, e os caras disponibilizam alguns exemplos com as várias funcionalidades.

Apanhei um pouquinho para aprender como usá-la, até porque estava usando com um driver nacional, o SMC-U-PRO, que é muito bom hardware mas na parte de documentação deixa um pouco a desejar (tem um monte de versão do hardware já vendida, e um monte de documentação na net, foi difícil achar o pdfde uma versão ao menos parecida com a nossa, além de não se achar exemplo de uso do bicho com o Arduino). Mas vale o preço, é uma excelente opção principalmente para motores mais parrudos, quando se quer velocidades altas e/ou passos muito pequenos.

Bom, vamos a um exemplo de código, devidamente comentado:

#include <AccelStepper.h>

// Define os motores.
// AccelStepper::DRIVER - seta o tipo de controladora, no caso um driver, SMC-U-PRO
AccelStepper stepperX(AccelStepper::DRIVER,6,7);
AccelStepper stepperY(AccelStepper::DRIVER,9,10);

void setup()
{
// habilita os pinos de enable dos motores
   stepperX.setEnablePin(8);
   stepperY.setEnablePin(11);

// seta a a velocidade máxima dos motores
   stepperX.setMaxSpeed(2000);
   stepperY.setMaxSpeed(2000);
}

void loop()
{
// prepara os motores para girar em uma direção...
// "manda" girar o motor -2000 steps. O valor legativo significa giro no sentido contrário
// aos ponteiros do relógio.
// Obs: o comando não gira o motor, só diz que é para girar. O giro efetivo é no loop abaixo
    stepperX.moveTo(-2000);

// seta a velocidade de giro em passos/s.
    stepperX.setSpeed(1000);
    stepperY.moveTo(-2000);
    stepperY.setSpeed(1000);

// esse é o loop que move os motores até a posição 2000. Observe que a rotina não
// fica bloqueada no stepperX.runSpeed, ou seja, ele dá um passo e sai.
//Aí vc pode fazer outras coisas, como por exemplo acionar o giro de outros motores,
// como eu fiz.
// Mas o que quer que vc coloque dentro do while tem que ser rápido, porque
// senão vai atrasar o giro dos motores. Você pode colocar, por exemplo, um botão de
// parada imediata, a ser testado dentro do loop, ou um sensor de fim de curso.
while ((stepperX.currentPosition() != -2000) && (stepperY.currentPosition() != -2000))
{
stepperX.runSpeed();
stepperY.runSpeed();
}

// o código abaixo é análogo, só que gira na direção contrária, agora.

    stepperX.moveTo(2000);
    stepperX.setSpeed(1000);
    stepperY.moveTo(2000);
    stepperY.setSpeed(1000);
// move os motores até a posição -2000
while ((stepperX.currentPosition() != 2000) && (stepperY.currentPosition() != 2000))
{
    stepperX.runSpeed();
    stepperY.runSpeed();
}
}

Parece grande mais é mais comentário do que programa. O que importa é que vc pode colocar "quase qualquer" código dentro dos loops while, ou colocar outras funcionalidades dentro do comando loop que não vai afetar o giro do motor. Porque "quase qualquer"? Porque se vc colocar alguma rotina que demore muito (e o "muito" depende da velocidade de giro que vc quer do motor) ou que trave a execução (um delay(), por exemplo) aí ferrou, pq o programa tem que "passar" periodicamente pela rotina runSpeed() ou outra equivalente.

Daí, vc pergunta: Uai, como faço prá não usar delay(), se precisar de esperar durante um intervalo de tempo?

Resposta: crie o seu próprio delay(), e use ele em vez do da lib do Arduino, assim:

void myDelay(long interval)

{

    long init = millis();

    while ((millis() - init) <= interval)

    {

        stepper.runSpeed();

    }

}

Essa myDelay() pode ser usada no seu programa sem comprometer o comando dos motores.

É isso! A AccellStepper tem outras funcionalidades, mas com essas que descrevi já dá para vc ver como controlar mais de um motor ao mesmo tempo com precisão.

Abaixo, um vídeo de um teste que fiz com ela, onde os motores aceleram e desaceleram simultaneamente:

Exibições: 27304

Comentar

Você precisa ser um membro de Laboratorio de Garagem (arduino, eletrônica, robotica, hacking) para adicionar comentários!

Entrar em Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)

Comentário de Eduardo castellani em 10 outubro 2016 às 9:38

Eu estou me lascando para unir dois códigos, eu quero controlar um numero de voltas especifico, tenho um encoder rotativo, e vários motores DC e tenho de passo também, mas como tenho poucos conhecimentos em programação, esta difiicil. Alguem pode ajudar?  quero dar 700 voltas e para, para enrolar uma bobina.

Comentário de Alexandre Marins Cunha de Olivei em 25 julho 2015 às 22:03

Boa noite, sei que este forum é antigo mais alguem pode me ajudar, quero que o motor faça uma volta para um lado e outra para o outro lado e pare, so volte a funcionar se ou apertar um botao ou por outro estimulo, o problema esta que no loop ele fica direto.

Comentário de J.A Assunção em 26 agosto 2014 às 16:35

amigo, 

void setup()

{

// seta a velocidade do motor para 30 RPM

    stepper.setSpeed(30);

}

void loop()

{

    stepper.step(100);

    delay(100);

    stepper.step(-100);

    delay(100);

}

nesse caso vc setou a velocidade fixa e mandou o motor dar apenas 100 passos,

no meu caso, meu setSpeed é variavel de acordo com um map do potenciometro,

e eu quero fazer o motor rodar infinitamente com essa velocidade,

como faço o codigo, para rodar infinitos passos e não apenas 100 ?

obrigado pela atenção

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço