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:
  1. /* 
  2.  * Segundo exemplo de comando do Arduino via IR 
  3.  */  
  4.   
  5. #include <IRremote.h>  
  6.   
  7. // variaveis para recepção dos comandos IR  
  8. const int RECV_PIN = 11;  
  9. IRrecv irrecv(RECV_PIN);  
  10.   
  11. // comandos  
  12. typedef unsigned long dword;  
  13. const dword addr = 0;  
  14. const dword cmdPlay = 0x22;  
  15. const dword cmdNext = 0xC2;  
  16. const dword cmdPrev = 0x02;  
  17. #define CMD_IR(cmd) ((addr << 24) | \  
  18.                      ((~addr & 0xFF) << 16) | \  
  19.                      (cmd << 8) | \  
  20.                      (~cmd & 0xFF) )  
  21.   
  22. // pinos dos LEDs  
  23. const int LED_R = 4;  
  24. const int LED_Y = 3;  
  25. const int LED_G = 2;  
  26.   
  27. // pinos do EasyDriver  
  28. const int ED_DIR = 6;  
  29. const int ED_STEP = 5;  
  30. const int ED_ENAB = 13;  
  31.   
  32. // variaveis de controle do motor  
  33. enum { PARADO, ANDANDO } modo = PARADO;  
  34.   
  35. void setup()  
  36. {  
  37.   // Configura conexões dos LEDS  
  38.   pinMode (LED_G, OUTPUT);  
  39.   pinMode (LED_Y, OUTPUT);  
  40.   pinMode (LED_R, OUTPUT);  
  41.   
  42.   // Configura conexões com o EasyDriver  
  43.   pinMode (ED_DIR, OUTPUT);  
  44.   pinMode (ED_STEP, OUTPUT);  
  45.   pinMode (ED_ENAB, OUTPUT);  
  46.   digitalWrite (ED_ENAB, HIGH);  // desliga  
  47.   digitalWrite (ED_DIR, LOW);  
  48.   digitalWrite (ED_STEP, LOW);  
  49.   
  50.   // Inicia recepção IR  
  51.   irrecv.enableIRIn();  
  52. }  
  53.   
  54. void loop() {  
  55.   decode_results results;  
  56.     
  57.   if (irrecv.decode(&results) && results.decode_type==NEC) {  
  58.     // recebeu um comando NEC  
  59.     switch (results.value) {  
  60.       case CMD_IR(cmdPlay):  
  61.         digitalWrite(LED_G, HIGH);  
  62.         digitalWrite(LED_Y, LOW);  
  63.         digitalWrite(LED_R, LOW);  
  64.         if (modo == ANDANDO) {  
  65.           modo = PARADO;  
  66.           digitalWrite (ED_ENAB, HIGH);  
  67.         } else {  
  68.           modo = ANDANDO;  
  69.           digitalWrite (ED_ENAB, LOW);  
  70.         }  
  71.         break;          
  72.       case CMD_IR(cmdPrev):  
  73.         digitalWrite(LED_G, LOW);  
  74.         digitalWrite(LED_Y, HIGH);  
  75.         digitalWrite(LED_R, LOW);  
  76.         if (modo == PARADO) {  
  77.           digitalWrite (ED_DIR, HIGH);  
  78.         }  
  79.         break;          
  80.       case CMD_IR(cmdNext):  
  81.         digitalWrite(LED_G, LOW);  
  82.         digitalWrite(LED_Y, LOW);  
  83.         digitalWrite(LED_R, HIGH);  
  84.         if (modo == PARADO) {  
  85.           digitalWrite (ED_DIR, LOW);  
  86.         }  
  87.         break;          
  88.     }  
  89.       
  90.     // decodificar o próximo comando  
  91.     irrecv.resume();  
  92.   }  
  93.   
  94.   // Move o motor se ligado  
  95.   if (modo == ANDANDO) {  
  96.     digitalWrite (ED_STEP, HIGH);  
  97.     delay (1);  
  98.     digitalWrite (ED_STEP, LOW);  
  99.     delay (1);  
  100.   }      
  101. }  
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: