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!
- Criada por Ken Shirriff. ↩
Comentar