Controle remoto no Arduino: incrementando nosso placar eletrônico

Um controle remoto simples e um receptor infravermelho permitem operar nosso placar eletrônico à distância.

Veremos como acrescentei um módulo receptor de controle remoto ao projeto do placar eletrônico, para que a pontuação possa ser controlada à distância.

Nosso placar eletrônico com módulo display 7 segmentos, apresentado no artigo anterior, tinha funcionalidade completa, mas uma limitação importante: ser operado por botões que ficam fisicamente no display, exigindo assim que o operador fique permanentemente junto a ele.

Na prática, podemos desejar que o placar fique no alto de uma parede, ou em outro lugar de boa visibilidade mas inconveniente para a presença da pessoa que vai registrar os pontos. Ainda mais na prática, pode até mesmo ser um dos jogadores o responsável por fazer avançar a contagem, e aí o nosso modelo exigiria que o display ficasse próximo a ele, e não em um local igualmente visível para ambos os jogadores.

Existem várias soluções para isso (boa parte delas envolve fiação), mas hoje veremos uma que é especialmente conveniente: um controle remoto infravermelho (ou IR), do mesmo tipo usado em TVs.

Para nossos testes, usaremos um Kit Controle Remoto Infravermelho + Receptor - KY-022 cedido pela Usinainfo, que patrocinou o experimento deste artigo. Trata-se de par composto por um controle de 18 teclas e um módulo receptor infravermelho KY-022, fácil de conectar ao Arduino.

O mais interessante é que o módulo KY-022 não se limita ao controle que vem no kit – trata-se de um receptor infravermelho apto a receber sinais da maioria dos controles remotos comuns das nossas casas. Nos meus testes, ele decodificou sinais vindos dos controles da TV a cabo, do aparelho de DVD, de 2 TVs e do som: 100% dos controles que eu testei. Mas fique atento: é possível que você tenha algum controle remoto baseado em radiofrequência ou outro padrão de comunicação, e aí ele não será compatível com esse módulo.

Esse módulo receptor tem 3 pinos, identificados pelas letras G, R e Y, sendo que G deve ser ligado ao GND, R deve ser ligado ao 5V, e Y deve ser ligado a um pino digital do Arduino. Uma vez conectado, pode-se usar a biblioteca IRRemote1 para receber os comandos de qualquer controle remoto compatível.

Códigos de teclas de controle remoto

Em sua essência, o funcionamento de um controle remoto infravermelho se baseia em enviar códigos numéricos a um receptor. Cada tecla é representada por um código numérico específico, e cabe ao programa que aciona o receptor a tarefa de interpretar os códigos.

Ou seja: ao pressionar a tecla ⬆ no controle remoto que vem nesse kit, ele transmite o código 0xFF629D. Cabe ao nosso programa no Arduino saber que 0xFF629D corresponde à tecla da seta para cima e, ao receber esse código, realizar a ação adequada (que depende do contexto: pode ser aumentar o volume, ligar um motor, ou aumentar o ponto de um dos jogadores em um placar, por exemplo).

Para descobrir qual o código correspondente a cada tecla de um controle, podemos usar o exemplo IRrecvDemo que acompanha a biblioteca IRRemote. Quando ele está instalado em um Arduino, fica continuamente monitorando um sensor e exibindo, no monitir serial, todos os códigos que recebe.

Como eu quero usar as teclas cima, direita, baixo e esquerda do controle remoto deste kit, transferi o IRrecvDemo para um Arduino Uno, modifiquei a definição da variável RECV_PIN para referenciar o pino do Arduino que está conectado ao pino Y do módulo, e pressionei, no controle, as teclas desejadas, na sequência que mencionei. O monitor serial exibiu os seguintes códigos:

511DBB
FFC23D
FFA857
FF22DD

Portanto os códigos acima correspondem, pela ordem, às teclas ⬆, ➡, ⬇ e ⬅ do controle que acompanha o kit.

Apenas para exemplificar a diferença, pressionei as mesmas teclas direcionais em um controle remoto da TV a Cabo (Net), e os códigos gerados foram:

E17AD02F
E17A38C7
E17A30CF
E17AD827

Adequando nosso programa

A montagem do placar e a descrição de seu programa já foram descritos detalhadamente no artigo anterior: “Placar eletrônico no Arduino e módulo display 7 segmentos com TN1638”.

Especialmente importante, no programa anterior, é a existência de uma função chamada soltouTecla(), que recebe como parâmetro um código de pressionamento de tecla do teclado físico do módulo usado no placar, e realiza o processamento adequado (ou seja, aumenta ou diminui a pontuação do jogador apropriado, recalcula a situação da partida e redesenha os números mostrados no placar).

O que vamos fazer hoje é acrescentar, no programa, o código necessário para poder controlar a pontuação do jogador A com as teclas ⬆ e ⬇, e a do jogador B com as teclas ➡ e ⬅.

Para isso, vamos ler um módulo receptor infravermelho conectado ao pino 4 do Arduino e, ao detectar o pressionamento das teclas ⬆, ➡, ⬇ e ⬅ no controle remoto, simular o pressionamento da tecla com a função correspondente no teclado físico do módulo.

Ou seja: a tecla ➡ do controle deve aumentar a pontuação do jogador B; a tecla física (do módulo display) que realiza essa mesma função tem o código numérico 16 (conforme visto no artigo anterior); portanto, ao detectar que a tecla ➡ do controle remoto foi pressionada, faremos uma chamada à função soltouTecla(), passando 16 como o parâmetro, e o programa prosseguirá como se a tecla física correspondente tivesse sido pressionada, atualizando pontuações e a exibição no display.

Tudo isso é feito com apenas 4 trechos acrescentados ao programa do artigo anterior. Eles estão coloridos na listagem a seguir, para facilitar a explicação, que vem logo abaixo.

#include <TM1638.h>
TM1638 painel(10,11,12);

#include <IRremote.h>
IRrecv irrecv(4);
decode_results results;
const unsigned long bot_A_mais=0xFF629D;
const unsigned long bot_A_menos=0xFFA857;
const unsigned long bot_B_mais=0xFFC23D;
const unsigned long bot_B_menos=0xFF22DD;


const byte SETSVITORIA=3;

long SetA=SETSVITORIA, SetB=SETSVITORIA; 
long PontoA=0, PontoB=0;

void atualizaPlacar() {
  long p=SetA * 10000000 + PontoA * 10000 + SetB * 1000 + PontoB;
  painel.setDisplayToDecNumber(p, 136);
}

void pisca(byte quantas) {
  for (byte i=0;i<quantas;i++) {
    painel.setLEDs(24);
    delay(30);
    painel.setLEDs(60);
    delay(40);
    painel.setLEDs(126);
    delay(50);
    painel.setLEDs(255);
    delay(60);
  }
}

void calculaPartida() {
  if (PontoA<0) PontoA=0;
  if (PontoB<0) PontoB=0;
  if ((PontoA>10) & (PontoA-PontoB > 1)) {
    atualizaPlacar();
    SetA--;
    PontoA=0;
    PontoB=0;
    pisca(5);
  }
  if ((PontoB>10) & (PontoB-PontoA > 1)) {
    atualizaPlacar();
    SetB--;
    PontoA=0;
    PontoB=0;
    pisca(5);
  }
  if ((SetA==0) | (SetB==0)) {
    atualizaPlacar();
    PontoA=0;
    PontoB=0;
    SetA=SETSVITORIA; 
    SetB=SETSVITORIA; 
    pisca(10);   
  }
}

void setup() {
  irrecv.enableIRIn();
  
  atualizaPlacar();
}

void soltouTecla(byte t) {
  switch (t) {
    case 1:
      PontoA++;
      break;
    case 2:
      PontoA--;
      break;
    case 16:
      PontoB++;
      break;
    case 32:
      PontoB--;
      break;
  }
  calculaPartida();
  atualizaPlacar();
}

void recebeuRemoto(unsigned long codigoIR) {
    switch(codigoIR) {
      case bot_A_mais:
        soltouTecla(1);
        break;
      case bot_A_menos:
        soltouTecla(2);
        break;      
      case bot_B_mais:
        soltouTecla(16);
        break;
      case bot_B_menos:
        soltouTecla(32);
        break;
    }  
}


