Skip to content

Instantly share code, notes, and snippets.

@wkoch
Last active May 23, 2022 17:30
Show Gist options
  • Save wkoch/1c23fd09d9a0974eb2c17297798b5b25 to your computer and use it in GitHub Desktop.
Save wkoch/1c23fd09d9a0974eb2c17297798b5b25 to your computer and use it in GitHub Desktop.

Revisions

  1. wkoch revised this gist May 23, 2022. 1 changed file with 18 additions and 20 deletions.
    38 changes: 18 additions & 20 deletions jogo.ino
    Original 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 13 // Número de rodadas para vencer o 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

    #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

    @@ -52,7 +48,7 @@ void setup()
    saida(PIEZO1);
    saida(PIEZO2);

    toqueVencedor(); // Ao ligar toque a música vencedor
    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);

    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
    toquePerdedor(); // Perdeu, toca som de derrota
    }
    // 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 toqueVencedor(void)
    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];
    int duracao = 1000 / tempos[i]; // Velocidade da música
    tone(PIEZO1, notas[i], duracao);
    aguarde(duracao * 1.3);
    aguarde(duracao * 1.3); // Pausa entre notas
    noTone(PIEZO1);
    if(checaBotao() != NADA_ESCOLHIDO)
    break;
    }
    }
    }
  2. wkoch revised this gist May 23, 2022. 3 changed files with 89 additions and 699 deletions.
    100 changes: 0 additions & 100 deletions do_zero.ino
    Original file line number Diff line number Diff line change
    @@ -1,100 +0,0 @@
    #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);
    }
    }
    299 changes: 89 additions & 210 deletions jogo.ino
    Original file line number Diff line number Diff line change
    @@ -1,37 +1,5 @@
    // 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 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
    #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 JOGO_MEMORIA 0
    #define MODO_MUSICAL 1
    #define MODO_JOGO 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 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

    // 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);
    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(LED_VERMELHO);
    saida(LED_VERDE);
    saida(LED_AZUL);
    saida(LED_AMARELO);

    SAIDA(PIEZO1);
    SAIDA(PIEZO2);
    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 == JOGO_MEMORIA)
    if (modoDeJogo == MODO_JOGO)
    {
    // Play no jogo de memória e recebe com resultado
    // 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()); // Gerador aleatório

    randomSeed(millis()); // Semeia o 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
    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 currentMove = 0 ; currentMove < rodadas ; currentMove++)
    for (byte atual = 0 ; atual < rodadas ; atual++)
    {
    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
    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 playMoves(void)
    void apresentaJogadas(void)
    {
    for (byte currentMove = 0 ; currentMove < rodadas ; currentMove++)
    for (byte atual = 0 ; atual < rodadas ; atual++)
    {
    toner(tabuleiro[currentMove], 150);
    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 add_to_moves(void)
    void adicionaJogada(void)
    {
    byte novoBotao = random(0, 4); //min (incluido), max (excluido)

    // Temos que converter esse número, 0 até 3, para CHOICEs
    // 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 aguarde_botao(void)
    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();
    byte botao = checaBotao();

    if (button != NADA_ESCOLHIDO)
    if (botao != NADA_ESCOLHIDO)
    {
    toner(button, 150); // Reproduzir o botão que o usuário acabou de pressionar

    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 button;
    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 toner(byte which, int buzz_length_ms)
    void emitirTom(byte qual, int duracao_milisegundos)
    {
    controlaLEDs(which); // Ligue um dado LED
    controlaLEDs(qual); // Ligue um dado LED

    // Reproduz o som associado ao LED fornecido
    switch(which)
    switch(qual)
    {
    case VERMELHO:
    buzz_sound(buzz_length_ms, 1136);
    emitirSom(duracao_milisegundos, 1136);
    break;
    case VERDE:
    buzz_sound(buzz_length_ms, 568);
    emitirSom(duracao_milisegundos, 568);
    break;
    case AZUL:
    buzz_sound(buzz_length_ms, 851);
    emitirSom(duracao_milisegundos, 851);
    break;
    case AMARELO:
    buzz_sound(buzz_length_ms, 638);
    emitirSom(duracao_milisegundos, 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)
    // 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 buzz_length_us = buzz_length_ms * (long)1000;
    long comprimento_microsegundos = duracao_milisegundos * (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))
    // Faz um loop até que o tempo restante de reprodução seja menor que uma única pausa_microsegundos
    while (comprimento_microsegundos > (pausa_microsegundos * 2))
    {
    buzz_length_us -= buzz_delay_us * 2; // Diminui o tempo de jogo restante
    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(buzz_delay_us);
    delayMicroseconds(pausa_microsegundos);

    digitalWrite(PIEZO1, HIGH);
    digitalWrite(PIEZO2, LOW);
    delayMicroseconds(buzz_delay_us);
    delayMicroseconds(pausa_microsegundos);
    }
    }

    // Reproduzir o som e as luzes do vencedor
    void toqueVencedor(void)
    {
    controlaLEDs(VERDE | AZUL);
    winner_sound();
    somVencedor();
    controlaLEDs(VERMELHO | AMARELO);
    winner_sound();
    somVencedor();
    controlaLEDs(VERDE | AZUL);
    winner_sound();
    somVencedor();
    controlaLEDs(VERMELHO | AMARELO);
    winner_sound();
    somVencedor();
    }

    // Som vencedor
    // Este é apenas um som (chato) único que criamos, não há mágica nisso
    void winner_sound(void)
    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);
    buzz_sound(255, 1500);
    emitirSom(255, 1500);

    controlaLEDs(AZUL | AMARELO);
    buzz_sound(255, 1500);
    emitirSom(255, 1500);

    controlaLEDs(VERMELHO | VERDE);
    buzz_sound(255, 1500);
    emitirSom(255, 1500);

    controlaLEDs(AZUL | AMARELO);
    buzz_sound(255, 1500);
    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);
    toner(AMARELO, 150);

    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(PIEZO1, LOW); // configure o lado "PIEZO1" da campainha para ficar baixo, enquanto tocamos o tom no outro pino.
    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 < 134; i++) {
    for (int i = 0; i < limite; i++) {
    mudaLED();
    tone(PIEZO2, melodia[i], tempo[i]);
    delay(tempo[i]);
    noTone(PIEZO2);
    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
    }
    389 changes: 0 additions & 389 deletions muito_mexido.ino
    Original file line number Diff line number Diff line change
    @@ -1,389 +0,0 @@
    #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
    }
  3. wkoch revised this gist May 23, 2022. 3 changed files with 728 additions and 127 deletions.
    100 changes: 100 additions & 0 deletions do_zero.ino
    Original 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);
    }
    }
    366 changes: 239 additions & 127 deletions jogo.ino
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,38 @@
    #define entrada(x) pinMode(x, INPUT_PULLUP)
    #define saida(x) pinMode(x, OUTPUT)
    // 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 aguardeMicroSegundos(x) delayMicroseconds(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 MODO_ATRACAO 0
    #define MODO_JOGO 1
    #define MODO_MUSICAL 2
    #define JOGO_MEMORIA 0
    #define MODO_MUSICAL 1

    // Variáveis de estado do jogo
    byte modo = MODO_ATRACAO; //Por padrão, vamos jogar o jogo da memória
    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 (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};
    // 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);
    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(LED_VERMELHO);
    SAIDA(LED_VERDE);
    SAIDA(LED_AZUL);
    SAIDA(LED_AMARELO);

    saida(PIEZO1);
    saida(PIEZO2);
    SAIDA(PIEZO1);
    SAIDA(PIEZO2);

    toqueVencedor(); // Ao ligar toque a música vencedor

    if (checaBotao() == AMARELO) tocarMusica();
    }

    void loop()
    {
    switch(modo)
    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)
    {
    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;
    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

    void redefinirJogo(void)
    // Jogue o jogo regular da memória
    // Retorna false se o jogador perde ou true se o jogador ganhar
    boolean jogoDaMemoria(void)
    {
    // Redefinir todo o tabuleiro
    for (int i = 0; i < ++rodadas; i++) {
    tabuleiro[i] = 0;
    }
    rodadas = 0;
    }
    randomSeed(millis()); // Gerador aleatório

    // Jogo da memória
    void jogoDaMemoria(void)
    {
    // redefinirJogo();
    randomSeed(millis()); // Semente do gerador aleatório
    rodadas = 0; // Redefinir o jogo para o começo

    while (rodadas < RODADAS_ATE_SER_CAMPEAO)
    {
    criaNovaJogada(); // Adicione uma cor nova no tabuleiro
    mostraParaMemorizar(); // Mostra o tabuleiro para memorizar
    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 jogadaAtual = 0; jogadaAtual < rodadas; jogadaAtual++)
    for (byte currentMove = 0 ; currentMove < rodadas ; currentMove++)
    {
    byte opcao = aguardarBotao(); // Veja o botão que o usuário pressiona
    byte choice = aguarde_botao(); // 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();
    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
    }

    // O jogador cumpriu todas as rodadas para ganhar!
    toqueVencedor();
    redefinirJogo();
    return true; // O jogador cumpriu todas as rodadas para ganhar!
    }

    // Reproduz o conteúdo atual dos movimentos do jogo
    void mostraParaMemorizar(void)
    void playMoves(void)
    {
    for (byte jogadaAtual = 0 ; jogadaAtual < rodadas ; jogadaAtual++)
    for (byte currentMove = 0 ; currentMove < rodadas ; currentMove++)
    {
    emiteTom(tabuleiro[jogadaAtual], 150);
    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 criaNovaJogada(void)
    void add_to_moves(void)
    {
    byte novaCor = random(0, 4); //min (incluido), max (excluido)
    byte novoBotao = 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;
    // 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++] = novaCor; // Adicionar este novo botão ao array do jogo
    tabuleiro[rodadas++] = novoBotao; // 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
    // 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 aguardarBotao(void)
    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)
    {
    emiteTom(button, 150); // Reproduzir o botão que o usuário acabou de pressionar
    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 emiteTom(byte cor, int duracao)
    void toner(byte which, int buzz_length_ms)
    {
    controlaLEDs(cor); // Ligue um dado LED
    controlaLEDs(which); // Ligue um dado LED

    // Reproduz o som associado ao LED fornecido
    switch(cor)
    switch(which)
    {
    case VERMELHO:
    emitirSom(duracao, 1136);
    buzz_sound(buzz_length_ms, 1136);
    break;
    case VERDE:
    emitirSom(duracao, 568);
    buzz_sound(buzz_length_ms, 568);
    break;
    case AZUL:
    emitirSom(duracao, 851);
    buzz_sound(buzz_length_ms, 851);
    break;
    case AMARELO:
    emitirSom(duracao, 638);
    buzz_sound(buzz_length_ms, 638);
    break;
    }

    controlaLEDs(DESLIGA); // Desligue todos os LEDs
    }

    // Alterna o buzzer a cada atrasoEmMiliSegundos, por uma duração.
    void emitirSom(int duracao, int atrasoEmMiliSegundos)
    // 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 duracaoMicroSegundos = duracao * (long)1000;
    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 atrasoEmMiliSegundos
    while (duracaoMicroSegundos > (atrasoEmMiliSegundos * 2))
    // 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))
    {
    duracaoMicroSegundos -= atrasoEmMiliSegundos * 2; // Diminui o tempo de jogo restante
    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);
    aguardeMicroSegundos(atrasoEmMiliSegundos);
    delayMicroseconds(buzz_delay_us);

    digitalWrite(PIEZO1, HIGH);
    digitalWrite(PIEZO2, LOW);
    aguardeMicroSegundos(atrasoEmMiliSegundos);
    delayMicroseconds(buzz_delay_us);
    }
    }

    // Reproduzir o som e as luzes do vencedor
    void toqueVencedor(void)
    {
    controlaLEDs(VERDE | AZUL);
    somGanhador();
    winner_sound();
    controlaLEDs(VERMELHO | AMARELO);
    somGanhador();
    winner_sound();
    controlaLEDs(VERDE | AZUL);
    somGanhador();
    winner_sound();
    controlaLEDs(VERMELHO | AMARELO);
    somGanhador();
    winner_sound();
    }

    // Som vencedor
    void somGanhador(void)
    // 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);
    aguardeMicroSegundos(x);
    delayMicroseconds(x);

    digitalWrite(PIEZO2, LOW);
    digitalWrite(PIEZO1, HIGH);
    aguardeMicroSegundos(x);
    delayMicroseconds(x);
    }
    }
    }
    @@ -315,36 +423,39 @@ void somGanhador(void)
    void toquePerdedor(void)
    {
    controlaLEDs(VERMELHO | VERDE);
    emitirSom(255, 1500);
    buzz_sound(255, 1500);

    controlaLEDs(AZUL | AMARELO);
    emitirSom(255, 1500);
    buzz_sound(255, 1500);

    controlaLEDs(VERMELHO | VERDE);
    emitirSom(255, 1500);
    buzz_sound(255, 1500);

    controlaLEDs(AZUL | AMARELO);
    emitirSom(255, 1500);
    buzz_sound(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;
    while(true)
    {
    controlaLEDs(VERMELHO);
    aguarde(100);
    if (checaBotao() != NADA_ESCOLHIDO) return;

    controlaLEDs(AZUL);
    aguarde(100);
    if (checaBotao() != NADA_ESCOLHIDO) modo = MODO_JOGO;
    controlaLEDs(AZUL);
    aguarde(100);
    if (checaBotao() != NADA_ESCOLHIDO) return;

    controlaLEDs(VERDE);
    aguarde(100);
    if (checaBotao() != NADA_ESCOLHIDO) modo = MODO_JOGO;
    controlaLEDs(VERDE);
    aguarde(100);
    if (checaBotao() != NADA_ESCOLHIDO) return;

    controlaLEDs(AMARELO);
    aguarde(100);
    if (checaBotao() != NADA_ESCOLHIDO) modo = MODO_MUSICAL;
    controlaLEDs(AMARELO);
    aguarde(100);
    if (checaBotao() != NADA_ESCOLHIDO) return;
    }
    }

    //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    @@ -357,7 +468,7 @@ void tocarMusica(void)
    {
    // Ligue o LED inferior direito (amarelo)
    controlaLEDs(AMARELO);
    emiteTom(AMARELO, 150);
    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
    {
    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++) {
    // iterar sobre as notas da melodia:
    for (int i = 0; i < 134; i++) {
    mudaLED();
    tone(PIEZO2, notas[i], tempos[i]); // Função nativa do arduino para reproduzir Tons.
    tone(PIEZO2, melodia[i], tempo[i]);
    delay(tempo[i]);
    noTone(PIEZO2);
    }
    }
    }
    389 changes: 389 additions & 0 deletions muito_mexido.ino
    Original 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
    }
  4. wkoch created this gist May 22, 2022.
    390 changes: 390 additions & 0 deletions jogo.ino
    Original 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
    }