Arduino Uno com fuso e motor de passo


Hoje vamos falar de um assunto muito importante dentro da mecânica e da mecatrônica: os elementos de máquinas. Neste artigo, especificamente, vamos tratar dos fusos, apresentando algumas características interessantes e aplicações. Ainda, vamos demonstrar algumas formas de calcular o movimento provocado por um fuso e apresentar uma montagem de teste.
Fiz a montagem abaixo que expõe o avanço de um fuso de 2mm e outro de 8mm. Esse fusos TR8 que estou utilizando são comumente utilizados em pequenos Routers e impressoras 3D. Lembrando que, dominando alguns conceitos que vamos trabalhar aqui, você será capaz de projetar vários tipos de máquinas.

Recursos utilizados

- Fuso trapezoidal de 8mm de diâmetro e 2mm de passo
- Fuso trapezoidal de 8mm de diâmetro e 8mm de passo
- Castanha flangeada para fuso 8x2
- Castanha flangeada para fuso 8x8
- Mancais para fusos de 8mm de diâmetro
- Guia linear cilíndrica 10mm de diâmetro
- Rolamentos cilíndricos  para guias 10mm
- Suportes para guias cilíndricas de 10mm
- Motores NEMA 17
- Acopladores de eixo
- Arduino Uno
- Driver DRV8825
- Teclado matricial 4x4
- Display Nokia 5110
- Peças plásticas diversas
- Parafusos e porcas
- Base de madeira
- Fonte externa de alimentação 12V


Sobre fusos – O que são?

Os fusos são elementos de máquinas, como os parafusos. Ou seja, são barras retas formadas por roscas de passos contínuos. São utilizados em mecanismos que exigem movimento linear e posicionamento. Podem exercer altas forças de tração e compressão e transmitem torque.
Permitem movimentação com travamento automático. Podem ser construídos de diversos materiais, sendo os mais comuns alumínio e aço.
Como empresas chinesas estão fabricando os fusos trapezoidais, eu indico que você adquira este tipo de produto ao invés do conhecido parafuso de porca. Isso em função do preço mais atrativo e do arrasto, que considero medonho.
Na foto coloco o melhor fuso que existe, na minha opinião, que é o fuso de esfera recirculante. Ele geralmente é feito de um aço bem duro, sendo que as esferas giram em seu entorno, isso dentro da castanha. Além da precisão que ótima, também destaco a durabilidade, já que esse tipo de fuso consegue reproduzir bilhões de movimentos sem estragar o mecanismo. Uma opção mais barata, que é a que usamos aqui, é o fuso trapezoidal.

Sobre fusos – Roscas simples e de esferas

Os fusos de esferas, na foto à esquerda, possuem canais semicirculares onde as esferas rolam. São relativamente mais caros e possuem baixa fricção se comparados ao fusos de rosca simples, levando a um rendimento muito superior (atrito de rolamento).
Já os fusos de roscas simples, no lado direito da imagem,  possuem normalmente perfis trapezoidais, por ser esta geometria ser mais adequada a aplicação de forças no sentido axial e transmissão suave de movimento. São relativamente baratos e possuem alta fricção se comparados aos fusos de esferas recirculantes, levando a um baixo rendimento devido ao atrito de escorregamento.


Sobre fusos – Aplicações

Os fusos podem ser aplicados em qualquer mecanismo onde haja a necessidade de movimento linear. São amplamente utilizados na indústria em maquinário e processos.


Algumas aplicações incluem:

- Elevadores de carga
- Prensas
- Fresas e tornos
- Equipamentos CNC
- Embaladoras
- Impressoras 3D
- Equipamentos de corte e gravação a laser
- Processos industriais
- Sistemas de posicionamento e movimentação linear




Sobre fusos – Parâmetros

