22 outubro 2016

Como usar motor DC com encoder no Arduino

Neste post vamos mostrar um motor muito usado em projetos de robótica, que é um motor DC com encoder embutido. Esse tipo de motor com encoder permite que você possa calcular a distância percorrida pelo robô, ou ajustar a velocidade do motor de acordo com a leitura de sensores.

Motor DC com encoder embutido

O motor que vamos utilizar é o motor DC 6V com encoder embutido, o mesmo mostrado na imagem acima, que tem uma pequena placa na parte de trás onde estão instalados os sensores hall que vão ler as informações relativas à rotação do motor.

São 2 sensores na placa, e com ele podemos medir não só a velocidade como também o sentido de rotação, o que pode ser muito útil na hora de configurar o robô para evitar obstáculos, virar para direita/esquerda, retornar, etc.

Conexões do motor DC com encoder embutido


Essa placa tem um conector com 6 pinos, onde vamos ligar tanto a alimentação do motor (pinos M- e M+), a alimentação dos sensores do encoder (GND e 3.3V) e onde teremos o sinal de saída, nos pinos C1 (canal A do encoder) e C2 (canal B do encoder):

Encoder - Conexões

Assim, precisamos de apenas dois pinos do Arduino para ler as informações dos sensores do encoder. O pino C1 será ligado ao pino 2 do Arduino (interrupção 0), e o pino C2 será ligado ao pino digital 4.

Ligação do Motor DC 6V 210 RPM no Arduino


Como esse motor exige mais corrente do que a suportada pelos pinos do Arduino, vamos usar no nosso circuito um módulo ponte H L298N (abaixo), controlando o sentido de rotação com um potenciômetro de 10K ligado ao pino digital A0. 

Módulo Ponte H L298N

Ligamos então o motor em uma das saídas da ponte H (OUT1 e OUT2), os pinos GND e 3.3V da placa do encoder nos pinos correspondentes no Arduino, a saída C1 no pino digital 2, e a saída C2 no pino digital 4:

Circuito Arduino Uno Motor DC com Encoder e Ponte H L298N

Os pinos 6 e 7 controlam o sentido de rotação do motor: sentido horário (pino 6 HIGH e pino 7 LOW) ou anti-horário (pino 6 LOW e pino 7 HIGH).

Programa motor DC com encoder


O programa abaixo não utiliza bibliotecas específicas, efetuando a leitura dos pinos 2 (interrupção 0 do Arduino, utilizado para a contagem de pulsos) e  4 (usado para identificar o sentido de rotação do motor). 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
//Programa: Motor DC com encoder
//Autor: Arduino e Cia

const byte Encoder_C1 = 2;
const byte Encoder_C2 = 4;
byte Encoder_C1Last;
int duracao;
boolean Direcao;

//Pinos de ligacao ponte H L298N
#define pino_motor1 6
#define pino_motor2 7

void setup()
{
  Serial.begin(57600);
  //Pino potenciometro
  pinMode(A0, INPUT);
  //Definicao pinos ponte H
  pinMode(pino_motor1, OUTPUT);
  pinMode(pino_motor2, OUTPUT);
  //Definicao do encoder
  EncoderInit();
}

void loop()
{
  Serial.print("Pulso: ");
  Serial.print(duracao);
  int valor = analogRead(A0);
  if (valor >= 512)
  {
    digitalWrite(pino_motor1, LOW);
    digitalWrite(pino_motor2, LOW);
    //delay(1000);
    digitalWrite(pino_motor1, LOW);
    digitalWrite(pino_motor2, HIGH);
    Serial.println(" Sentido: Anti-horario");
  }
  else
  {
    digitalWrite(pino_motor1, HIGH);
    digitalWrite(pino_motor2, LOW);
    Serial.println(" Sentido: Horario");
  }
  duracao = 0;
  delay(100);
}

void EncoderInit()
{
  pinMode(Encoder_C2, INPUT);
  attachInterrupt(0, calculapulso, CHANGE);
}

void calculapulso()
{
  int Lstate = digitalRead(Encoder_C1);
  if ((Encoder_C1Last == LOW) && Lstate == HIGH)
  {
    int val = digitalRead(Encoder_C2);
    if (val == LOW && Direcao)
    {
      Direcao = false; //Reverse
    }
    else if (val == HIGH && !Direcao)
    {
      Direcao = true;  //Forward
    }
  }
  Encoder_C1Last = Lstate;

  if (!Direcao)  duracao++;
  else  duracao--;
}

Conforme o valor enviado pelo potenciômetro ligado na porta analógica A0, o sentido de rotação do motor é alterado. Essa alteração pode ser acompanhada no Serial Monitor, onde também é mostrada a quantidade de pulsos lida pelo encoder (não esqueça de alterar a velocidade da serial para 57600):


Experimente incorporar ao circuito um potenciômetro para controlar também a velocidade do motor, assim você pode acompanhar a variação na quantidade de pulsos lidos.

10 comentários:

  1. tem previsão de fazer testes com clone de controle de ar condicionado??? Já tem 3 semanas que estou apanhando aqui...não consigo de jeito nenhum infelizmente...
    A cada vez que aperto o mesmo botão recebo código diferente, quando envio o código, sempre é enviado um diferente(usando um arduino para enviar e outro para receber - testes)...Será a biblioteca?
    http://www.instructables.com/id/Ar-Condicionado-controlado-por-Arduino-via-infrave/

    ResponderExcluir
  2. Qual a relação da quantidade de pulsos lidos com a velocidade?

    ResponderExcluir
    Respostas
    1. Aparentemente, a relação é de aproximadamente 340 ppr (pulsos por revolução) segundo uma pagina do AliExpress que vende o mesmo produto.

      Excluir
    2. Aparentemente, a relação é de aproximadamente 340 ppr (pulsos por revolução) segundo um artigo do Aliexpress que vende o mesmo produto.

      Excluir
  3. cOMO FAZERPARA FREIAR MOTOR quando chegar numero de pulsos no encoder

    ResponderExcluir
    Respostas
    1. Olá! Inverta a polaridade no controlador L298. Acho que pela corrente que esse motor consome não deverá estragar o driver.

      Embora eu tenha tido problemas com controladores da china com troca de sentido muito rápidas. Os diodos Schotty são pequenos e queimam com facilidade.

      Excluir
  4. Qual a quantidade de pulsos geradas por um encoder desses em cada volta?

    ResponderExcluir
  5. Quando eu coloco essa programação junto ao motor girante em um único sentido, os pulsos vão de -1, ... , -32000. Depois cai de +3200, ..., +1. alguem pode me explicar o por quê?

    ResponderExcluir
  6. No serial mostra que meu encoder somente com valor negativo, tanto para sentido horario como anti horario, sera que ele esta com defeito?

    ResponderExcluir
  7. Gostaria de ligar esse enconder ao meu projeto que é um carrinho controlado..

    ResponderExcluir