Início
/
Projetos Arduino
/
Jogos
/
Jogo roleta de leds (Shot Game) - arduino jogo #05
Jogo roleta de leds (Shot Game) - arduino jogo #05
Angelo Luis Ferreira | 08/02/2021
Acessos: 8.883
Jogo 5 : Shot game - roleta de leds
Objetivo
Neste projeto vamos criar um jogo simples, divertido e que requer apenas uma pessoa para jogar. O objetivo do jogo é acertar o led verde ou pelo menos um dos leds laranja ou amarelo. Para acertar um led é necessário clicar o botão (push button) no momento em que o led estiver aceso. Cada partida terá 5 jogadas e a pontuação será a soma dos pontos de cada jogada, sendo: led verde = 50 pontos, led laranja = 20 pontos e led amarelo = 10 pontos. A velocidade do jogo também aumenta a cada jogada. Portanto fique ligado e bata o seu recorde!
Aplicação
Para fins didáticos e diversão.
Componentes necessários
Referência
|
Componente
|
Quantidade
|
Imagem
|
Observação
|
Protoboard |
Protoboard 830 pontos |
1 |
|
No mínimo utilizar protoboard com 830 pontos
|
Jumpers |
Kit cabos ligação macho / macho |
1 |
|
|
Led 5mm |
Led 5mm |
9 |
|
Utilizar de preferência: 4 leds vermelhos, 2 leds amarelos, 2 leds laranjas e 1 led verde |
Resistor |
Resistor de 150 Ω maior |
9 |
|
Se precisar usar outros valores, calcule o resistor apropriado para o led ou barra grafica utilizada. |
Push Button |
Push button 6X6X5mm |
1 |
|
|
Capacitor Cerâmico |
Capacitor Cerâmico 2nF a 10nF |
1 |
|
O capacitor será utilizado para estabilizar a função do botão (push button) no caso de se utilizar interrupção externa. |
Display LCD |
Display LCD 16X2 com pinos soldados |
1 |
|
LCD que utilize o controlador HD44780 (veja na descrição ou datasheet do componente)
O display poderá ser de qualquer cor (fundo verde, azul ou vermelho)
|
Módulo I2C para display LCD |
Módulo I2C com CI PCF8574 |
1 |
|
O módulo I2C poderá vir separado ou já soldado no display LCD
(datasheet)
Se você não possui um módulo I2C para display LCD, poderá adaptar o projeto para o display LCD sem o adaptador.
|
Arduino UNO |
Arduino UNO R3 |
1 |
|
Você poderá utilizar uma placa Arduino UNO original ou similar
|
Montagem do Circuito
Conecte os componentes no Protoboard como mostra a figura abaixo. Verifique cuidadosamente os cabos de ligação antes de ligar seu Arduino. Lembre-se que o Arduino deve estar totalmente desconectado da força enquanto você monta o circuito.
Atenção
1) Lembre-se que o LED tem polaridade: O terminal maior tem polaridade positiva e o lado do chanfro tem polaridade negativa.
2) Determinamos o valor do resistor através da tabela prática: Tabela prática de utilização de leds 3mm e 5mm. Entretanto, o mais correto é sempre verificar o datasheet do fabricante do LED para você ter os exatos valores de tensão e corrente do mesmo - leia Leds ligados em série e em paralelo.
3) Monte os botões (push button) sem o resistor, pois através da programação vamos habilitar o resistor pull-up interno do Arduino. Desta forma, quando o botão estiver pressionado, o Arduino retornará "LOW" ou "0". Veja o projeto Projeto 02b - Led apaga com push button pressionado (pull-up interno do Arduino) ou assista o vídeo Arduino: Botão e Resistor de Pull Up Interno
4) Como vamos configurar uma interrupção externa neste projeto, precisaremos utilizar um capacitor cerâmico para evitar o efeito "bouncing" no push button.
4.1. Como a interrupção externa gera uma ação muito rápida, somente o delay utilizado no software não será suficiente para evitar as oscilações geradas pelo efeito "bouncing". Recomendo utilizar um capacitor cerâmico de 2,0nF a 10nF na montagem do botão. Utilizamos no nosso projeto um capacitor de 2,2nF. Veja abaixo como conectar o capacitor cerâmico.
4.2. O efeito "bouncing" ocorre sempre quando trabalhamos com chaves mecânicas. Ele é responsável por gerar equivocadamente sinais como se ocorressem diversos acionamentos em um pequeno intervalo de tempo:
5.2.1. Veja no gráfico abaixo o exemplo deste efeito. Observe que ao pressionarmos um botão, por exemplo, ocorre algumas oscilações rápidas com idas e vindas do nível lógico alto e do nível lógico baixo, antes da estabilização das partes mecânicas do componente. Estas oscilações podem gerar informações indevidas ao nosso microcontrolador, que interpretará que o botão foi pressionado rapidamente várias vezes, quando na verdade foi pressionado apenas um vez.
4.3. Debouncing são técnicas que utilizamos para resolver este problema. O "debouncing" consiste basicamente em atrasar o código, através do software, com o uso da função delay(), função delayMicroseconds(), função millis(), ou através do hardware, com a instalação de um capacitor ou ainda através de bibliotecas específicas.
4.3.1. Como configuramos uma interrupção externa para atuar em uma chave mecânica (push button, por exemplo), o sinal será enviado diretamente no pino do microcontrolador quando pressionamos o botão. Por isso, para eliminarmos os efeitos do "bouncing" de forma mais eficiente precisamos criar um atraso primeiro no hardware, usando o capacitor cerâmico e depois no software, usando a função delayMicroseconds() que funcionará em uma ISR (Interrupt Service Routine, ou Rotina de Serviço de Interrupções em português).
5. Como vamos utilizar neste projeto efeitos de iluminação sequencial por leds e interrupção externa, recomendo que leia os seguintes tutoriais:
6. Neste projeto vamos utilizar um display LCD 16x2 com controlador HD44780, que se adapta aos mais diversos projetos com vários modelos de placas e microcontroladores. Este display possui 16 colunas por 2 linhas com backlight (luz de fundo) verde, azul ou vermelha e tem 16 pinos para a conexão. Atenção: Utilize um display LCD com os pinos soldados.
7. Para a montagem do display com adaptador, entenda a estrutura do módulo I2C para display LCD 16x2 / 20X4:
7.1. Na lateral do adaptador encontramos 4 pinos, sendo: 2 pinos para alimentação (Vcc e GND) e 2 pinos para conexão com a interface I2C (SDA e SCL) que deverão estar conectados nos pinos analógicos A4 (SDA) e A5 (SCL) do Arduino Uno ou nos pinos A20 (SDA) e A21 (SCL) do Arduino Mega 2560. Veja a tabela abaixo com onde temos as principais placas Arduino e suas conexões com o I2C.
7.2. Para controlar o contraste do display, utilize o potenciômetro de ajuste de contraste. O jumper lateral, quando utilizado, permite que a luz do fundo (backlight) seja controlada pelo programa ou permaneça apagada.
7.3. A seleção de endereço do adaptador I2C para display LCD, na maioria dos módulos fornecidos no mercado já vêm configurados com o com o endereço 0x27. Se você não sabe qual endereço que o seu módulo I2C e/ou módulo RTC DS3231 está configurado, baixe o seguinte "sketch":
DOWNLOAD - I2C_scanner.ino
7.3.1 Após instalar e rodar o sketch acima, abra o monitor serial que mostrará qual é o endereço que o seu módulo I2C e o módulo RTC DS3231 está configurado:
7.3.2 Nos casos em que módulo I2C estiver configurado com uma faixa de endereços diferente do endereço 0X27 altere a alinha de programação -> LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3, POSITIVE); com o endereço correto.
7.4. Para saber mais sobre a montagem e utilização de display LCD com módulo I2C leia: Projeto 48 - Como controlar um display LCD com o módulo I2C.
8. Veja abaixo como ficou a montagem do nosso projeto:
Incluindo biblioteca LiquidCrystal_I2C
Atenção: Caso você opte pela utilização do display de LCD sem o módulo I2C, siga os procedimentos do Projeto 38 - Controlando um display LCD (instalação e comandos básicos) e não instale a biblioteca abaixo.
Para que o módulo I2C funcione corretamente é necessário adicionarmos a biblioteca LiquidCrystal_I2C no IDE do Arduino. Uma das grandes vantagens das placas Arduino é a diversidade de bibliotecas disponíveis que podem ser utilizadas em seus programas. Estas bibliotecas podem ser criadas para a linguagem "C" ou especificamente para o Arduino, reduzindo drasticamente o tempo gasto com programação. Veja a tabela Coletânea de bibliotecas para sensores.
Download dos arquivos da biblioteca LiquidCrystal_I2C
DOWNLOAD - NewliquidCrystal_1.3.4.zip
Para saber detalhes desta biblioteca clique aqui.
Instalando a biblioteca pelo IDE do Arduino
Após fazer o download do arquivo NewliquidCrystal_1.3.4.zip com todos os arquivos da biblioteca compactados no formato zip, abra o IDE do Arduino e siga o tutorial:Como incluir uma biblioteca no IDE do Arduino.
Utilizando a biblioteca LiquidCrystal_I2C
Para instalação e utilização da biblioteca para o módulo I2C como comunicação para um display LCD siga o tutorial: Projeto 48 - Como controlar um display LCD com o módulo I2C .
Código do Projeto (Sketch)
1. Faça o download e abra o arquivo jogo5.ino no IDE do Arduino:DOWNLOAD - jogo5.ino
Obs. 1: Nos casos em que módulo I2C estiver configurado com um endereço diferente do endereço 0X27, altere a alinha de programação -> LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3, POSITIVE); com o endereço correto. - Veja o tutorial Projeto 48 - Como controlar um display LCD com o módulo I2C
Obs. 2: Se estiver utilizando um display de LCD 20 X 4, altere o comando da linha 45 para lcd.begin (20,4);
Obs. 3: Se não possuir o módulo I2C utilize apenas o display LCD conforme Projeto 38 - Controlando um display LCD (instalação e comandos básicos).
2. Se preferir, copie e cole o código abaixo no IDE do Arduino:
/*******************************************************************************
*
* Jogo 5 - Jogo da Roleta (shot game)
* Adaptado por Angelo Luis Ferreira
* 05/02/2021
* http://squids.com.br/arduino
*
*******************************************************************************/
// =======================================================================
// Definições
// led pino 7 = verde (50 pontos) - currentLED=4
// led pino 6 e led pino 8 = amarelo (20 pontos) - currentLED = 3 e 5
// led pino 5 e led pino 9 = laranja (10 pontos) - currentLED = 2 e 6
// demais leds = vermelho (0 pontos)
//
// =====================================================================
// biblioteca LCS com I2C
#include
// Inicializa o display no endereco 0x27
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3, POSITIVE);
// hardware
byte ledPin[] = {3,4,5,6,7,8,9,10,11}; // leds
byte butPin = 2; // push button
// variáveis
int shot = 0;
boolean gameStatus = false;
boolean gameOverStatus = false;
byte currentLED = 0;
int dirFlag = 1;
int points = 0;
int record = 0;
void setup(){
// define hardware - entradas e saídas
for (byte i = 0; i<9; i++) {
pinMode(ledPin[i], OUTPUT);
}
pinMode(butPin, INPUT_PULLUP);
// inicia monitor serial e display LCD
Serial.begin(9600);
lcd.begin (16,2);
// inicia interrupção externa
attachInterrupt(digitalPinToInterrupt(butPin), buttonClick, FALLING);
// tela inicial
showStart(); // exibe display para iniciar jogo
allLedsOn(); // acende todos os leds
Serial.println("================================");
Serial.println("Novo Jogo - Clique para iniciar");
} // end setup
void loop() {
if (!gameStatus) {
if (gameOverStatus == true) {
gameOver();
} else if (gameOverStatus == false) {
allLedsOff();
checkButton();
}
} else if (gameStatus){
moveLed();
}
} //end loop
// ========================== JOGANDO =====================================
void moveLed() {
showGame(); // exibe pontos no lcd
digitalWrite(ledPin[currentLED], HIGH); // acende o LED atual
if (shot >0 && shot<6) delay(100/(6-shot)); // dificuldade do jogo
currentLED += dirFlag; // incrementa de acordo com o valor de direction
allLedsOff();
// altera a direção se tivermos atingido o fim
if (currentLED == 9) dirFlag = -1;
if (currentLED == 0) dirFlag = 1;
if (shot<=0) { // sem vidas
gameStatus = false;
gameOverStatus = true;
}
}
// ao clicar o botão durante o jogo
void buttonClick() {
// calcula pontuação
if (currentLED == 4) points += 50;
if (currentLED == 3 || currentLED == 5) points += 20;
if (currentLED == 2 || currentLED == 6) points += 10;
showGameMonitor(); // exibe pontos no monitor
// calcula jogadas
if (gameStatus == true) {
shot--;
}
delayMicroseconds(50000); // debouncing
}
void showGameMonitor() {
if (shot > 0) {
Serial.print(currentLED); // exibe o led que foi clicado
if (currentLED == 4) {
Serial.println(" | Acertou o Led verde -> 50 pontos - SHOT!!!");
} else if (currentLED == 3 || currentLED == 5){
Serial.println(" | Acertou o led laranja -> 20 pontos");
} else if (currentLED == 2 || currentLED == 6){
Serial.println(" | Acertou o led amarelo -> 10 pontos");
} else Serial.println(" | Acertou o led vermelho -> 0 pontos");
}
}
// exibe no lcd
void showGame(){
// pontos
lcd.setCursor(0,0);
lcd.print("Pontos: ");
lcd.setCursor(9,0);
lcd.print(points);
// shot
lcd.setCursor(0,1);
lcd.print("Shot: ");
lcd.setCursor(6,1);
lcd.print(shot);
// record
lcd.setCursor(9,1);
lcd.print("R= ");
lcd.setCursor(12,1);
lcd.print(record);
}
//================= Tela inicialização ======================
// clique para iniciar jogo
void showStart() {
for (byte i=0;i<3;i++) {
lcd.setBacklight(HIGH);
lcd.setCursor(2,0);
lcd.print("CLIQUE PARA");
lcd.setCursor(1,1);
lcd.print("INICIAR O JOGO!");
delay(300);
lcd.setBacklight(LOW);
delay(300);
}
lcd.setBacklight(HIGH);
}
// acende tods leds
void allLedsOn() {
for (byte i = 0; i<9; i++) {
digitalWrite(ledPin[i], HIGH);
}
delay(1000);
}
// apaga todos leds
void allLedsOff() {
for (byte i = 0; i<9; i++) {
digitalWrite(ledPin[i], LOW);
}
}
// verifica se o botão foi acionado
void checkButton() {
if (!digitalRead(butPin) && gameStatus == false) {
if(shot == 0) {
shot = 5;
gameStatus = true;
lcd.clear();
}
while(!digitalRead(butPin)) {}
delay(50);
}
}
//================ GAME OVER =================
void gameOver() {
// imprime no monitor serial
Serial.print("Game Over | ");
Serial.print("Seus Pontos: ");
Serial.println(points);
if (points > record) Serial.println(" *** NOVO RECORDE *** ");
Serial.println("================================");
Serial.println("Novo Jogo - Clique para iniciar");
// imprime no display
lcd.clear();
lcd.setCursor(3,0);
lcd.print("GAME OVER");
lcd.setCursor(0,1);
lcd.print("SEUS PONTOS: ");
lcd.setCursor(12,1);
lcd.print(points);
delay(5000);
lcd.clear();
// seta record
if (points > record) {
record = points;
recordShow();
} else {
// tela inicial
showStart(); // exibe display para iniciar jogo
allLedsOn(); // acende todos os leds
}
// set variáveis
shot = 0;
gameStatus = false;
gameOverStatus = false;
currentLED = 0;
points = 0;
dirFlag = 1;
}
// ==================== Record Show ================
void recordShow() {
for (byte i=0;i<3;i++) {
lcd.setBacklight(HIGH);
lcd.setCursor(1,0);
lcd.print("*NOVO RECORD*");
lcd.setCursor(2,1);
lcd.print(points);
lcd.setCursor(6,1);
lcd.print(" Pontos");
delay(500);
lcd.setBacklight(LOW);
delay(500);
}
lcd.setBacklight(HIGH);
delay(2000);
lcd.clear();
// tela para inicializar jogo
lcd.setCursor(2,0);
lcd.print("CLIQUE PARA");
lcd.setCursor(1,1);
lcd.print("INICIAR O JOGO!");
allLedsOn();
delay(500);
}
Vídeo
Como o projeto deve funcionar
1. Ao executar o programa, aparecerá no display a mensagem "Clique para iniciar o jogo".
2. Para acompanhar qual led foi acionado, abra também o Monitor Serial.
3. Clique no botão (push button) para iniciar o jogo.
3.1. Os leds se acenderão um a um, da esquerda para a direita e depois da direita para a esquerda (sequência vai e volta).
3.2. O objetivo do jogo é clicar rapidamente no momento exato quando o led verde esteja aceso.
3.2.1. Se você acertar (clicar) o led verde, ganhará 50 pontos;
3.2.2. Se acertar os leds próximos, amarelo, 20 pontos e o laranja 10 pontos.
3.3. Cada partida possui 5 jogadas (shots), ou seja, você poderá tentar acertar o led verde, amarelo ou laranjado 5 vezes.
3.4. A velocidade da sequência de leds irá aumentando a cada jogada.
3.5. A pontuação do jogo será a soma dos pontos que você recebeu por cada led acertado.
3.6. A pontuação será mostrada no display lcd, e no Monitor Serial como mostra a figura abaixo:
3.7. No display LCD vamos visualizar os pontos acumulados na partida, o número de jogada faltantes e o recorde a ser batido.
4. O recorde será zerado quando você reiniciar ou desligar o Arduino.
Créditos
Este projeto foi uma adaptação do projeto: Led Roulette Game
Desafios
Com base neste projeto, resolva os seguintes desafios: Desafio 84
O anúncio abaixo ajuda a manter o Squids Arduino funcionando
Comentários