Existem diversas características de um fuso que devem ser levadas em consideração ao se projetar um mecanismo. Além do seu diâmetro e passo, é necessário reconhecer sua resistência a compressão, seu momento de inércia (resistência a alteração de seu estado de rotação), material construtivo, a velocidade de rotação a qual será submetido, direção de operação (horizontal ou vertical), a carga aplicada, entre outras.
Mas, baseando-se em mecanismos já construídos, podemos intuir vários destes parâmetros.
Vamos reconhecer alguns bem comuns. Comecemos pelo PASSO.

Sobre fusos – Passo (deslocamento e velocidade)

Determina o comprimento percorrido pela castanha a cada revolução, sendo medido normalmente em mm/revolução.
Um fuso de 2mm por revolução provocará um deslocamento de 2mm a cada volta que o fuso executar. Influenciará na velocidade linear da castanha, uma vez que, com o aumento da velocidade de rotação, o número de revoluções por unidade de tempo aumentará e consequentemente a distância percorrida também.
Se um fuso de 2mm por revolução girar a 60 RPM (uma volta por segundo), a castanha se movimentará a 2mm por segundo.

Montagem



Na nossa montagem, tenho dois motores e nosso teclado com o display, que ficou parecendo uma calculadora, pois eu fiz uma capa para eles na impressora 3D. No display da Nokia temos as seguintes opções:
F1: Crescente – Fuso vai da posição atual para a posição que eu determinar
F2: Decrescente – Volta
F3: Velocidade – Posso alterar a largura de pulso
F4: ESC


Montagem – Materiais

A - Guias lineares de 10mm
B - Fusos trapezoidais de passos 2 e 8mm
C - Base com furação
D - Mancais para os fusos
E - Suportes das guias
F - Castanhas dos fusos
G - Rolamentos
H - Acopladores
I - Motores
J - Peças de plásticos diversas (cursores, suportes dos motores, calços, suporte de teclado e display)


Montagem - Passo 01

Seguindo a furação da base (C), montamos os dois motores (I). Para prendê-los, usamos suportes feitos na impressora 3D (J). Não apertamos nenhum dos parafusos nesta etapa de posicionamento. Isso permitirá os ajustes necessários na etapa de alinhamento.


Montagem - Passo 02

Ainda seguindo a furação da base (C), posicionamos os suportes das guias (E) e os mancais (D). Detalhe para o calço plástico (J) utilizado para ajustar as alturas dos mancais.


Montagem - Passo 03

Criamos um cursor usando uma peça impressa para conectar o rolamento (G) à castanha (F). Usamos dois cursores, um direito outro esquerdo. Sua função é indicar a posição em uma escala sempre que quisermos determinar o deslocamento causado pelo fuso.


Montagem - Passo 04

Inserimos a guia (A) e o fuso (B) nos seus respectivos mancal (D) e suporte (E), pelo lado oposto ao motor, em seguida, inserimos a guia e o fuso no rolamento (G) e castanha (F) e na ponta do fuso inserimos também o acoplador (H). Levamos os dois até atingirem seus pontos finais (suporte oposto e motor).
Apertamos levemente os parafusos para permitir um posterior ajuste. Repetimos o procedimento usando a guia e fuso restantes. Com todos os componentes posicionados, efetuamos o alinhamento das partes, finalizando a etapa de montagem mecânica.


Montagem - Eletrônica

Usando um suporte plástico impresso, fixamos o display Nokia 5110 e um teclado matricial 4x4. No espaço inferior do suporte residirá o Arduino Uno, o driver DRV8825.


Usando a furação disponível na base, prendemos o conjunto.

Esquema elétrico

O esquema elétrico é simples. Temos o DRV8825 e os dois mesma 17 espelhados, ou seja, o mesmo passo que mando para um vai para o outro. O que muda é que em um dos motores eu tenho um fuso de 8mm e no outro um fuso de 2mm. Obvio, então, que o primeiro, com fuso de 8mm, vai mais rápido. Ainda constam no esquema o display e o teclado 4x4, que tem que ser matricial.


Código fonte

Inclusão de bibliotecas e criação de objetos
Temos aqui uma Lib que eu que fiz, que é a StepDriver.h. Ela está preparada para os drivers 8825, 4988 e também para o TB6600. Crio neste etapa o objeto DRV8825, o d1.

