quinta-feira, outubro 10, 2013

Controle Remoto Infravermelho Parte 5

Vamos sofisticar um pouquinho o exemplo anterior e controlar um motor de passo.




Para acionar o motor de passo vou usar o EasyDriver. Esta pequena plaquinha contem o Allegro A3967, um controlador bastante versátil e fácil de interfacear. Neste exemplo, as ligações que eu fiz no EasyDriver são:
  • O sinal GND ao terra do Arduino
  • O sinal STEP ao pino D do Arduino
  • O sinal DIR ao pino D do Arduino
  • O sinal ENABLE ao pino D do Arduino
  • Os pinos MOTOR A B C D às bobinas do motor de passo
  • Os pinos PWR IN (alimentação do motor) a uma fonte externa de 12V
A minha montagem inclui ainda um "capacitor de desacoplamento" - um capacitor pequeno (10nF) ligado entre a alimentação e o terra, próximo ao Arduino, com o objetivo de filtrar interferências na alimentação quando o motor é acionado.  Eu acrescentei isto após ter comportamentos esquisitos no Arduino e parece ter resolvido o problema.

Uma característica deste controlador é que normalmente temos corrente nas bobinas quando o motor está parado (para segurar o motor na posição), o que gera um certo aquecimento da placa e do motor. Como não estou preocupado em segurar o motor, uso o pino ENABLE para desabilitar as saídas quando o motor estiver parado.

Para mover o motor basta enviar um pulso no sinal STEP. Por default o controlador trabalha com microstepping - cada pulso corresponde a um oitavo de passo. O sinal DIR define a direção do movimento.

A tecla Play é usada para ligar e desligar o movimento. As teclas Next e Prev controlam o sinal DIR, permitindo definir se o movimento será para frente ou para trás. Estas duas teclas só atuam quando o motor estiver parado.

O programa não é muito complicado:
/*
 * Segundo exemplo de comando do Arduino via IR
 */

#include <IRremote.h>

// variaveis para recepção dos comandos IR
const int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);

// comandos
typedef unsigned long dword;
const dword addr = 0;
const dword cmdPlay = 0x22;
const dword cmdNext = 0xC2;
const dword cmdPrev = 0x02;
#define CMD_IR(cmd) ((addr << 24) | \
                     ((~addr & 0xFF) << 16) | \
                     (cmd << 8) | \
                     (~cmd & 0xFF) )

// pinos dos LEDs
const int LED_R = 4;
const int LED_Y = 3;
const int LED_G = 2;

// pinos do EasyDriver
const int ED_DIR = 6;
const int ED_STEP = 5;
const int ED_ENAB = 13;

// variaveis de controle do motor
enum { PARADO, ANDANDO } modo = PARADO;

void setup()
{
  // Configura conexões dos LEDS
  pinMode (LED_G, OUTPUT);
  pinMode (LED_Y, OUTPUT);
  pinMode (LED_R, OUTPUT);

  // Configura conexões com o EasyDriver
  pinMode (ED_DIR, OUTPUT);
  pinMode (ED_STEP, OUTPUT);
  pinMode (ED_ENAB, OUTPUT);
  digitalWrite (ED_ENAB, HIGH);  // desliga
  digitalWrite (ED_DIR, LOW);
  digitalWrite (ED_STEP, LOW);

  // Inicia recepção IR
  irrecv.enableIRIn();
}

void loop() {
  decode_results results;
  
  if (irrecv.decode(&results) && results.decode_type==NEC) {
    // recebeu um comando NEC
    switch (results.value) {
      case CMD_IR(cmdPlay):
        digitalWrite(LED_G, HIGH);
        digitalWrite(LED_Y, LOW);
        digitalWrite(LED_R, LOW);
        if (modo == ANDANDO) {
          modo = PARADO;
          digitalWrite (ED_ENAB, HIGH);
        } else {
          modo = ANDANDO;
          digitalWrite (ED_ENAB, LOW);
        }
        break;        
      case CMD_IR(cmdPrev):
        digitalWrite(LED_G, LOW);
        digitalWrite(LED_Y, HIGH);
        digitalWrite(LED_R, LOW);
        if (modo == PARADO) {
          digitalWrite (ED_DIR, HIGH);
        }
        break;        
      case CMD_IR(cmdNext):
        digitalWrite(LED_G, LOW);
        digitalWrite(LED_Y, LOW);
        digitalWrite(LED_R, HIGH);
        if (modo == PARADO) {
          digitalWrite (ED_DIR, LOW);
        }
        break;        
    }
    
    // decodificar o próximo comando
    irrecv.resume();
  }

  // Move o motor se ligado
  if (modo == ANDANDO) {
    digitalWrite (ED_STEP, HIGH);
    delay (1);
    digitalWrite (ED_STEP, LOW);
    delay (1);
  }    
}
O vídeo abaixo mostra o funcionamento:


O vídeo e a foto dão uma dica do que eu pretendo fazer no próximo post.

Nenhum comentário: