Como montar o Jogo Pega LED
O Pega LED é um jogo interativo de rastreamento de luz, ideal para brincar com os amigos e testar a agilidade de cada participante. Para pontuar, participante precisa acionar um sensor LDR usando uma lanterna no local em que o LED verde aparecer. A cada ponto, o LED verde muda de posição. Por exemplo, se o LED verde acender na posição 3, o jogador deve direcionar a luz da lanterna para o LDR da posição 3. O jogo tem duração de 60 segundos e ganha quem conseguir fazer a maior pontuação nesse intervalo de tempo.
O jogo é controlado por 6 LDRs que, quando saturados com a lanterna, agem como se fosse botões. Cada LDR é responsável por uma posição do LED endereçável. Desta forma, foram definidas 6 posições de 0 a 5, onde o LDR conectado ao pino A0 controla o LED da posição 0, o LDR no pino A1 controla o LED na posição 1, e assim sucessivamente, até o LDR no pino A5.
MATERIAIS NECESSÁRIOS
1 x Placa Uno SMD R3 Atmega328;
1 x Cabo USB Tipo A – B Compatível com Arduino;
1x Kit de LDR 5mm Fotoresistor;
1x Kit de Resistor 10 kΩ;
1x Termo retrátil;
1x Kit de cabo Jumper Macho x Macho 20 cm;
1x Fita de LED Endereçável.
ESQUEMATICO DE LIGAÇÃO
Certifique-se que o circuito esteja desenergizado e faça as ligações conforme o esquemático abaixo.
Ao montar seu circuito na protoboard, preste atenção nos seguintes pontos:
- Conecte o GND da fita ao GND do Arduino;
- Conecte o Din (sinal da fita led), na porta digital 2 da placa UNO;
- E o 5V da fita no 5V do Arduino;
- Ligue também um pino de cada um dos LDRs ao 5 V do Arduino;
- No outro pino do LDR, coloque um resistor de 10 kΩ conectado ao GND;
- No pino do LDR ligado ao GND, conecte um jumper que irá para as portas analógicas correspondentes às posições. O jumper do LDR da primeira posição deve ser conectado à entrada A0 do Arduino, o segundo à A1, o terceiro à A2, o quarto à A3, o quinto à A4, e o sexto à A5.
Observação: Como o LDR é um sensor que é bastante sensível, a luz da lanterna pode interferir no LDR ao lado. Para garantir que a luz atinja apenas o LDR desejado, é importante colocar um tubo termo retrátil ou um canudo cobrindo suas laterais, protegendo-o da luz indesejada.
ELABORANDO O CÓDIGO
CÓDIGO TESTE
Antes de começar a programar o projeto, é importante testar a sensibilidade dos LDRs. Para isso, definimos a quantidade de LDRs e declaramos um array que armazena os números dos pinos analógicos aos quais os LDRs estão conectados: A0, A1, A2, A3, A4 e A5. Em seguida, utilizamos a função Serial.begin() no setup() para iniciar a comunicação serial. No loop(), foi criado um laço for para ler os valores dos LDRs e imprimi-los de maneira organizada.
O código testa todos os LDRs ao mesmo tempo, e identifica a quantidade de luz que o sensor está capturando no ambiente. O valor lido é exibido no monitor serial e serve de base para ajustar a sensibilidade no código principal.
O código teste ficou assim:
#define NUM_LDRS 6 // Número de LDRs // Pinos dos LDRs int ldrPinos[NUM_LDRS] = {A0, A1, A2, A3, A4, A5}; void setup() { Serial.begin(9600); // Inicializa a comunicação serial } void loop() { // Lê os valores dos LDRs for (int i = 0; i < NUM_LDRS; i++) { int valorLdr = analogRead(ldrPinos[i]); Serial.print("LDR"); Serial.print(i); Serial.print(": "); Serial.print(valorLdr); Serial.print("\t"); // Tabulação para separar os valores na mesma linha } Serial.println(); // pula para a próxima linha após imprimir todos os valores delay(1000); // Atraso de 1 segundo entre as leituras }
Lembre-se de testar os LDRs com e sem a lanterna. Além disso, verifique se, ao direcionar a lanterna para um LDR específico, não há interferência no LDR próximo. Evite posicioná-los muito próximos uns dos outros.
CÓDIGO COMPLETO
Agora, no código principal do projeto, incluímos a biblioteca Adafruit_NeoPixel.h, que é responsável pelo controle dos LEDs endereçáveis. Definimos o pino 2 para o sinal dos LEDs e a quantidade utilizada, além de criar uma variável para controlar o brilho.
Em seguida, criamos um objeto para o controle dos LEDs. Logo após, definimos um array contendo os pinos analógicos nos quais os LDRs estão conectados e a sensibilidade desses LDRs. Valores acima de 950 indicam maior sensibilidade à luz. Ajuste conforme o resultado obtido no código teste, esse passo é necessário para obter a melhor resposta do sensor.
Na linha unsigned long intervaloLedVerde = 2000;, configuramos o tempo em que o LED ficará aceso na cor verde, que neste caso é de 2000ms (2 segundos). Já a variável unsigned long contagemRegressiva = 60000; define o tempo total de duração do jogo em milissegundos, ou seja, 60000ms (1 minuto).
No setup(), o código inicializa a comunicação serial com Serial.begin(9600);, configura os LEDs com leds.begin(); e define o brilho com leds.setBrightness(BRILHO);. Em seguida, usamos a função randomSeed(analogRead(7)); para garantir que as posições aleatórias dos LEDs sejam aleatórias cada vez que o programa for iniciado.
No loop principal, monitoramos o tempo decorrido com millis() e atualizamos a contagem regressiva. Se o tempo se esgotar, o jogo termina e a pontuação é exibida no monitor serial. O LED verde muda de posição a cada intervaloLedVerde para manter o jogo dinâmico
A função mediaLeituraAnalogica(int pino) faz uma leitura média dos valores analógicos dos LDRs para suavizar as flutuações. Quando o valor lido pelo LDR do LED verde excede o limite definido, a pontuação é incrementada, e o LED verde é movido para uma nova posição aleatória com a função trocaLedVerde(unsigned long milissegundosAtuais). Este processo garante que o jogo permaneça interativo e desafiador, incentivando o jogador a reagir rapidamente para marcar pontos. A inclusão de pequenos atrasos com delay(20) ajuda no debounce das leituras dos LDRs, tornando a detecção mais precisa e confiável.
Ao final o código ficará assim:
#include <Adafruit_NeoPixel.h> #include <Wire.h> #define PIN 2 #define NUM_LEDS 6 Adafruit_NeoPixel leds = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800); int ldrPinos[NUM_LEDS] = {A0, A1, A2, A3, A4, A5}; // Pinos dos LDRs int limite = 950; // Limite para os LDRs int ledVerde = -1; // Índice do LED que é verde int pontuacao = 0; // Variável para rastrear pontos unsigned long ultimaTrocaLedVerde = 0; // Tempo em que o LED verde foi trocado pela última vez unsigned long intervaloLedVerde = 5000; // Intervalo em milissegundos para a troca do LED verde unsigned long contagemRegressiva = 60000; // Temporizador em milissegundos unsigned long milissegundosAnteriores = 0; bool jogoTerminado = false; void setup() { Serial.begin(9600); // Inicializa a comunicação serial leds.begin(); leds.show(); // Inicializa todos os pixels como 'desligados' randomSeed(analogRead(7)); // Inicializa a semente aleatória ledVerde = random(NUM_LEDS); // Seleciona um LED aleatório para ser verde } void loop() { if (jogoTerminado) return; unsigned long milissegundosAtuais = millis(); // Manipula o temporizador regressivo if (milissegundosAtuais - milissegundosAnteriores >= 1000) { milissegundosAnteriores = milissegundosAtuais; contagemRegressiva -= 1000; if (contagemRegressiva <= 0) { jogoTerminado = true; Serial.println("Fim de Jogo"); Serial.print("Pontos: "); Serial.println(pontuacao); return; } else { Serial.print("Tempo: "); Serial.println(contagemRegressiva / 1000); } } // Troca o LED verde em intervalos if (milissegundosAtuais - ultimaTrocaLedVerde > intervaloLedVerde) { int novoLedVerde; do { novoLedVerde = random(NUM_LEDS); // Troca o LED verde para outra posição aleatória } while (novoLedVerde == ledVerde); // Garante que a nova posição seja diferente da atual ledVerde = novoLedVerde; ultimaTrocaLedVerde = milissegundosAtuais; } // Atualiza as cores dos LEDs for (int i = 0; i < NUM_LEDS; i++) { leds.setPixelColor(i, (i == ledVerde) ? leds.Color(0, 255, 0) : leds.Color(255, 0, 0)); } leds.show(); // Lê e processa os valores dos LDRs int valorLdrVerde = mediaLeituraAnalogica(ldrPinos[ledVerde]); if (valorLdrVerde > limite) { pontuacao++; Serial.print("Pontos: "); Serial.println(pontuacao); trocaLedVerde(milissegundosAtuais); } delay(20); // Pequeno atraso para debouncing da leitura dos LDRs } int mediaLeituraAnalogica(int pino) { int total = 0; for (int i = 0; i < 5; i++) { total += analogRead(pino); delay(10); } return total / 5; // Média das leituras } void trocaLedVerde(unsigned long milissegundosAtuais) { int novoLedVerde; do { novoLedVerde = random(NUM_LEDS); } while (novoLedVerde == ledVerde); ledVerde = novoLedVerde; ultimaTrocaLedVerde = milissegundosAtuais; }
Quando enviar o código, abra o monitor serial do Arduino IDE para acompanhar a pontuação. Confira o projeto finalizado no vídeo abaixo:
Você pode usar sua criatividade e expandir esse projeto, nós por exemplo, criamos uma estrutura de cano pvc para que o jogo ficasse mais esportivo e ainda mais divertido, veja o vídeo abaixo:
Obrigado a todos e, em caso de dúvidas, deixe seu comentário abaixo!
Graduando em Engenharia da Computação pela Faculdade Independente do Nordeste. Estagiário do setor de desenvolvimento da Casa da Robótica.