Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Jogo da Memória com Arduino (Clone do Simon) – Tutorial Passo a Passo

Componentes Necessários

Componente Quantidade Observações
Arduino UNO R3 1 Controlador
Resistores 330Ω 4 Limite corrente dos LEDs
Resistores 10kΩ 4 Pull-down nos botões
LEDs coloridos (vermelho, verde, azul, amarelo) 4 Um por botão
Mini Speaker / Buzzer passivo 1 Opcional – sons do jogo
Push-buttons táteis (6x6mm) 4 Um por cor
Protoboard (meia ou inteira) 1 Montagem
Jumpers Conforme necessário Conexões

Sobre o Projeto

Recriação do clássico jogo Simon (Lançado em 1978) usando Arduino. O jogo apresenta uma sequência crescente de cores/luzes que o jogador deve repetir pressionando os botões correspondentes. A cada acerto, a sequência aumenta em um passo. Errou? Game over – a sequência final é mostrada para contagem de pontos.

Como Jogar

  1. Ligue o Arduino – aguarde ~3 segundos
  2. 5 piscadas lentas de todos os LEDs = início do jogo
  3. Um LED acende – pressione o botão correspondente
  4. O mesmo LED acende novamente + um novo – repita a sequência
  5. Continue até errar ou exceder o tempo (2s padrão)
  6. Piscada rápida de todos = Game Over → mostra sua sequência final → reinicia

Esquemático de Ligação

Circuito por Canal (×4)

       5V
        │
       [10kΩ] ← Pull-down
        │
Pino ●──┼──● Botão (NO)
  Arduino   │
        ┌───┘
        ▼
       GND

Pino PWM ●──[330Ω]──●│> LED │●── GND
  Arduino           (cor)

Pinout padrão do código:

Os pinos servem tanto como entrada (botão) quanto saída (LED) – o código alterna pinMode dinamicamente.

Código Fonte Completo


#define PLAYER_WAIT_TIME 2000  // Tempo máximo entre botões (ms)

byte sequence[100];      // Armazena a sequência gerada
byte curLen = 0;         // Tamanho atual da sequência
byte inputCount = 0;     // Botões corretos pressionados na rodada
byte lastInput = 0;      // Último botão pressionado
byte expRd = 0;          // LED/botão esperado
bool btnDwn = false;     // Flag: botão pressionado (debounce simples)
bool wait = false;       // Turno do jogador?
bool resetFlag = false;  // Flag: jogador errou
byte soundPin = 5;       // Buzzer
byte noPins = 4;         // Número de botões/LEDs
byte pins[] = {2, 13, 10, 8}; // Pinos (botão+LED compartilhado)

long inputTime = 0;      // Timer para timeout do jogador

void setup() {
  delay(3000);           // Segurança: tempo para reprogramar se travar
  Serial.begin(9600);
  Reset();
}

void setPinDirection(byte dir) {
  for (byte i = 0; i < noPins; i++) pinMode(pins[i], dir);
}

void writeAllPins(byte val) {
  for (byte i = 0; i < noPins; i++) digitalWrite(pins[i], val);
}

void beep(byte freq) {
  analogWrite(soundPin, 2);
  delay(freq);
  analogWrite(soundPin, 0);
  delay(freq);
}

void flash(short freq) {
  setPinDirection(OUTPUT);
  for (int i = 0; i < 5; i++) {
    writeAllPins(HIGH); beep(50); delay(freq);
    writeAllPins(LOW);  delay(freq);
  }
}

void Reset() {
  flash(500);  // 5 piscadas lentas = novo jogo
  curLen = 0; inputCount = 0; lastInput = 0;
  expRd = 0; btnDwn = false; wait = false; resetFlag = false;
}

void Lose() {
  flash(50);  // Piscada rápida = game over
}

void playSequence() {
  for (int i = 0; i < curLen; i++) {
    Serial.print("Seq: "); Serial.print(i); Serial.print(" Pin: "); Serial.println(sequence[i]);
    digitalWrite(sequence[i], HIGH); delay(500);
    digitalWrite(sequence[i], LOW);  delay(250);
  }
}

void DoLoseProcess() {
  Lose(); delay(1000);
  playSequence();  // Mostra sequência final (para contar pontos)
  delay(1000);
  Reset();
}

