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
- Ligue o Arduino – aguarde ~3 segundos
- 5 piscadas lentas de todos os LEDs = início do jogo
- Um LED acende – pressione o botão correspondente
- O mesmo LED acende novamente + um novo – repita a sequência
- Continue até errar ou exceder o tempo (2s padrão)
- 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:
- Botão/LED 0: Pino 2
- Botão/LED 1: Pino 13
- Botão/LED 2: Pino 10
- Botão/LED 3: Pino 8
- Buzzer: Pino 5 (PWM)
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:
btnDwn: evita leituras múltiplas enquanto botão segurado- Detecção de borda de descida (
HIGH → LOW) para confirmar pressionamento único delay(20)após soltura para debounce mecânico
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)
- Replicar o circuito para cada novo canal (resistores + LED + botão)
- Conectar a pinos livres (evite 0, 1 – Serial; 13 – LED built-in)
- Atualizar no código:
byte noPins = 5; // ou 6, 7, 8 byte pins[] = {2, 13, 10, 8, 6, 7, 4, 3}; // Adicione seus pinos - 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
- Protoboard: use jumpers curtos; botões 6x6mm saem fácil – prenda com fita ou solda em perfboard
- LEDs: difusos ficam melhor que transparentes; teste polaridade antes
- Buzzer passivo: precisa de
tone()ou PWM; buzzer ativo (contínuo) não permite variação de tom - Delay(3000) no setup(): essencial! Permite recuperar Arduino se código travar (reprogramar antes do loop)
- Alimentação: USB do PC basta; para portátil, power bank 5V
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
- Crie um Sistema Ambilight Impressionante para Monitor com Arduino
- Construa um Jogo em Tempo Real com Giroscópio: Arduino Nano + Sensor MPU-6050
- Display Interativo de Giroscópio com Anel NeoPixel e Arduino
- Construa o Clássico Jogo Pong no Arduino UNO com Display OLED – Tutorial Passo a Passo
- Controle USB para Jogos DIY com Arduino – Construa Seu Próprio Gamepad de Alto Desempenho
- Jogo Breakout Touch com Arduino: Arcade Clássico em LCD TFT 2,4″
- Pixie: Relógio de Pulso NeoPixel Baseado em Arduino – Elegante Timepiece DIY LED
- Pixel Chaser: Jogo LED Interativo de Um Toque com Arduino Nano
- Automatize o Jogo do Dinossauro do Chrome com Arduino e LDR
- Sistema Portátil de Câmera de Vigilância Remota