Criando Jogos com Arduino 2: Passo a Passo
Desarme a Bomba
Você e seu amigo estão presos em uma sala com uma bomba. A
única forma de sair ileso é cortando o fio correto para desarmar a bomba.
Vocês têm 30 segundos até que a bomba exploda!
Neste projeto, vamos criar o jogo Desarme a Bomba com Arduino.
Trata-se de um jogo de sorte, você deve tentar desarmar a bomba em menos
de 30 segundos, cortando um dos 7 fios conectados a ela.
Há apenas um fio que desarma a bomba, mas há um fio que explode
a bomba instantaneamente, também. Tenha cuidado, se você cortar um dos
outros cinco fios, seu tempo será reduzido pela metade.
Tenha sorte e ninguém explode!
MATERIAIS NECESSÁRIOS
1 x Placa UNO SMD compatível com Arduino UNO ;
1 x Cabo USB ;
1 x Protoboard ;
2 x Resistores de 220 Ω ;
2 x LEDs difusos de 5 mm ;
1 x Buzzer passivo ;
1 x Botões do tipo push button ;
1 x Resistores de 10 kΩ ;
Jumpers macho-macho .
ESQUEMÁTICO DE LIGAÇÃO DOS COMPONENTES
Inicialmente, certifique-se que sua placa UNO esteja desligada. M
onte atentamente o circuito conforme a Figura 1 5 .
Ao montar seu circuito na protoboard preste atenção nos seguintes
pontos:
O terminal positivo do buzzer deve ser conectado à porta digital 3
da placa UNO e o outro terminal deve ser ligado ao GND.
O terminal mais longo de cada LED deve ser conectado ao pino
digital correspondente. O terminal mais curto deve ser conectado ao
terra (GND);
Os jumpers conectados nas portas 6 a 12 do Arduino são
correspondentes aos 7 fios conectados à bomba. Eles devem ser
conectados ao terra (GND);
Conecte o push button com um resistor de 10 k Ω pull-up
(conectado no VCC) no porta Reset do Arduino. Desta forma,
quando o botão for pressionado o Arduino reiniciará.
Figura 15 - Circuito para Projeto Desarme a Bomba.
ELABORANDO O CÓDIGO
Com o circuito montado, vamos a programação do jogo Desarme a
Bomba. Para melhor compreensão o código será explicado passo a passo a
seguir. Neste momento, observe o código abaixo e aproveite para analisar
sua estrutura.
int fio[] = {6, 7, 8, 9, 10, 11, 12}; //Portas do Arduino correspondentes aos fios da bomba
int fioUsado[] = {0, 0, 0, 0, 0, 0, 0}; //Array para guardar o fio já retirado
int ledVerde = 5; //Correspondente ao LED verde
int ledVermelho = 4; //Correspondente ao LED vermelho
int buzzer = 3; //Correspondente ao buzzer
int pino; //Guarda o pino que desarma a bomba
int pinoExplode; //Guarda o pino que explode a bomba
int ledLigaDesliga = 0; //Variável utilizada para guardar o estado do LED (ligado/desligado)
int tempoMaximo = 1800; //Intervalo de tempo inicial da contagem para explosão da bomba
unsigned long millisAnterior = millis (); //variável que recebe o tempo atual em milissegundos
void setup () {
Serial . begin (9600); //Inicializa a comunicação serial
pinMode (ledVerde, OUTPUT ); //Define ledVerde como saída pinMode (ledVermelho , OUTPUT ); //Define ledVermelho como saída pinMode (buzzer, OUTPUT ); //Define buzzer como saída
digitalWrite (ledVerde, LOW ); //Desliga o LED verde digitalWrite (ledVermelho, LOW ); //Desliga o LED vermelho
for ( int i = 0; i < 9; i++) {
pinMode (fio[i], INPUT_PULLUP ); //Define os fios da bomba como entrada e em modo
PULL UP, ou seja, lê HIGH quando não colocamos em nível lógico LOW
}
randomSeed ( analogRead (0)); //Inicializa o gerador de número aleatórios, começando em um
ponto arbitrário
desarmeAbomba(); //Chama a função desarme a bomba
}
void loop () {} //A função loop está vazia, pois queremos que o jogo funcione uma única vez.
Para jogar novamente basta pressionar o botão conectado ao Reset.
//Função responsável pelo funcionamento do jogo
void desarmeAbomba() {
Serial . println ( "-*-*-*-* INICIO -*-*-*-*" ); //Imprime a mensagem no monitor serial
//Sorteio do fio que desarma a bomba
pino = random (0, 6); //Sorteia um número aleatório entre 0 e 6 Serial . print ( "Pino para desarmar a bomba -> " ); //Imprime a mensagem no monitor serial Serial . println (fio[pino]); //Imprime no monitor serial o fio sorteado que desarma a bomba
//Sorteio do fio que explode a bomba
do {
pinoExplode = random (0, 6); //Sorteia novamente um número aleatório entre 0 e 6 Serial . print ( "Pino que explode a bomba -> " ); //Imprime a mensagem no monitor serial Serial . println (fio[pinoExplode]); //Imprime no monitor serial o fio sorteado para explodir a
bomba
} while (pinoExplode == pino); //verifica se o fio que explode a bomba é igual ao que desarma a
bomba. Se sim, repete o laço e sorteia um novo número
//Leitura e verificação dos pinos
do {
for ( int i = 0; i < 7; i++) { //for que percorre todas as posições do array
if ( digitalRead (fio[i]) == HIGH && fioUsado[i] == 0) { //Verifica se o pino foi retirado ou
se ele já foi retirado alguma vez
fioUsado[i] = 1; //Define 1 na posição do vetor para gravar que o pino foi retirado
if (pinoExplode == i) { //Verifica se o fio retirado é igual ao fio que explode a bomba
Serial . println ( "Boooom!! A bomba explodiu -*-*-*-*-*" ); //Imprime a mensagem no
monitor serial
}
else {
if (pino == i) { //Verifica se o fio retirado é igual ao fio que desarma a bomba
Serial . println ( "Ufa, essa foi por um fio. Voce conseguiu desarmar a bomba" );
//Imprime a mensagem no monitor serial
} else { //Se o fio retirado não for igual ao fio que desarma ou explode a bomba
Serial . println ( "Pino errado, tenha cuidado!" ); //Imprime a mensagem no monitor serial tempoMaximo = tempoMaximo / 2; //Reduz o tempo de jogo pela metade
}
}
}
}
if (( millis () - millisAnterior) > tempoMaximo) { //Verifica se o tempo que passou é maior que
o intervalo de tempo determinado para explosão da bomba
millisAnterior = millis (); //Atualiza para o tempo atual tempoMaximo = tempoMaximo - 50; //Reduz o intervalo de tempo em 50 milissegundos
//Pisca LED verde
if (ledLigaDesliga) {
digitalWrite (ledVerde, LOW );
ledLigaDesliga = 0;
} else {
ledLigaDesliga = 1;
digitalWrite (ledVerde, HIGH );
}
tone (buzzer, 493, 100); //Beep para informar que o tempo está diminuindo
}
if (tempoMaximo <= 0) { //Se o tempo máximo for menor ou igual a zero, finaliza o jogo
Serial . println ( "FIM .............." ); //Imprime a mensagem Fim no monitor serial digitalWrite (ledVermelho, HIGH ); //O LED vermelho é acionado, indicando que a bomba
explodiu
tone (buzzer, 493, 1000); //Beep que indica que a bomba explodiu delay (1000); //Intervalo para tocar o buzzer break ; //Se o tempo máximo for menor ou igual a zero para o laço de repetição
}
//Efeito do buzzer e LEDs quando o jogador consegue desarmar a bomba
if (fioUsado[pino] == 1) { //Verifica se o fio que desarma a bomba foi retirado
tone (buzzer, 262, 600); delay (300); digitalWrite (ledVerde, LOW ); tone (buzzer, 294, 400); delay (350); digitalWrite (ledVerde, HIGH ); tone (buzzer, 330, 300); delay(350); digitalWrite (ledVerde, LOW ); tone (buzzer, 349, 300); delay (350); digitalWrite (ledVerde, HIGH ); tone (buzzer, 392, 300); delay (300); digitalWrite (ledVerde, LOW ); tone (buzzer, 440, 300); delay (300); digitalWrite (ledVerde, HIGH ); tone (buzzer, 493, 300); delay (200); digitalWrite (ledVerde, LOW ); break ;
}
//Efeito do buzzer e LEDs quando o jogador explode a bomba
if (fioUsado[pinoExplode] == 1) { //Verifica se o fio que explode a bomba foi retirado
digitalWrite (ledVermelho, HIGH );
tone (buzzer, 493, 1000);
delay (1000);
break ;
}
} while (1);
}
Para melhor compreensão do código acompanhe os seguintes passos:
1. Declarar as variáveis
Iniciamos a programação declarando as variáveis correspondentes
aos fios da bomba. Os fios conectados às portas 6, 7, 8, 9, 10, 11 e 12 foram
declarados no array fio[ ] .
Um array é uma lista de variáveis que podem ser acessadas com um
número índice. As variáveis que encontramos até agora tinham apenas um
único valor, usando um array podemos criar uma variável com um conjunto
de valores que podem ser acessados dando sua posição dentro da lista.
Em seguida, declaramos o array fioUsado[ ] , que será utilizado para
armazenar qual fio da bomba já foi retirado ou cortado.
Logo após, declaramos as variáveis ledVerd e , ledVermelho e
buzzer , correspondentes aos pinos 5, 4 e 3, em que os LEDs e o buzzer
estão conectados, respectivamente.
Declaramos também as variáveis pin o , para armazenar o fio que
desarma a bomba; pinoExplod e , para armazenar o fio que explode a
bomba; ledLigaDeslig a , para guardar o estado do LED; tempoMaxim o ,
para guardar o tempo até que a bomba exploda; e millisAnterio r , para
retornar o tempo passado desde que o jogo iniciou.
2. Inicialização da comunicação serial e configurações iniciais
A comunicação serial foi inicializada por meio da instrução: Serial .
begin (9600) ; .
Os pinos de 4 e 5, conectados aos LEDs, e o pino 3, conectado ao
buzzer, foram configurados como saída ( OUTPU T ).
Para iniciar o jogo com os LEDs desligados, os definimos como LO
W .
Também na função setup ( ) , definimos todas as portas em que os
fios estão conectados como entrada pull-up. Fizemos isso, percorrendo os
elementos do array e os configurando como entrada pull-up (
INPUT_PULLU P ) com o auxílio da estrutura de repetição fo r .
O Arduino possui resistores pull-up internos que podemos habilitar e
usar em nossos projetos. Ao definir um pino como INPUT_PULLU P ,
garantimos que seu estado inicial seja igual a HIG H .
Os pinos correspondentes aos fios da bomba foram definidos com
INPUT_PULLUP e conectados ao GND do Arduino. Assim, quando um fio
for retirado ou cortado, seu estado mudará de LO W para HIG H .
3. Inicialização do gerador de números aleatórios
O gerador de números aleatórios foi inicializado através da função
randomSeed ( analogRead (0)) ; que utiliza como entrada aleatória a leitura
analógica do pino A0.
4. Chamar a função desarmeAbomba()
Ainda dentro da função setup ( ) , chamamos a função
desarmeAbomba( ) , responsável pelo funcionamento do jogo. Assim, o
jogo funcionará apenas uma vez.
Para que o jogo seja iniciado novamente, o jogador deverá
pressionar o botão conectado ao Reset do Arduino. Por esta razão, a função loop ( ) encontra-se vazia.
5. Sorteio do fio que desarma a bomba
Iniciamos a função desarmeAbomba( ) sorteando um número
aleatório entre 0 e 6. Para realização do sorteio usamos a função random ()
; que gera números aleatórios. Dentro dessa função incluímos o limite
mínimo e máximo do valor aleatório (0, 6).
Este número sorteado foi utilizado como índice para acessar o array
que guarda os pinos do Arduino correspondente aos fios da bomba. Deste
modo, se o número sorteado for igual ao número zero, o fio que desarma a
bomba está conectado à porta digital 6, se o número sorteado for igual a 1, o
fio que desarma a bomba está conectado à porta digital 7; e assim por
diante.
6. Sorteio do fio que explode a bomba e verificar se este fio é diferente do
fio que desarma a bomba
Para sortear o fio que explode a bomba também usamos a função
random () ; . Dentro dessa função incluímos o limite mínimo e máximo do
valor aleatório (0, 6).
Novamente, o número sorteado foi utilizado como índice para
acessar o array que guarda os pinos do Arduino correspondente aos fios da
bomba.
Por meio da estrutura de repetição d o .. . whil e , verificamos se o
fio sorteado para explodir a bomba é igual ao fio sorteado para desarmá-la
( pinoExplode == pin o ). Se sim, o sorteio será realizado novamente.
7. Leitura e verificação dos pinos
Com o auxílio da estrutura de repetição fo r percorremos todas as
posições do array fio[ ] , realizando a sua leitura. Caso algum fio tenha sido
retirado ou cortado, sua posição no array fioUsado[ ] será alterado para 1.
Em seguida, verificamos se o fio retirado é igual o fio que explode a
bomba. Se sim, a mensagem "Boooom!! A bomba explodiu -*-*-*-*-*" será
impressa no monitor serial. Senão, comparamos se ele é igual ao fio que
desarma a bomba. Se sim, a mensagem "Ufa, essa foi por um fio. Você
conseguiu desarmar a bomba" será mostrada no monitor serial. Se não, o
monitor serial imprime a mensagem "Pino errado, tenha cuidado!" e o
tempo para desarmar a bomba será reduzido pela metade.
8. Realizar a contagem do tempo usando a função millis ( ) e
decrementar o tempo
A função millis ( ) retorna o número de milissegundos passados
desde que a placa microcontroladora começou a executar o programa.
Usamos essa função para realizar a contagem do tempo.
A variável millisAnterio r foi utilizada para guardar o tempo
anterior. Verificamos se millis () - millisAnterior é maior que o intervalo de
tempo determinado para a explosão da bomba. Se sim, a variável
millisAnterio r é atualizada com o novo valor de millis () e o intervalo de
tempo será reduzido em 50 milissegundos. Para sinalizar que o tempo está
reduzindo o LED verde pisca e o buzzer emite o beep.
9. Verificar se o tempo de jogo acabou
Se o intervalo de tempo máximo para desarmar a bomba acabar (
tempoMaximo <= 0 ), o acionamento do LED vermelho e o beep longo do
buzzer sinalizarão que a bomba explodiu.
10. Verificar se o fio que desarma a bomba foi retirado
Usando a condiciona l i f , verificamos se o fio retirado ou cortado
foi igual ao pino que desarma a bomba ( fioUsado[pino] == 1 ). Se sim, o
LED verde continua piscando e o buzzer emite uma pequena melodia.
11. Verificar se o fio que explode a bomba foi retirado
Usando a condiciona l i f , verificamos se o fio retirado ou cortado
foi igual ao pino que explode a bomba ( fioUsado[pinoExplode] == 1 ). Se
sim, o LED vermelho é acionado e o buzzer emite um beep longo.
TINKERCAD
Para melhor visualizar o circuito deste projeto, basta se acessar o
seguinte link : www.blogdarobotica.com/tinkercad-circuitobomba .
Para simular a programação do projeto, acesse o seguinte link:
www.blogdarobotica.com/tinkercad-desarmeabomba
Observação : No Tinkercad o botão foi inserido apenas para que a
simulação do código pudesse acontecer. Quando pressionado, botão
representa o fio retirado ou cortado.
OceanofPDF.com