Jogo roleta de leds (Shot Game) - arduino jogo #05

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 Resultado de imagem para protoboard 830v

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  3 Pçs 2.2nf X 2kv Capacitor 222 2200 105°c 2kv Capacitores - R$ 21 ... 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 Módulo I2C display LCD Arduino   

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:

Módulo I2C - Detalhes

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

×

Infomações do site / SEO








×

Adicionar Marcadores