//Biblioteca responsável por capturar a tecla que foi pressionada no teclado
#include <Keypad.h>
//Biblioteca responsável pelos graficos do display
#include <Adafruit_GFX.h>
//Biblioteca responsável pela comunicacao do display
#include <Adafruit_PCD8544.h>

//Configuracao de pinos do Display
// pin 6 - Serial clock out (SCLK)
// pin 5 - Serial data out (DIN)
// pin 4 - Data/Command select (D/C)
// pin 3 - LCD chip select (CS/CE)
// pin 2 - LCD reset (RST)
Adafruit_PCD8544 display = Adafruit_PCD8544(6, 5, 4, 3, 2);

//Biblioteca de motor de passo
#include <StepDriver.h>

//Instancia o driver DRV8825
DRV8825 d1;

Constantes e variáveis globais
Nesta parte do código trato da matriz, que já ensinei em outra videoaula (Assista aqui!). Ainda, falo do objeto Keypad, além da distância e da velocidade.

const byte LINHAS = 4; //número de linhas do teclado
const byte COLUNAS = 4; //número de colunas do teclado

//define uma matriz com os símbolos que deseja ser lido do teclado
char SIMBOLOS[LINHAS][COLUNAS] = {
  {'A', '1', '2', '3'},
  {'B', '4', '5', '6'},
  {'C', '7', '8', '9'},
  {'D', 'c', '0', 'e'}
};

byte PINOS_LINHA[LINHAS] = {A2, A3, A4, A5}; //pinos que indicam as linhas do teclado
byte PINOS_COLUNA[COLUNAS] = {0, 1, A0, A1}; //pinos que indicam as colunas do teclado


//instancia de Keypad, responsável por capturar a tecla pressionada
Keypad customKeypad = Keypad( makeKeymap(SIMBOLOS), PINOS_LINHA, PINOS_COLUNA, LINHAS, COLUNAS);

//variáveis resposnsáveis por armazenar o valor digitado
char customKey;
unsigned long distancia = 0;
unsigned long velocidade = 2000;

Função de leitura do teclado
Nesta etapa temos o código referente ao display, que trabalha a impressão crescente e decrescente.

//Funcao responsavel por ler o valor do usuario pelo teclado-----------------------------------------
unsigned long lerValor() {
  //Escreve o submenu que coleta os valores no display
  display.clearDisplay();
  display.fillRect(0, 0, 84, 11, 2);
  display.setCursor(27, 2);
  display.setTextColor(WHITE);
  display.print("VALOR");
  display.setTextColor(BLACK);

  display.fillRect(0, 24, 21, 11, 2);
  display.setCursor(2, 26);
  display.setTextColor(WHITE);
  display.print("CLR");
  display.setTextColor(BLACK);
  display.setCursor(23, 26);
  display.print("LIMPAR");

  display.fillRect(0, 36, 21, 11, 2);
  display.setCursor(5, 38);
  display.setTextColor(WHITE);
  display.print("F4");
  display.setTextColor(BLACK);
  display.setCursor(23, 38);
  display.print("VOLTAR");
  display.setCursor(2, 14);
  display.display();
  String valor = "";
  char tecla = false;

looping aguardando tecla pressionada
Aqui expomos a programação do Loop, ou seja, onde você digita os valores.

//Loop infinito enquanto nao chamar o return
  while (1) {
    tecla = customKeypad.getKey();
    if (tecla) {
      switch (tecla) {
        //Se teclas de 0 a 9 forem pressionadas
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
        case '0':
          valor += tecla;
          display.print(tecla);
          display.display();
          break;
        //Se tecla CLR foi pressionada
        case 'c':
          //Limpa a string valor
          valor = "";
          //Apaga o valor do display
          display.fillRect(2, 14, 84, 8, 0);
          display.setCursor(2, 14);
          display.display();
          break;
          
        //Se tecla ENT foi pressionada
        case 'e':
          //Retorna o valor
          return valor.toInt();
          break;
          
        //Se tecla F4 (ESC) foi pressionada
        case 'D':
          return -1;
        default:
          break;
      }
    }
    //Limpa o char tecla
    tecla = false;
  }
}

Função de movimentação do motor
A função “mover” é trabalhada nesta etapa. Pego a quantidade de pulsos e a direção e, depois, faço um “for”.

//Funcao responsavel por mover o motor--------------------------------------
void mover(unsigned long pulsos, bool direcao) {
  for (unsigned long i = 0; i < pulsos; i++) {
    d1.motorMove(direcao);
  }
}

setup()
Agora faço a movimentação do display e a configuração do driver, sendo que eu coloquei inclusive a pinagem dentro do código fonte para facilitar. Inicializo certos valores e trato dos métodos que geram as configurações.

void setup() {
  //Configuracao do display ------------------------------------------------
  display.begin();
  display.setContrast(50);
  display.clearDisplay();   
  display.setTextSize(1);  
  display.setTextColor(BLACK); 

  //Configuração do Driver DRV8825 -----------------------------------------
  // pin GND - Enable (ENA)
  // pin 13 - M0 
  // pin 12 - M1
  // pin 11 - M2
  // pin 10 - Reset (RST)
  // pin 9 - Sleep (SLP)
  // pin 8 - Step (STP)
  // pin 7 - Direction (DIR)
  d1.pinConfig(99, 13, 12, 11, 10, 9, 8, 7);
  d1.sleep(LOW);
  d1.reset();
  d1.stepPerMm(100);
  d1.stepPerRound(200);
  d1.stepConfig(1);
  d1.motionConfig(50, velocidade, 5000);
  
}

loop() – 1ª parte – Desenhando menu

void loop() {
  
  //Escreve o Menu do Programa no display -----------------------------------
  display.clearDisplay();
  display.fillRect(0, 0, 15, 11, 2);
  display.setCursor(2, 2);
  display.setTextColor(WHITE);
  display.print("F1");
  display.setTextColor(BLACK);
  display.setCursor(17, 2);
  display.print("CRESCENTE");

  display.fillRect(0, 12, 15, 11, 2);
  display.setCursor(2, 14);
  display.setTextColor(WHITE);
  display.print("F2");
  display.setTextColor(BLACK);
  display.setCursor(17, 14);
  display.print("DECRESCENTE");

  display.fillRect(0, 24, 15, 11, 2);
  display.setCursor(2, 26);
  display.setTextColor(WHITE);
  display.print("F3");
  display.setTextColor(BLACK);
  display.setCursor(17, 26);
  display.print("VELOCIDADE");

loop() – 2ª parte – Desenhando menu

display.fillRect(0, 36, 15, 11, 2);
  display.setCursor(2, 38);
  display.setTextColor(WHITE);
  display.print("F4");
  display.setTextColor(BLACK);
  display.setCursor(17, 38);
  display.print("ESC");

  display.display();

  bool esc = false;

loop() – 3ª parte – Executando

 //Loop enquanto a tecla F4 (ESC) nao for pressionada
  while (!esc) {
    
    //captura a tecla pressionada do teclado
    customKey = customKeypad.getKey();

    //caso alguma tecla foi pressionada
    if (customKey) {

      //Trata a tecla apertada
      switch (customKey)
      {
        //Se tecla F1 foi pressionada
        case 'A':
          distancia = lerValor();

          //Se tecla ESC foi pressionada
          if (distancia == -1) {
            esc = true;
          } else {
            //Escreve a tela "Movendo" no display
            display.clearDisplay();
            display.fillRect(0, 0, 84, 11, 2);
            display.setCursor(21, 2);
            display.setTextColor(WHITE);
            display.print("MOVENDO");
            display.setTextColor(BLACK);
            display.setCursor(2, 14);
            display.print(distancia);
            display.print(" Passos");
            display.display();

loop() – 4ª parte – Executando

            //Move o motor
            mover(distancia, LOW);
            
            //Volta ao menu
            esc = true;
          }
          break;

        //Se tecla F2 foi pressionada
        case 'B':
          distancia = lerValor();

          //Se tecla ESC foi pressionada
          if (distancia == -1) {
            esc = true;
          } else {
            
            //Escreve a tela "Movendo" no display
            display.clearDisplay();
            display.fillRect(0, 0, 84, 11, 2);
            display.setCursor(21, 2);
            display.setTextColor(WHITE);
            display.print("MOVENDO");
            display.setTextColor(BLACK);
            display.setCursor(2, 14);
            display.print(distancia);
            display.print(" Passos");
            display.display();

loop() – 5ª parte – Executando

            //Move o motor
            mover(distancia, HIGH);
            
            //Volta ao menu
            esc = true;
          }
          break;

        //Se tecla F3 foi pressionada
        case 'C':
          velocidade = lerValor();
          if (velocidade == -1) {
            esc = true;
          } else {
            //Escreve a tela "Velocidade" no display
            display.clearDisplay();
            display.fillRect(0, 0, 84, 11, 2);
            display.setCursor(12, 2);
            display.setTextColor(WHITE);
            display.print("VELOCIDADE");
            display.setTextColor(BLACK);
            display.setCursor(2, 14);
            display.print(velocidade);
            display.print(char(229));
            display.print("s");

loop() – 6ª parte – Executando

            display.fillRect(31, 24, 21, 11, 2);
            display.setCursor(33, 26);
            display.setTextColor(WHITE);
            display.println("OK!");
            display.setTextColor(BLACK);
            display.display();

            //Configura nova velocidade ao motor
            d1.motionConfig(50, velocidade, 5000);
            delay(2000);
            
            //Volta ao menu
            esc = true;
          }
          break;
        //Se tecla F4 (ESC) foi pressionada
        case 'D':
        //Se tecla CLR foi pressionada
        case 'c':
        //Se tecla ENT foi pressionada
        case 'e':
        //Volta ao menu
          esc = true;
        default:
          break;
      }

    }
     //Limpa o char customKey
    customKey = false;
  }
}