byte anim=2;
byte ultimatecla;
word tempotecla=0;
word contavoltas=0;
boolean crescendo=true;

void animaLeds() {
  painel.setLEDs((128 | anim | 1));
  if (crescendo) anim=anim*2;
  else anim=anim/2;
  if (anim>63) crescendo=false;
  if (anim<3) crescendo=true;
}

void loop() {
  byte teclas = painel.getButtons();
  if (teclas!=ultimatecla) {
    if ((teclas==0) & (tempotecla>4)) {
      soltouTecla(ultimatecla);
    }
    ultimatecla=teclas;
    tempotecla=0;
  }
  else {
    tempotecla++;
  }
  
  if (irrecv.decode(&results)) {
    recebeuRemoto(results.value);
    irrecv.resume(); 
  }    
  
  if (contavoltas%300==0) {
    animaLeds();
  }  
  contavoltas++;
}

O trecho em roxo faz a inclusão da biblioteca IRRemote (que precisa ter sido previamente instalada na sua IDE Arduino), instancia (no objeto irrecv, cujo parâmetro é o número do pino do Arduino em que está conectado) nosso módulo leitor infravermelho, e define 4 constantes numéricas hexadecimais equivalentes aos códigos das teclas ⬆, ➡, ⬇ e ⬅, que lemos acima usando o exemplo IRrecvDemo, às quais dei nomes correspondendo a ações que devem realizar: o botão que aumenta a pontuação do jogador A, o que a diminui, etc.

A linha em verde fica na função setup() e tem uma tarefa especial: ativa os recursos da biblioteca IRRemote responsáveis por monitorar continuamente o módulo leitor.

Em laranja temos a função recebeuRemoto(). Ela será chamada sempre que uma tecla de controle remoto for lida pelo módulo receptor, e recebe como parâmetro o código numérico obtido dessa leitura, que será comparado aos 4 códigos das teclas ⬆, ➡, ⬇ e ⬅, chamando a função soltouTecla() com o código de tecla física correspondente à função desejada, conforme já exposto acima.

Finalmente, em vermelho, temos o trecho da função loop() que se encarrega de verificar se algum código foi lido pelo módulo (função irrecv.decode da biblioteca), repassando-os à recebeuRemoto() e logo em seguida liberando o módulo para que possa receber mais comandos remotos (função irrecv.resume() da biblioteca).

Com essas 4 pequenas alterações, nosso placar ganha a capacidade de ser controlado remotamente.

Patrocínio: Usinainfo

Quero agradecer à UsinaInfo, que vem patrocinando alguns experimentos do BR-Arduino, inclusive este com o Kit Controle Remoto Infravermelho + Receptor - KY-022 (que também usa o Módulo Display 7 Segmentos + 8 Leds + 8 Push Buttons Programáveis - TM1638).

Além de receber material da empresa para os experimentos como parte do acordo de patrocínio, eu já fiz compras de componentes lá, aproveitando a variedade, o estoque bem suprido, as descrições detalhadas e a qualidade do seu sistema de comércio eletrônico. Recomendo sem ressalvas.

Agradeço também pela confiança que ficou expressa nos termos do patrocínio: a empresa me enviou os componentes necessários ao experimento combinado, mas não fez qualquer exigência sobre a forma e nem buscou exercer controle sobre o que eu fosse escrever. Obrigado, UsinaInfo!

 
  1.   Criada por Ken Shirriff.

Comentar

Dos leds ao Arduino, ESP8266 e mais

Aprenda eletrônica com as experiências de um geek veterano dos bits e bytes que nunca tinha soldado um led na vida, e resolveu narrar para você o que descobre enquanto explora esse universo – a partir da eletrônica básica, até chegar aos circuitos modernos.

Por Augusto Campos, autor do BR-Linux e Efetividade.net.

Recomendados

Livro recomendado


Artigos já disponíveis

Comunidade Arduino

O BR-Arduino é integrante da comunidade internacional de entusiastas do Arduino, mas não tem relação com os criadores e distribuidores do produto, nem com os detentores das marcas registradas.

Livros recomendados