Last active
May 23, 2022 17:30
-
-
Save wkoch/1c23fd09d9a0974eb2c17297798b5b25 to your computer and use it in GitHub Desktop.
Revisions
-
wkoch revised this gist
May 23, 2022 . 1 changed file with 18 additions and 20 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -25,14 +25,10 @@ #define PIEZO2 7 // Parâmetros do jogo #define RODADAS_ATE_SER_CAMPEAO 10 // Número de rodadas para vencer o Jogo. #define TEMPO_DE_RESPOSTA_JOGADOR 3000 // Tempo para pressionar um botão antes que o jogo acabe. 3 segundos // Variáveis de estado do jogo byte tabuleiro[32]; //Salva a combinação de botões à medida que avançamos byte rodadas = 0; //Conta o número de rodadas de sucesso que o jogador fez @@ -52,7 +48,7 @@ void setup() saida(PIEZO1); saida(PIEZO2); toqueInicial(); // Ao ligar toque a música vencedor if (checaBotao() == AMARELO) tocarMusica(); } @@ -66,17 +62,11 @@ void loop() controlaLEDs(DESLIGA); // Desligue os LEDs aguarde(250); // Roda o jogo de memória e recebe resultado if (jogoDaMemoria() == true) toqueVencedor(); // Ganhou, toca som de vitória else toquePerdedor(); // Perdeu, toca som de derrota } //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= @@ -249,7 +239,7 @@ void emitirSom(int duracao_milisegundos, int pausa_microsegundos) } // Reproduzir o som e as luzes do vencedor void toqueInicial(void) { controlaLEDs(VERDE | AZUL); somVencedor(); @@ -261,6 +251,12 @@ void toqueVencedor(void) somVencedor(); } void toqueVencedor(void) { toqueInicial(); tocarMusica(); } // Som vencedor // Este é apenas um som (chato) único que criamos, não há mágica nisso void somVencedor(void) @@ -364,10 +360,12 @@ void tocarMusica(void) // iterar sobre as notas da melodia: for (int i = 0; i < limite; i++) { mudaLED(); int duracao = 1000 / tempos[i]; // Velocidade da música tone(PIEZO1, notas[i], duracao); aguarde(duracao * 1.3); // Pausa entre notas noTone(PIEZO1); if(checaBotao() != NADA_ESCOLHIDO) break; } } } -
wkoch revised this gist
May 23, 2022 . 3 changed files with 89 additions and 699 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,100 +0,0 @@ This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,37 +1,5 @@ #define entrada(x) pinMode(x, INPUT_PULLUP) #define saida(x) pinMode(x, OUTPUT) #define aguarde(x) delay(x) #define DESLIGA 0 // Usado para controlar LEDs @@ -53,134 +21,38 @@ #define BOTAO_AMARELO 6 // Definições dos pinos do Buzzer #define PIEZO1 4 #define PIEZO2 7 // Parâmetros do jogo #define RODADAS_ATE_SER_CAMPEAO 13 // Número de rodadas para vencer o Jogo. #define TEMPO_DE_RESPOSTA_JOGADOR 3000 // Tempo para pressionar um botão antes que o jogo acabe. 3 segundos #define MODO_JOGO 0 #define MODO_MUSICAL 1 // Variáveis de estado do jogo byte modoDeJogo = MODO_JOGO; //Por padrão, vamos jogar o jogo da memória byte tabuleiro[32]; //Salva a combinação de botões à medida que avançamos byte rodadas = 0; //Conta o número de rodadas de sucesso que o jogador fez void setup() { // Configuração dos pinos de entradas e saídas entrada(BOTAO_VERMELHO); entrada(BOTAO_VERDE); entrada(BOTAO_AZUL); entrada(BOTAO_AMARELO); saida(LED_VERMELHO); saida(LED_VERDE); saida(LED_AZUL); saida(LED_AMARELO); saida(PIEZO1); saida(PIEZO2); toqueVencedor(); // Ao ligar toque a música vencedor if (checaBotao() == AMARELO) tocarMusica(); } @@ -195,13 +67,11 @@ void loop() aguarde(250); if (modoDeJogo == MODO_MUSICAL) tocarMusica(); if (modoDeJogo == MODO_JOGO) { // Roda o jogo de memória e recebe resultado if (jogoDaMemoria() == true) toqueVencedor(); // Ganhou, toca som de vitória else @@ -216,38 +86,33 @@ void loop() // Retorna false se o jogador perde ou true se o jogador ganhar boolean jogoDaMemoria(void) { randomSeed(millis()); // Semeia o gerador aleatório rodadas = 0; // Redefinir o jogo para o começo while (rodadas < RODADAS_ATE_SER_CAMPEAO) { adicionaJogada(); // Adicione um botão aos movimentos atuais e reproduza-os apresentaJogadas(); // Jogue de volta o tabuleiro do jogo atual // Em seguida, solicite ao jogador que repita a sequência. for (byte atual = 0 ; atual < rodadas ; atual++) { byte opcao = aguardarBotao(); // Veja o botão que o usuário pressiona if (opcao == 0) return false; // Se a espera expirar, o jogador perde if (opcao != tabuleiro[atual]) return false; // Se a escolha estiver incorreta, o jogador perde } aguarde(1000); // O jogador estava correto, espera antes de jogar } return true; // O jogador cumpriu todas as rodadas para ganhar! } // Reproduz o conteúdo atual dos movimentos do jogo void apresentaJogadas(void) { for (byte atual = 0 ; atual < rodadas ; atual++) { emitirTom(tabuleiro[atual], 150); // Aguarde algum tempo entre a reprodução do botão // Encurtar isso para tornar o jogo mais difícil @@ -256,11 +121,11 @@ void playMoves(void) } // Adiciona um novo botão aleatório à sequência do jogo void adicionaJogada(void) { byte novoBotao = random(0, 4); //min (incluido), max (excluido) // Temos que converter esse número, 0 até 3, para cor if(novoBotao == 0) novoBotao = VERMELHO; else if(novoBotao == 1) novoBotao = VERDE; else if(novoBotao == 2) novoBotao = AZUL; @@ -299,24 +164,21 @@ void controlaLEDs(byte leds) // Aguarde até que um botão seja pressionado. // Retorna uma das cores do LED (LED_VERMELHO, etc.) se for bem-sucedida, 0 se expirar byte aguardarBotao(void) { long inicio = millis(); // Lembre-se da hora em que começamos o loop // Enquanto tempo decorrido desde a definição da variável início for menor que limite do jogo: while ( (millis() - inicio) < TEMPO_DE_RESPOSTA_JOGADOR) // Faz um loop até que passe o tempo limite { byte botao = checaBotao(); if (botao != NADA_ESCOLHIDO) { emitirTom(botao, 150); // Reproduzir o botão que o usuário acabou de pressionar while(checaBotao() != NADA_ESCOLHIDO) ; // Agora vamos esperar que o usuário libere o botão aguarde(10); // Isso ajuda com toques duplos acidentais return botao; } } @@ -340,68 +202,68 @@ byte checaBotao(void) // Verde, superior direito: 880Hz - 1.136ms - pulso de 0.568ms // Azul, inferior esquerdo: pulso de 587.33Hz - 1.702ms - 0.851ms // Amarelo, inferior direito: 784Hz - 1,276ms - pulso de 0,638ms void emitirTom(byte qual, int duracao_milisegundos) { controlaLEDs(qual); // Ligue um dado LED // Reproduz o som associado ao LED fornecido switch(qual) { case VERMELHO: emitirSom(duracao_milisegundos, 1136); break; case VERDE: emitirSom(duracao_milisegundos, 568); break; case AZUL: emitirSom(duracao_milisegundos, 851); break; case AMARELO: emitirSom(duracao_milisegundos, 638); break; } controlaLEDs(DESLIGA); // Desligue todos os LEDs } // Alterna o buzzer a cada pausa_microsegundos, por uma duração de duracao_milisegundos. void emitirSom(int duracao_milisegundos, int pausa_microsegundos) { // Converter tempo total de reprodução de milissegundos para microssegundos long comprimento_microsegundos = duracao_milisegundos * (long)1000; // Faz um loop até que o tempo restante de reprodução seja menor que uma única pausa_microsegundos while (comprimento_microsegundos > (pausa_microsegundos * 2)) { comprimento_microsegundos -= pausa_microsegundos * 2; // Diminui o tempo de jogo restante // Alterna a campainha em várias velocidades digitalWrite(PIEZO1, LOW); digitalWrite(PIEZO2, HIGH); delayMicroseconds(pausa_microsegundos); digitalWrite(PIEZO1, HIGH); digitalWrite(PIEZO2, LOW); delayMicroseconds(pausa_microsegundos); } } // Reproduzir o som e as luzes do vencedor void toqueVencedor(void) { controlaLEDs(VERDE | AZUL); somVencedor(); controlaLEDs(VERMELHO | AMARELO); somVencedor(); controlaLEDs(VERDE | AZUL); somVencedor(); controlaLEDs(VERMELHO | AMARELO); somVencedor(); } // Som vencedor // Este é apenas um som (chato) único que criamos, não há mágica nisso void somVencedor(void) { // Alterna a campainha em várias velocidades for (byte x = 250 ; x > 70 ; x--) @@ -423,16 +285,16 @@ void winner_sound(void) void toquePerdedor(void) { controlaLEDs(VERMELHO | VERDE); emitirSom(255, 1500); controlaLEDs(AZUL | AMARELO); emitirSom(255, 1500); controlaLEDs(VERMELHO | VERDE); emitirSom(255, 1500); controlaLEDs(AZUL | AMARELO); emitirSom(255, 1500); } // Mostra uma tela de "modo de atração" enquanto aguarda o usuário pressionar o botão. @@ -466,28 +328,46 @@ int numeroDoLed = 0; // Mantém o controle de qual LED estamos ligando durante o // Esta função é ativada quando o usuário segura o botão inferior direito (amarelo) void tocarMusica(void) { // Notas (frequências) da música. int notas[] = { 2637, 2637, 0, 2637, 0, 2093, 2637, 0, 3136, 0, 0, 0, 1568, 0, 0, 0, 2093, 0, 0, 1568, 0, 0, 1319, 0, 0, 1760, 0, 1976, 0, 1865, 1760, 0, 1568, 2637, 3136, 3520, 0, 2794, 3136, 0, 2637, 0, 2093, 2349, 1976, 0, 0, 2093, 0, 0, 1568, 0, 0, 1319, 0, 0, 1760, 0, 1976, 0, 1865, 1760, 0, 1568, 2637, 3136, 3520, 0, 2794, 3136, 0, 2637, 0, 2093, 2349, 1976, 0, 0, 262, 523, 220, 440, 233, 466, 0, 0, 262, 523, 220, 440, 233, 466, 0, 0, 175, 349, 147, 294, 156, 311, 0, 0, 175, 349, 147, 294, 156, 311, 0, 0, 311, 277, 294, 277, 311, 311, 208, 196, 277, 262, 370, 349, 165, 466, 440, 415, 311, 247, 233, 220, 208, 0, 0, 0}; // Duração das notas da música int tempos[] = { 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 9, 9, 9, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 9, 9, 9, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 6, 3, 12, 12, 12, 12, 12, 12, 6, 3, 12, 12, 12, 12, 12, 12, 6, 3, 12, 12, 12, 12, 12, 12, 6, 6, 18, 18, 18, 6, 6, 6, 6, 6, 6, 18, 18, 18, 18, 18, 18, 10, 10, 10, 10, 10, 10, 3, 3, 3}; // Ligue o LED inferior direito (amarelo) controlaLEDs(AMARELO); emitirTom(AMARELO, 150); controlaLEDs(VERMELHO | VERDE | AZUL); // Ligue os outros LEDs até você soltar o botão while(checaBotao() != NADA_ESCOLHIDO) ; // Aguarde até que o usuário pare de pressionar o botão controlaLEDs(NADA_ESCOLHIDO); // Desligue os LEDs aguarde(1000); // Espere um segundo antes de tocar música digitalWrite(PIEZO2, LOW); // configure o lado "PIEZO1" da campainha para ficar baixo, enquanto tocamos o tom no outro pino. while(checaBotao() == NADA_ESCOLHIDO) // Reproduzir música até você pressionar um botão { int limite = sizeof notas / sizeof *notas; // Descobre o tamanho do array // iterar sobre as notas da melodia: for (int i = 0; i < limite; i++) { mudaLED(); int duracao = 1000 / tempos[i]; tone(PIEZO1, notas[i], duracao); aguarde(duracao * 1.3); noTone(PIEZO1); } } } @@ -496,7 +376,6 @@ void tocarMusica(void) void mudaLED(void) { controlaLEDs(1 << numeroDoLed); // Mude o LED numeroDoLed++; // Ir para o próximo LED if(numeroDoLed > 3) numeroDoLed = 0; // Enrole o balcão, se necessário } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,389 +0,0 @@ -
wkoch revised this gist
May 23, 2022 . 3 changed files with 728 additions and 127 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,100 @@ #define ATRACAO 0 #define JOGO 1 #define MUSICA 2 // #define AMARELO 1 // #define AZUL 2 // #define VERDE 3 // #define VERMELHO 4 #define VERMELHO 10 #define VERDE 3 #define AZUL 13 #define AMARELO 5 // #define BOTAO_AMARELO 8 // #define BOTAO_AZUL 9 // #define BOTAO_VERDE 10 // #define BOTAO_VERMELHO 11 #define BOTAO_VERMELHO 9 #define BOTAO_VERDE 2 #define BOTAO_AZUL 12 #define BOTAO_AMARELO 6 #define PIEZO1 6 #define PIEZO2 7 #define entrada(x) pinMode(x, INPUT_PULLUP) #define saida(x) pinMode(x, OUTPUT) #define aguarde(x) delay(x) byte modo = MUSICA; void setup(void) { entrada(BOTAO_AMARELO); entrada(BOTAO_AZUL); entrada(BOTAO_VERDE); entrada(BOTAO_VERMELHO); saida(PIEZO1); saida(PIEZO2); saida(BOTAO_AMARELO); saida(BOTAO_AZUL); saida(BOTAO_VERDE); saida(BOTAO_VERMELHO); } void loop(void) { switch(modo) { case JOGO: break; case MUSICA: break; default: modoAtracao(); } } void modoAtracao() { return; } void easterEgg() { // Notas (frequências) da música. int notas[] = { 2637, 2637, 0, 2637, 0, 2093, 2637, 0, 3136, 0, 0, 0, 1568, 0, 0, 0, 2093, 0, 0, 1568, 0, 0, 1319, 0, 0, 1760, 0, 1976, 0, 1865, 1760, 0, 1568, 2637, 3136, 3520, 0, 2794, 3136, 0, 2637, 0, 2093, 2349, 1976, 0, 0, 2093, 0, 0, 1568, 0, 0, 1319, 0, 0, 1760, 0, 1976, 0, 1865, 1760, 0, 1568, 2637, 3136, 3520, 0, 2794, 3136, 0, 2637, 0, 2093, 2349, 1976, 0, 0, 262, 523, 220, 440, 233, 466, 0, 0, 262, 523, 220, 440, 233, 466, 0, 0, 175, 349, 147, 294, 156, 311, 0, 0, 175, 349, 147, 294, 156, 311, 0, 0, 311, 277, 294, 277, 311, 311, 208, 196, 277, 262, 370, 349, 165, 466, 440, 415, 311, 247, 233, 220, 208, 0, 0, 0}; // Duração das notas da música int tempos[] = { 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 9, 9, 9, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 9, 9, 9, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 6, 3, 12, 12, 12, 12, 12, 12, 6, 3, 12, 12, 12, 12, 12, 12, 6, 3, 12, 12, 12, 12, 12, 12, 6, 6, 18, 18, 18, 6, 6, 6, 6, 6, 6, 18, 18, 18, 18, 18, 18, 10, 10, 10, 10, 10, 10, 3, 3, 3}; int limite = sizeof notas / sizeof *notas; // Descobre o tamanho do array digitalWrite(PIEZO2, LOW); for(int estaNota = 0; estaNota < limite; estaNota++) { int duracao = 1500 / tempos[estaNota]; tone(PIEZO1, notas[estaNota], duracao); int pausa = duracao * 5.40; delay(duracao); noTone(PIEZO1); } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,7 +1,38 @@ // Frequências das notas musicais #define NOTA_D3 147 #define NOTA_DS3 156 #define NOTA_E3 165 #define NOTA_F3 175 #define NOTA_G3 196 #define NOTA_GS3 208 #define NOTA_A3 220 #define NOTA_AS3 233 #define NOTA_B3 247 #define NOTA_C4 262 #define NOTA_CS4 277 #define NOTA_D4 294 #define NOTA_DS4 311 #define NOTA_F4 349 #define NOTA_FS4 370 #define NOTA_GS4 415 #define NOTA_A4 440 #define NOTA_AS4 466 #define NOTA_C5 523 #define NOTA_E6 1319 #define NOTA_G6 1568 #define NOTA_A6 1760 #define NOTA_AS6 1865 #define NOTA_B6 1976 #define NOTA_C7 2093 #define NOTA_D7 2349 #define NOTA_E7 2637 #define NOTA_F7 2794 #define NOTA_G7 3136 #define NOTA_A7 3520 #define ENTRADA(x) pinMode(x, INPUT_PULLUP) #define SAIDA(x) pinMode(x, OUTPUT) #define aguarde(x) delay(x) #define DESLIGA 0 // Usado para controlar LEDs #define NADA_ESCOLHIDO 0 // Usado para verificar botões @@ -29,118 +60,194 @@ #define RODADAS_ATE_SER_CAMPEAO 13 // Número de rodadas para vencer o Jogo. #define TEMPO_DE_RESPOSTA_JOGADOR 3000 // Tempo para pressionar um botão antes que o jogo acabe. 3 segundos #define JOGO_MEMORIA 0 #define MODO_MUSICAL 1 // Variáveis de estado do jogo byte modoDeJogo = JOGO_MEMORIA; //Por padrão, vamos jogar o jogo da memória byte tabuleiro[32]; //Salva a combinação de botões à medida que avançamos byte rodadas = 0; //Conta o número de rodadas de sucesso que o jogador fez // Notas na melodia. int melodia[] = { NOTA_E7, NOTA_E7, 0, NOTA_E7, 0, NOTA_C7, NOTA_E7, 0, NOTA_G7, 0, 0, 0, NOTA_G6, 0, 0, 0, NOTA_C7, 0, 0, NOTA_G6, 0, 0, NOTA_E6, 0, 0, NOTA_A6, 0, NOTA_B6, 0, NOTA_AS6, NOTA_A6, 0, NOTA_G6, NOTA_E7, NOTA_G7, NOTA_A7, 0, NOTA_F7, NOTA_G7, 0, NOTA_E7, 0, NOTA_C7, NOTA_D7, NOTA_B6, 0, 0, NOTA_C7, 0, 0, NOTA_G6, 0, 0, NOTA_E6, 0, 0, NOTA_A6, 0, NOTA_B6, 0, NOTA_AS6, NOTA_A6, 0, NOTA_G6, NOTA_E7, NOTA_G7, NOTA_A7, 0, NOTA_F7, NOTA_G7, 0, NOTA_E7, 0, NOTA_C7, NOTA_D7, NOTA_B6, 0, 0, NOTA_C4, NOTA_C5, NOTA_A3, NOTA_A4, NOTA_AS3, NOTA_AS4, 0, 0, NOTA_C4, NOTA_C5, NOTA_A3, NOTA_A4, NOTA_AS3, NOTA_AS4, 0, 0, NOTA_F3, NOTA_F4, NOTA_D3, NOTA_D4, NOTA_DS3, NOTA_DS4, 0, 0, NOTA_F3, NOTA_F4, NOTA_D3, NOTA_D4, NOTA_DS3, NOTA_DS4, 0, 0, NOTA_DS4, NOTA_CS4, NOTA_D4, NOTA_CS4, NOTA_DS4, NOTA_DS4, NOTA_GS3, NOTA_G3, NOTA_CS4, NOTA_C4, NOTA_FS4, NOTA_F4, NOTA_E3, NOTA_AS4, NOTA_A4, NOTA_GS4, NOTA_DS4, NOTA_B3, NOTA_AS3, NOTA_A3, NOTA_GS3, 0, 0, 0}; // Duração das notas int tempo[] = { 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 9, 9, 9, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 9, 9, 9, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 6, 3, 12, 12, 12, 12, 12, 12, 6, 3, 12, 12, 12, 12, 12, 12, 6, 3, 12, 12, 12, 12, 12, 12, 6, 6, 18, 18, 18, 6, 6, 6, 6, 6, 6, 18, 18, 18, 18, 18, 18, 10, 10, 10, 10, 10, 10, 3, 3, 3 }; void setup() { // Configuração dos pinos de entradas e saídas ENTRADA(BOTAO_VERMELHO); ENTRADA(BOTAO_VERDE); ENTRADA(BOTAO_AZUL); ENTRADA(BOTAO_AMARELO); SAIDA(LED_VERMELHO); SAIDA(LED_VERDE); SAIDA(LED_AZUL); SAIDA(LED_AMARELO); SAIDA(PIEZO1); SAIDA(PIEZO2); toqueVencedor(); // Ao ligar toque a música vencedor if (checaBotao() == AMARELO) tocarMusica(); } void loop() { modoAtracao(); // Pisca luzes enquanto aguarda o usuário apertar um botão // Indique o início do jogo controlaLEDs(VERMELHO | VERDE | AZUL | AMARELO); // Ativar todos os LEDs aguarde(1000); controlaLEDs(DESLIGA); // Desligue os LEDs aguarde(250); if (modoDeJogo == MODO_MUSICAL) { tocarMusica(); } if (modoDeJogo == JOGO_MEMORIA) { // Play no jogo de memória e recebe com resultado if (jogoDaMemoria() == true) toqueVencedor(); // Ganhou, toca som de vitória else toquePerdedor(); // Perdeu, toca som de derrota } } //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //As seguintes funções estão relacionadas apenas ao jogo // Jogue o jogo regular da memória // Retorna false se o jogador perde ou true se o jogador ganhar boolean jogoDaMemoria(void) { randomSeed(millis()); // Gerador aleatório rodadas = 0; // Redefinir o jogo para o começo while (rodadas < RODADAS_ATE_SER_CAMPEAO) { add_to_moves(); // Adicione um botão aos movimentos atuais e reproduza-os playMoves(); // Jogue de volta o tabuleiro do jogo atual // Em seguida, solicite ao jogador que repita a sequência. for (byte currentMove = 0 ; currentMove < rodadas ; currentMove++) { byte choice = aguarde_botao(); // Veja o botão que o usuário pressiona if (choice == 0) return false; // Se a espera expirar, o jogador perde if (choice != tabuleiro[currentMove]) return false; // Se a escolha estiver incorreta, o jogador perde } aguarde(1000); // O jogador estava correto, espera antes de jogar } return true; // O jogador cumpriu todas as rodadas para ganhar! } // Reproduz o conteúdo atual dos movimentos do jogo void playMoves(void) { for (byte currentMove = 0 ; currentMove < rodadas ; currentMove++) { toner(tabuleiro[currentMove], 150); // Aguarde algum tempo entre a reprodução do botão // Encurtar isso para tornar o jogo mais difícil @@ -149,24 +256,24 @@ void mostraParaMemorizar(void) } // Adiciona um novo botão aleatório à sequência do jogo void add_to_moves(void) { byte novoBotao = random(0, 4); //min (incluido), max (excluido) // Temos que converter esse número, 0 até 3, para CHOICEs if(novoBotao == 0) novoBotao = VERMELHO; else if(novoBotao == 1) novoBotao = VERDE; else if(novoBotao == 2) novoBotao = AZUL; else if(novoBotao == 3) novoBotao = AMARELO; tabuleiro[rodadas++] = novoBotao; // Adicionar este novo botão ao array do jogo } //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // As seguintes funções controlam o hardware // ilumina um determinado LEDs // Passar em um byte composto de VERMELHO, AMARELO, etc void controlaLEDs(byte leds) { if ((leds & VERMELHO) != 0) @@ -192,7 +299,7 @@ void controlaLEDs(byte leds) // Aguarde até que um botão seja pressionado. // Retorna uma das cores do LED (LED_VERMELHO, etc.) se for bem-sucedida, 0 se expirar byte aguarde_botao(void) { long inicio = millis(); // Lembre-se da hora em que começamos o loop @@ -203,7 +310,7 @@ byte aguardarBotao(void) if (button != NADA_ESCOLHIDO) { toner(button, 150); // Reproduzir o botão que o usuário acabou de pressionar while(checaBotao() != NADA_ESCOLHIDO) ; // Agora vamos esperar que o usuário libere o botão @@ -233,67 +340,68 @@ byte checaBotao(void) // Verde, superior direito: 880Hz - 1.136ms - pulso de 0.568ms // Azul, inferior esquerdo: pulso de 587.33Hz - 1.702ms - 0.851ms // Amarelo, inferior direito: 784Hz - 1,276ms - pulso de 0,638ms void toner(byte which, int buzz_length_ms) { controlaLEDs(which); // Ligue um dado LED // Reproduz o som associado ao LED fornecido switch(which) { case VERMELHO: buzz_sound(buzz_length_ms, 1136); break; case VERDE: buzz_sound(buzz_length_ms, 568); break; case AZUL: buzz_sound(buzz_length_ms, 851); break; case AMARELO: buzz_sound(buzz_length_ms, 638); break; } controlaLEDs(DESLIGA); // Desligue todos os LEDs } // Alterna o buzzer a cada buzz_delay_us, por uma duração de buzz_length_ms. void buzz_sound(int buzz_length_ms, int buzz_delay_us) { // Converter tempo total de reprodução de milissegundos para microssegundos long buzz_length_us = buzz_length_ms * (long)1000; // Faz um loop até que o tempo restante de reprodução seja menor que um único buzz_delay_us while (buzz_length_us > (buzz_delay_us * 2)) { buzz_length_us -= buzz_delay_us * 2; // Diminui o tempo de jogo restante // Alterna a campainha em várias velocidades digitalWrite(PIEZO1, LOW); digitalWrite(PIEZO2, HIGH); delayMicroseconds(buzz_delay_us); digitalWrite(PIEZO1, HIGH); digitalWrite(PIEZO2, LOW); delayMicroseconds(buzz_delay_us); } } // Reproduzir o som e as luzes do vencedor void toqueVencedor(void) { controlaLEDs(VERDE | AZUL); winner_sound(); controlaLEDs(VERMELHO | AMARELO); winner_sound(); controlaLEDs(VERDE | AZUL); winner_sound(); controlaLEDs(VERMELHO | AMARELO); winner_sound(); } // Som vencedor // Este é apenas um som (chato) único que criamos, não há mágica nisso void winner_sound(void) { // Alterna a campainha em várias velocidades for (byte x = 250 ; x > 70 ; x--) @@ -302,11 +410,11 @@ void somGanhador(void) { digitalWrite(PIEZO2, HIGH); digitalWrite(PIEZO1, LOW); delayMicroseconds(x); digitalWrite(PIEZO2, LOW); digitalWrite(PIEZO1, HIGH); delayMicroseconds(x); } } } @@ -315,36 +423,39 @@ void somGanhador(void) void toquePerdedor(void) { controlaLEDs(VERMELHO | VERDE); buzz_sound(255, 1500); controlaLEDs(AZUL | AMARELO); buzz_sound(255, 1500); controlaLEDs(VERMELHO | VERDE); buzz_sound(255, 1500); controlaLEDs(AZUL | AMARELO); buzz_sound(255, 1500); } // Mostra uma tela de "modo de atração" enquanto aguarda o usuário pressionar o botão. void modoAtracao(void) { while(true) { controlaLEDs(VERMELHO); aguarde(100); if (checaBotao() != NADA_ESCOLHIDO) return; controlaLEDs(AZUL); aguarde(100); if (checaBotao() != NADA_ESCOLHIDO) return; controlaLEDs(VERDE); aguarde(100); if (checaBotao() != NADA_ESCOLHIDO) return; controlaLEDs(AMARELO); aguarde(100); if (checaBotao() != NADA_ESCOLHIDO) return; } } //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= @@ -357,7 +468,7 @@ void tocarMusica(void) { // Ligue o LED inferior direito (amarelo) controlaLEDs(AMARELO); toner(AMARELO, 150); controlaLEDs(VERMELHO | VERDE | AZUL); // Ligue os outros LEDs até você soltar o botão @@ -371,11 +482,12 @@ void tocarMusica(void) while(checaBotao() == NADA_ESCOLHIDO) // Reproduzir música até você pressionar um botão { // iterar sobre as notas da melodia: for (int i = 0; i < 134; i++) { mudaLED(); tone(PIEZO2, melodia[i], tempo[i]); delay(tempo[i]); noTone(PIEZO2); } } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,389 @@ #define entrada(x) pinMode(x, INPUT_PULLUP) #define saida(x) pinMode(x, OUTPUT) #define aguarde(x) delay(x) #define aguardeMicroSegundos(x) delayMicroseconds(x) #define DESLIGA 0 // Usado para controlar LEDs #define NADA_ESCOLHIDO 0 // Usado para verificar botões #define VERMELHO 0 #define VERDE 1 #define AZUL 2 #define AMARELO 3 #define LED_VERMELHO 10 #define LED_VERDE 3 #define LED_AZUL 13 #define LED_AMARELO 5 // Definições dos pinos de botão #define BOTAO_VERMELHO 9 #define BOTAO_VERDE 2 #define BOTAO_AZUL 12 #define BOTAO_AMARELO 6 // Definições dos pinos do Buzzer #define PIEZO1 4 #define PIEZO2 7 // Parâmetros do jogo #define RODADAS_ATE_SER_CAMPEAO 13 // Número de rodadas para vencer o Jogo. #define TEMPO_DE_RESPOSTA_JOGADOR 3000 // Tempo para pressionar um botão antes que o jogo acabe. 3 segundos #define MODO_ATRACAO 0 #define MODO_JOGO 1 #define MODO_MUSICAL 2 // Variáveis de estado do jogo byte modo = MODO_ATRACAO; //Por padrão, vamos jogar o jogo da memória byte tabuleiro[32]; //Salva a combinação de botões à medida que avançamos byte rodadas = 0; //Conta o número de rodadas de sucesso que o jogador fez // Notas (frequências) da música. int notas[] = { 2637, 2637, 0, 2637, 0, 2093, 2637, 0, 3136, 0, 0, 0, 1568, 0, 0, 0, 2093, 0, 0, 1568, 0, 0, 1319, 0, 0, 1760, 0, 1976, 0, 1865, 1760, 0, 1568, 2637, 3136, 3520, 0, 2794, 3136, 0, 2637, 0, 2093, 2349, 1976, 0, 0, 2093, 0, 0, 1568, 0, 0, 1319, 0, 0, 1760, 0, 1976, 0, 1865, 1760, 0, 1568, 2637, 3136, 3520, 0, 2794, 3136, 0, 2637, 0, 2093, 2349, 1976, 0, 0, 262, 523, 220, 440, 233, 466, 0, 0, 262, 523, 220, 440, 233, 466, 0, 0, 175, 349, 147, 294, 156, 311, 0, 0, 175, 349, 147, 294, 156, 311, 0, 0, 311, 277, 294, 277, 311, 311, 208, 196, 277, 262, 370, 349, 165, 466, 440, 415, 311, 247, 233, 220, 208, 0, 0, 0}; // Duração das notas da música int tempos[] = { 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 9, 9, 9, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 9, 9, 9, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 6, 3, 12, 12, 12, 12, 12, 12, 6, 3, 12, 12, 12, 12, 12, 12, 6, 3, 12, 12, 12, 12, 12, 12, 6, 6, 18, 18, 18, 6, 6, 6, 6, 6, 6, 18, 18, 18, 18, 18, 18, 10, 10, 10, 10, 10, 10, 3, 3, 3}; void setup() { // Configuração dos pinos de entradas e saídas entrada(BOTAO_VERMELHO); entrada(BOTAO_VERDE); entrada(BOTAO_AZUL); entrada(BOTAO_AMARELO); saida(LED_VERMELHO); saida(LED_VERDE); saida(LED_AZUL); saida(LED_AMARELO); saida(PIEZO1); saida(PIEZO2); toqueVencedor(); // Ao ligar toque a música vencedor } void loop() { switch(modo) { case MODO_JOGO: jogoDaMemoria(); // Roda um jogo de memória e volta ao loop break; case MODO_MUSICAL: tocarMusica(); // Toca a música Easter Egg e volta para o loop break; default: modoAtracao(); // Pisca luzes enquanto aguarda o usuário apertar um botão } } // Mostra uma tela de "modo de atração" enquanto aguarda o usuário pressionar o botão. void modoAtracao(void) { controlaLEDs(VERMELHO); aguarde(100); if (checaBotao() != NADA_ESCOLHIDO) modo = MODO_JOGO; controlaLEDs(AZUL); aguarde(100); if (checaBotao() != NADA_ESCOLHIDO) modo = MODO_JOGO; controlaLEDs(VERDE); aguarde(100); if (checaBotao() != NADA_ESCOLHIDO) modo = MODO_JOGO; controlaLEDs(AMARELO); aguarde(100); if (checaBotao() != NADA_ESCOLHIDO) modo = MODO_MUSICAL; } //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //As seguintes funções estão relacionadas apenas ao jogo void redefinirJogo(void) { // Redefinir todo o tabuleiro for (int i = 0; i < ++rodadas; i++) { tabuleiro[i] = 0; } rodadas = 0; } // Jogo da memória void jogoDaMemoria(void) { // redefinirJogo(); randomSeed(millis()); // Semente do gerador aleatório while (rodadas < RODADAS_ATE_SER_CAMPEAO) { criaNovaJogada(); // Adicione uma cor nova no tabuleiro mostraParaMemorizar(); // Mostra o tabuleiro para memorizar // Em seguida, solicite ao jogador que repita a sequência. for(byte jogadaAtual = 0; jogadaAtual < rodadas; jogadaAtual++) { byte opcao = aguardarBotao(); // Veja o botão que o usuário pressiona // Se a espera expirar, ou // Se a escolha estiver incorreta, o jogador perde if (opcao == 0 || opcao != tabuleiro[jogadaAtual]) toquePerdedor(); } aguarde(1000); // O jogador estava correto, espera antes de jogar } // O jogador cumpriu todas as rodadas para ganhar! toqueVencedor(); redefinirJogo(); } // Reproduz o conteúdo atual dos movimentos do jogo void mostraParaMemorizar(void) { for (byte jogadaAtual = 0 ; jogadaAtual < rodadas ; jogadaAtual++) { emiteTom(tabuleiro[jogadaAtual], 150); // Aguarde algum tempo entre a reprodução do botão // Encurtar isso para tornar o jogo mais difícil aguarde(150); // 150 funciona bem. 75 fica rápido. } } // Adiciona um novo botão aleatório à sequência do jogo void criaNovaJogada(void) { byte novaCor = random(0, 4); //min (incluido), max (excluido) // Temos que converter esse número, 0 até 3, para Cores // if(novaCor == 0) novaCor = VERMELHO; // else if(novaCor == 1) novaCor = VERDE; // else if(novaCor == 2) novaCor = AZUL; // else if(novaCor == 3) novaCor = AMARELO; tabuleiro[rodadas++] = novaCor; // Adicionar este novo botão ao array do jogo } //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // As seguintes funções controlam o hardware // ilumina um determinado LED // Passar um byte composto de VERMELHO, AZUL, VERDE e AMARELO void controlaLEDs(byte leds) { if (leds == VERMELHO) digitalWrite(LED_VERMELHO, HIGH); else digitalWrite(LED_VERMELHO, LOW); if (leds == VERDE) digitalWrite(LED_VERDE, HIGH); else digitalWrite(LED_VERDE, LOW); if (leds == AZUL) digitalWrite(LED_AZUL, HIGH); else digitalWrite(LED_AZUL, LOW); if (leds == AMARELO) digitalWrite(LED_AMARELO, HIGH); else digitalWrite(LED_AMARELO, LOW); } // Aguarde até que um botão seja pressionado. // Retorna uma das cores do LED (LED_VERMELHO, etc.) se for bem-sucedida, 0 se expirar byte aguardarBotao(void) { long inicio = millis(); // Lembre-se da hora em que começamos o loop // Enquanto tempo decorrido desde a definição da variável início for menor que limite do jogo: while ( (millis() - inicio) < TEMPO_DE_RESPOSTA_JOGADOR) // Faz um loop até que passe o tempo limite { byte botao = checaBotao(); if (botao != NADA_ESCOLHIDO) { emiteTom(botao, 150); // Reproduzir o botão que o usuário acabou de pressionar while(checaBotao() != NADA_ESCOLHIDO) ; // Agora vamos esperar que o usuário libere o botão aguarde(10); // Isso ajuda com toques duplos acidentais return botao; } } return NADA_ESCOLHIDO; // Se chegarmos aqui, expiramos! } // Retorna um bit '1' na posição correspondente a VERMELHO, VERDE, etc. byte checaBotao(void) { if (digitalRead(BOTAO_VERMELHO) == 0) return(VERMELHO); else if (digitalRead(BOTAO_VERDE) == 0) return(VERDE); else if (digitalRead(BOTAO_AZUL) == 0) return(AZUL); else if (digitalRead(BOTAO_AMARELO) == 0) return(AMARELO); return(NADA_ESCOLHIDO); // Se nenhum botão for pressionado, não retorne nenhum } // Acenda um LED e toque o tom // Vermelho, superior esquerdo: 440Hz - 2.272ms - 1.136ms de pulso // Verde, superior direito: 880Hz - 1.136ms - pulso de 0.568ms // Azul, inferior esquerdo: pulso de 587.33Hz - 1.702ms - 0.851ms // Amarelo, inferior direito: 784Hz - 1,276ms - pulso de 0,638ms void emiteTom(byte cor, int duracao) { controlaLEDs(cor); // Ligue um dado LED // Reproduz o som associado ao LED fornecido switch(cor) { case VERMELHO: emitirSom(duracao, 1136); break; case VERDE: emitirSom(duracao, 568); break; case AZUL: emitirSom(duracao, 851); break; case AMARELO: emitirSom(duracao, 638); break; } controlaLEDs(DESLIGA); // Desligue todos os LEDs } // Alterna o buzzer a cada atrasoEmMiliSegundos, por uma duração. void emitirSom(int duracao, int atrasoEmMiliSegundos) { // Converter tempo total de reprodução de milissegundos para microssegundos long duracaoMicroSegundos = duracao * (long)1000; // Faz um loop até que o tempo restante de reprodução seja menor que um único atrasoEmMiliSegundos while (duracaoMicroSegundos > (atrasoEmMiliSegundos * 2)) { duracaoMicroSegundos -= atrasoEmMiliSegundos * 2; // Diminui o tempo de jogo restante // Alterna a campainha em várias velocidades digitalWrite(PIEZO1, LOW); digitalWrite(PIEZO2, HIGH); aguardeMicroSegundos(atrasoEmMiliSegundos); digitalWrite(PIEZO1, HIGH); digitalWrite(PIEZO2, LOW); aguardeMicroSegundos(atrasoEmMiliSegundos); } } // Reproduzir o som e as luzes do vencedor void toqueVencedor(void) { controlaLEDs(VERDE | AZUL); somGanhador(); controlaLEDs(VERMELHO | AMARELO); somGanhador(); controlaLEDs(VERDE | AZUL); somGanhador(); controlaLEDs(VERMELHO | AMARELO); somGanhador(); } // Som vencedor void somGanhador(void) { // Alterna a campainha em várias velocidades for (byte x = 250 ; x > 70 ; x--) { for (byte y = 0 ; y < 3 ; y++) { digitalWrite(PIEZO2, HIGH); digitalWrite(PIEZO1, LOW); aguardeMicroSegundos(x); digitalWrite(PIEZO2, LOW); digitalWrite(PIEZO1, HIGH); aguardeMicroSegundos(x); } } } // Toque o som perdedor / luzes void toquePerdedor(void) { controlaLEDs(VERMELHO | VERDE); emitirSom(255, 1500); controlaLEDs(AZUL | AMARELO); emitirSom(255, 1500); controlaLEDs(VERMELHO | VERDE); emitirSom(255, 1500); controlaLEDs(AZUL | AMARELO); emitirSom(255, 1500); } //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // As seguintes funções estão relacionadas apenas ao Easter Egg Musical int numeroDoLed = 0; // Mantém o controle de qual LED estamos ligando durante o ciclo musical // Não faça nada além de tocar a música // Esta função é ativada quando o usuário segura o botão inferior direito (amarelo) void tocarMusica(void) { // Ligue o LED inferior direito (amarelo) controlaLEDs(AMARELO); emiteTom(AMARELO, 150); controlaLEDs(VERMELHO | VERDE | AZUL); // Ligue os outros LEDs até você soltar o botão while(checaBotao() != NADA_ESCOLHIDO) ; // Aguarde até que o usuário pare de pressionar o botão controlaLEDs(NADA_ESCOLHIDO); // Desligue os LEDs aguarde(1000); // Espere um segundo antes de tocar música digitalWrite(PIEZO1, LOW); // configure o lado "PIEZO1" da campainha para ficar baixo, enquanto tocamos o tom no outro pino. while(checaBotao() == NADA_ESCOLHIDO) // Reproduzir música até você pressionar um botão { int limite = sizeof notas / sizeof *notas; // Descobre o tamanho do array // iterar sobre as notas/tempos da música: for (int i = 0; i < limite; i++) { mudaLED(); tone(PIEZO2, notas[i], tempos[i]); // Função nativa do arduino para reproduzir Tons. } } } // Cada vez que esta função é chamada, a placa se move para o próximo LED void mudaLED(void) { controlaLEDs(1 << numeroDoLed); // Mude o LED numeroDoLed++; // Ir para o próximo LED if(numeroDoLed > 3) numeroDoLed = 0; // Enrole o balcão, se necessário } -
wkoch created this gist
May 22, 2022 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,390 @@ #define entrada(x) pinMode(x, INPUT_PULLUP) #define saida(x) pinMode(x, OUTPUT) #define aguarde(x) delay(x) #define aguardeMicroSegundos(x) delayMicroseconds(x) #define DESLIGA 0 // Usado para controlar LEDs #define NADA_ESCOLHIDO 0 // Usado para verificar botões #define VERMELHO (1 << 0) #define VERDE (1 << 1) #define AZUL (1 << 2) #define AMARELO (1 << 3) #define LED_VERMELHO 10 #define LED_VERDE 3 #define LED_AZUL 13 #define LED_AMARELO 5 // Definições dos pinos de botão #define BOTAO_VERMELHO 9 #define BOTAO_VERDE 2 #define BOTAO_AZUL 12 #define BOTAO_AMARELO 6 // Definições dos pinos do Buzzer #define PIEZO1 4 #define PIEZO2 7 // Parâmetros do jogo #define RODADAS_ATE_SER_CAMPEAO 13 // Número de rodadas para vencer o Jogo. #define TEMPO_DE_RESPOSTA_JOGADOR 3000 // Tempo para pressionar um botão antes que o jogo acabe. 3 segundos #define MODO_ATRACAO 0 #define MODO_JOGO 1 #define MODO_MUSICAL 2 // Variáveis de estado do jogo byte modo = MODO_ATRACAO; //Por padrão, vamos jogar o jogo da memória byte tabuleiro[32]; //Salva a combinação de botões à medida que avançamos byte rodadas = 0; //Conta o número de rodadas de sucesso que o jogador fez // Notas (frequências) da música. int notas[] = { 2637, 2637, 0, 2637, 0, 2093, 2637, 0, 3136, 0, 0, 0, 1568, 0, 0, 0, 2093, 0, 0, 1568, 0, 0, 1319, 0, 0, 1760, 0, 1976, 0, 1865, 1760, 0, 1568, 2637, 3136, 3520, 0, 2794, 3136, 0, 2637, 0, 2093, 2349, 1976, 0, 0, 2093, 0, 0, 1568, 0, 0, 1319, 0, 0, 1760, 0, 1976, 0, 1865, 1760, 0, 1568, 2637, 3136, 3520, 0, 2794, 3136, 0, 2637, 0, 2093, 2349, 1976, 0, 0, 262, 523, 220, 440, 233, 466, 0, 0, 262, 523, 220, 440, 233, 466, 0, 0, 175, 349, 147, 294, 156, 311, 0, 0, 175, 349, 147, 294, 156, 311, 0, 0, 311, 277, 294, 277, 311, 311, 208, 196, 277, 262, 370, 349, 165, 466, 440, 415, 311, 247, 233, 220, 208, 0, 0, 0}; // Duração das notas da música int tempos[] = { 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 9, 9, 9, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 9, 9, 9, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 6, 3, 12, 12, 12, 12, 12, 12, 6, 3, 12, 12, 12, 12, 12, 12, 6, 3, 12, 12, 12, 12, 12, 12, 6, 6, 18, 18, 18, 6, 6, 6, 6, 6, 6, 18, 18, 18, 18, 18, 18, 10, 10, 10, 10, 10, 10, 3, 3, 3}; void setup() { // Configuração dos pinos de entradas e saídas entrada(BOTAO_VERMELHO); entrada(BOTAO_VERDE); entrada(BOTAO_AZUL); entrada(BOTAO_AMARELO); saida(LED_VERMELHO); saida(LED_VERDE); saida(LED_AZUL); saida(LED_AMARELO); saida(PIEZO1); saida(PIEZO2); toqueVencedor(); // Ao ligar toque a música vencedor } void loop() { switch(modo) { case MODO_ATRACAO: modoAtracao(); // Pisca luzes enquanto aguarda o usuário apertar um botão break; case MODO_JOGO: jogoDaMemoria(); // Roda um jogo de memória e volta ao loop break; case MODO_MUSICAL: tocarMusica(); // Toca a música Easter Egg e volta para o loop break; } } //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //As seguintes funções estão relacionadas apenas ao jogo void redefinirJogo(void) { // Redefinir todo o tabuleiro for (int i = 0; i < ++rodadas; i++) { tabuleiro[i] = 0; } rodadas = 0; } // Jogo da memória void jogoDaMemoria(void) { // redefinirJogo(); randomSeed(millis()); // Semente do gerador aleatório while (rodadas < RODADAS_ATE_SER_CAMPEAO) { criaNovaJogada(); // Adicione uma cor nova no tabuleiro mostraParaMemorizar(); // Mostra o tabuleiro para memorizar // Em seguida, solicite ao jogador que repita a sequência. for(byte jogadaAtual = 0; jogadaAtual < rodadas; jogadaAtual++) { byte opcao = aguardarBotao(); // Veja o botão que o usuário pressiona // Se a espera expirar, ou // Se a escolha estiver incorreta, o jogador perde if (opcao == 0 || opcao != tabuleiro[jogadaAtual]) toquePerdedor(); } aguarde(1000); // O jogador estava correto, espera antes de jogar } // O jogador cumpriu todas as rodadas para ganhar! toqueVencedor(); redefinirJogo(); } // Reproduz o conteúdo atual dos movimentos do jogo void mostraParaMemorizar(void) { for (byte jogadaAtual = 0 ; jogadaAtual < rodadas ; jogadaAtual++) { emiteTom(tabuleiro[jogadaAtual], 150); // Aguarde algum tempo entre a reprodução do botão // Encurtar isso para tornar o jogo mais difícil aguarde(150); // 150 funciona bem. 75 fica rápido. } } // Adiciona um novo botão aleatório à sequência do jogo void criaNovaJogada(void) { byte novaCor = random(0, 4); //min (incluido), max (excluido) // Temos que converter esse número, 0 até 3, para Cores if(novaCor == 0) novaCor = VERMELHO; else if(novaCor == 1) novaCor = VERDE; else if(novaCor == 2) novaCor = AZUL; else if(novaCor == 3) novaCor = AMARELO; tabuleiro[rodadas++] = novaCor; // Adicionar este novo botão ao array do jogo } //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // As seguintes funções controlam o hardware // ilumina um determinado LED // Passar um byte composto de VERMELHO, AZUL, VERDE e AMARELO void controlaLEDs(byte leds) { if ((leds & VERMELHO) != 0) digitalWrite(LED_VERMELHO, HIGH); else digitalWrite(LED_VERMELHO, LOW); if ((leds & VERDE) != 0) digitalWrite(LED_VERDE, HIGH); else digitalWrite(LED_VERDE, LOW); if ((leds & AZUL) != 0) digitalWrite(LED_AZUL, HIGH); else digitalWrite(LED_AZUL, LOW); if ((leds & AMARELO) != 0) digitalWrite(LED_AMARELO, HIGH); else digitalWrite(LED_AMARELO, LOW); } // Aguarde até que um botão seja pressionado. // Retorna uma das cores do LED (LED_VERMELHO, etc.) se for bem-sucedida, 0 se expirar byte aguardarBotao(void) { long inicio = millis(); // Lembre-se da hora em que começamos o loop // Enquanto tempo decorrido desde a definição da variável início for menor que limite do jogo: while ( (millis() - inicio) < TEMPO_DE_RESPOSTA_JOGADOR) // Faz um loop até que passe o tempo limite { byte button = checaBotao(); if (button != NADA_ESCOLHIDO) { emiteTom(button, 150); // Reproduzir o botão que o usuário acabou de pressionar while(checaBotao() != NADA_ESCOLHIDO) ; // Agora vamos esperar que o usuário libere o botão aguarde(10); // Isso ajuda com toques duplos acidentais return button; } } return NADA_ESCOLHIDO; // Se chegarmos aqui, expiramos! } // Retorna um bit '1' na posição correspondente a VERMELHO, VERDE, etc. byte checaBotao(void) { if (digitalRead(BOTAO_VERMELHO) == 0) return(VERMELHO); else if (digitalRead(BOTAO_VERDE) == 0) return(VERDE); else if (digitalRead(BOTAO_AZUL) == 0) return(AZUL); else if (digitalRead(BOTAO_AMARELO) == 0) return(AMARELO); return(NADA_ESCOLHIDO); // Se nenhum botão for pressionado, não retorne nenhum } // Acenda um LED e toque o tom // Vermelho, superior esquerdo: 440Hz - 2.272ms - 1.136ms de pulso // Verde, superior direito: 880Hz - 1.136ms - pulso de 0.568ms // Azul, inferior esquerdo: pulso de 587.33Hz - 1.702ms - 0.851ms // Amarelo, inferior direito: 784Hz - 1,276ms - pulso de 0,638ms void emiteTom(byte cor, int duracao) { controlaLEDs(cor); // Ligue um dado LED // Reproduz o som associado ao LED fornecido switch(cor) { case VERMELHO: emitirSom(duracao, 1136); break; case VERDE: emitirSom(duracao, 568); break; case AZUL: emitirSom(duracao, 851); break; case AMARELO: emitirSom(duracao, 638); break; } controlaLEDs(DESLIGA); // Desligue todos os LEDs } // Alterna o buzzer a cada atrasoEmMiliSegundos, por uma duração. void emitirSom(int duracao, int atrasoEmMiliSegundos) { // Converter tempo total de reprodução de milissegundos para microssegundos long duracaoMicroSegundos = duracao * (long)1000; // Faz um loop até que o tempo restante de reprodução seja menor que um único atrasoEmMiliSegundos while (duracaoMicroSegundos > (atrasoEmMiliSegundos * 2)) { duracaoMicroSegundos -= atrasoEmMiliSegundos * 2; // Diminui o tempo de jogo restante // Alterna a campainha em várias velocidades digitalWrite(PIEZO1, LOW); digitalWrite(PIEZO2, HIGH); aguardeMicroSegundos(atrasoEmMiliSegundos); digitalWrite(PIEZO1, HIGH); digitalWrite(PIEZO2, LOW); aguardeMicroSegundos(atrasoEmMiliSegundos); } } // Reproduzir o som e as luzes do vencedor void toqueVencedor(void) { controlaLEDs(VERDE | AZUL); somGanhador(); controlaLEDs(VERMELHO | AMARELO); somGanhador(); controlaLEDs(VERDE | AZUL); somGanhador(); controlaLEDs(VERMELHO | AMARELO); somGanhador(); } // Som vencedor void somGanhador(void) { // Alterna a campainha em várias velocidades for (byte x = 250 ; x > 70 ; x--) { for (byte y = 0 ; y < 3 ; y++) { digitalWrite(PIEZO2, HIGH); digitalWrite(PIEZO1, LOW); aguardeMicroSegundos(x); digitalWrite(PIEZO2, LOW); digitalWrite(PIEZO1, HIGH); aguardeMicroSegundos(x); } } } // Toque o som perdedor / luzes void toquePerdedor(void) { controlaLEDs(VERMELHO | VERDE); emitirSom(255, 1500); controlaLEDs(AZUL | AMARELO); emitirSom(255, 1500); controlaLEDs(VERMELHO | VERDE); emitirSom(255, 1500); controlaLEDs(AZUL | AMARELO); emitirSom(255, 1500); } // Mostra uma tela de "modo de atração" enquanto aguarda o usuário pressionar o botão. void modoAtracao(void) { controlaLEDs(VERMELHO); aguarde(100); if (checaBotao() != NADA_ESCOLHIDO) modo = MODO_JOGO; controlaLEDs(AZUL); aguarde(100); if (checaBotao() != NADA_ESCOLHIDO) modo = MODO_JOGO; controlaLEDs(VERDE); aguarde(100); if (checaBotao() != NADA_ESCOLHIDO) modo = MODO_JOGO; controlaLEDs(AMARELO); aguarde(100); if (checaBotao() != NADA_ESCOLHIDO) modo = MODO_MUSICAL; } //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // As seguintes funções estão relacionadas apenas ao Easter Egg Musical int numeroDoLed = 0; // Mantém o controle de qual LED estamos ligando durante o ciclo musical // Não faça nada além de tocar a música // Esta função é ativada quando o usuário segura o botão inferior direito (amarelo) void tocarMusica(void) { // Ligue o LED inferior direito (amarelo) controlaLEDs(AMARELO); emiteTom(AMARELO, 150); controlaLEDs(VERMELHO | VERDE | AZUL); // Ligue os outros LEDs até você soltar o botão while(checaBotao() != NADA_ESCOLHIDO) ; // Aguarde até que o usuário pare de pressionar o botão controlaLEDs(NADA_ESCOLHIDO); // Desligue os LEDs aguarde(1000); // Espere um segundo antes de tocar música digitalWrite(PIEZO1, LOW); // configure o lado "PIEZO1" da campainha para ficar baixo, enquanto tocamos o tom no outro pino. while(checaBotao() == NADA_ESCOLHIDO) // Reproduzir música até você pressionar um botão { int limite = sizeof notas / sizeof *notas; // Descobre o tamanho do array // iterar sobre as notas/tempos da música: for (int i = 0; i < limite; i++) { mudaLED(); tone(PIEZO2, notas[i], tempos[i]); // Função nativa do arduino para reproduzir Tons. } } } // Cada vez que esta função é chamada, a placa se move para o próximo LED void mudaLED(void) { controlaLEDs(1 << numeroDoLed); // Mude o LED numeroDoLed++; // Ir para o próximo LED if(numeroDoLed > 3) numeroDoLed = 0; // Enrole o balcão, se necessário }