Sobre fusos – Configurações em máquinas

Em máquinas CNC como impressoras 3D e routers por exemplo, o programa responsável pelo controle do posicionamento precisa saber como os movimentos ocorrerão em função do número de pulsos dados ao motor de passo.
Se o driver do motor de passo permitir a aplicação de micro-passos, essa configuração deve ser levada em consideração no cálculo do deslocamento produzido.
Por exemplo: se um motor de 200 passos por revolução, estiver ligado a um driver configurado para 1/16, então serão necessários 16 x 200 pulsos para uma única revolução do fuso, ou seja, 3200 pulsos para cada revolução. Se este fuso tiver passo de 2mm por revolução, serão necessários 3200 pulsos no driver para que a castanha se mova 2mm.
De fato, os softwares controladores costumam usar um razão para especificar esta relação, o “número de pulsos por milímetro” ou “steps/mm”.

Marlin
No Marlin, por exemplo, vemos na seção @section motion:
Neste exemplo, podemos concluir que os eixos X e Y precisam de 80 pulsos para se deslocar 1mm, enquanto que o Z precisa de 3200 pulsos e o extrusor E0 precisa de 100.

GRBL
Abaixo vemos os comandos de configuração do GRBL. Com o comando $100, podemos ajustar o número de pulsos necessários para provocar um deslocamento de um milímetro no eixo X.
No exemplo podemos ver que o valor atual é de 250 pulsos por mm.
Os eixos Y e Z podem ser configurados respectivamente o $101 e $102.


Faça o download dos arquivos




2 comentários:

  1. Fernando, não encontrei o download da lib StepDriver.h
    Abraço!

    ResponderExcluir
    Respostas
    1. Olá, Luis Carlos. Obrigado pelo toque. Inserimos o link de download ao fim do artigo, ok!
      Abraço

      Excluir

Tecnologia do Blogger.