void loop() {
  if (!wait) {
    // ===== TURNO DO ARDUINO =====
    setPinDirection(OUTPUT);
    randomSeed(analogRead(A0));           // Seed aleatório (ruído analógico)
    sequence[curLen] = pins[random(0, noPins)]; // Novo passo aleatório
    curLen++;
    playSequence();                       // Mostra sequência completa
    beep(50);                             // Bipe "sua vez"
    wait = true;                          // Passa turno ao jogador
    inputTime = millis();                 // Inicia cronômetro
  } else {
    // ===== TURNO DO JOGADOR =====
    setPinDirection(INPUT);
    
    // Timeout
    if (millis() - inputTime > PLAYER_WAIT_TIME) {
      DoLoseProcess(); return;
    }
    
    if (!btnDwn) {
      expRd = sequence[inputCount];       // Botão esperado
      Serial.print("Esperado: "); Serial.println(expRd);
      
      // Verifica botões ERRADOS pressionados
      for (int i = 0; i < noPins; i++) {
        if (pins[i] == expRd) continue;   // Ignora o correto
        if (digitalRead(pins[i]) == HIGH) {
          lastInput = pins[i];
          resetFlag = true;               // Errou!
          btnDwn = true;
          Serial.print("Lido (errado): "); Serial.println(lastInput);
        }
      }
    }
    
    // Verifica botão CORRETO
    if (digitalRead(expRd) == HIGH && !btnDwn) {
      inputTime = millis();               // Reset timeout
      inputCount++;                       // Acerto!
      btnDwn = true;
      Serial.print("Lido (certo): "); Serial.println(expRd);
    } else {
      // Verifica soltura do botão (edge detection)
      if (btnDwn && digitalRead(lastInput) == LOW) {
        btnDwn = false;
        delay(20);                        // Debounce extra
        if (resetFlag) {
          DoLoseProcess();                // Errou → game over
        } else if (inputCount == curLen) {
          // Completou a sequência!
          wait = false;                   // Volta turno ao Arduino
          inputCount = 0;
          delay(1500);                    // Pausa antes da próxima rodada
        }
      }
    }
  }
}

Entendendo a Lógica do Jogo

Máquina de Estados

O jogo alterna entre dois estados principais:

Estado Variável Ações
Turno do Arduino wait == false Gera novo passo, mostra sequência completa, passa turno
Turno do Jogador wait == true Monitora botões, verifica acertos/erros, timeout

Detecção de Botão (Debounce + Edge)

Como os pinos alternam entre INPUT/OUTPUT, o código usa:

Geração Aleatória

randomSeed(analogRead(A0)) usa ruído térmico no pino flutuante A0 para semente verdadeiramente aleatória.

Personalizações e Dificuldade

Alterar Tempo de Resposta


// No topo do código:
#define PLAYER_WAIT_TIME 2000  // 2 segundos (padrão)
// Valores sugeridos:
#define PLAYER_WAIT_TIME 3000  // Fácil (3s)
#define PLAYER_WAIT_TIME 1000  // Difícil (1s)
#define PLAYER_WAIT_TIME 500   // Extremo (0.5s)

Adicionar Mais LEDs/Botões (até 6-8)

  1. Replicar o circuito para cada novo canal (resistores + LED + botão)
  2. Conectar a pinos livres (evite 0, 1 – Serial; 13 – LED built-in)
  3. Atualizar no código:
    byte noPins = 5;  // ou 6, 7, 8
    byte pins[] = {2, 13, 10, 8, 6, 7, 4, 3}; // Adicione seus pinos
    
  4. O array sequence[100] suporta até 100 passos (memória OK)

Diferentes Tons por Cor


// Frequências aproximadas (Hz) para notas musicais
int tones[] = {262, 330, 392, 523}; // Dó, Mi, Sol, Dó (oitava acima)

void playTone(byte pinIndex) {
  tone(soundPin, tones[pinIndex], 200);
}

Chame playTone(i) dentro de playSequence() e quando jogador acerta.

Dicas de Construção

Versão Portátil (Projeto Avançado)

O autor menciona versão portátil em caixa impressa 3D com bateria LiPo e carregador TP4056. Para inspiração avançada, veja: Lego Mini Memory Game (integração com carro Lego controlado).

Solução de Problemas

Sintoma Verificar
LED não acende no teste inicial Polaridade do LED, resistor 330Ω, pino correto no array pins[]
Botão não registra Pull-down 10kΩ no GND, fiação do botão (pinos opostos = mesmo circuito)
Jogo reinicia sozinho Ruído no pino A0 (randomSeed) – é normal; curto no botão – verifique solda
Buzzer não soa Pino 5 PWM? Buzzer passivo? Teste com tone(5, 1000, 500) no setup
Sequência muito rápida/lenta Ajuste delay(500) e delay(250) em playSequence()

Processo de manufatura

  1. Crie um Sistema Ambilight Impressionante para Monitor com Arduino
  2. Construa um Jogo em Tempo Real com Giroscópio: Arduino Nano + Sensor MPU-6050
  3. Display Interativo de Giroscópio com Anel NeoPixel e Arduino
  4. Construa o Clássico Jogo Pong no Arduino UNO com Display OLED – Tutorial Passo a Passo
  5. Controle USB para Jogos DIY com Arduino – Construa Seu Próprio Gamepad de Alto Desempenho
  6. Jogo Breakout Touch com Arduino: Arcade Clássico em LCD TFT 2,4″
  7. Pixie: Relógio de Pulso NeoPixel Baseado em Arduino – Elegante Timepiece DIY LED
  8. Pixel Chaser: Jogo LED Interativo de Um Toque com Arduino Nano
  9. Automatize o Jogo do Dinossauro do Chrome com Arduino e LDR
  10. Sistema Portátil de Câmera de Vigilância Remota