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.

2 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