Introdução
Lembra do clássico jogo Simon Says? É o projeto perfeito para aprender sobre arrays, máquinas de estado e manipulação de entrada do usuário no Arduino. Neste tutorial, vamos construir um jogo Simon Says totalmente funcional usando quatro LEDs e quatro botões, tudo simulado diretamente no seu navegador com o Velxio. Nenhum hardware necessário!

Visão Geral do Circuito
Vamos ver os componentes e como eles estão conectados.
Componentes
| Componente | ID | Finalidade |
|---|---|---|
| Arduino Uno | arduino-uno | O cérebro do jogo |
| LED Vermelho | led-red | Saída para a sequência vermelha |
| LED Verde | led-green | Saída para a sequência verde |
| LED Azul | led-blue | Saída para a sequência azul |
| LED Amarelo | led-yellow | Saída para a sequência amarela |
| Botão Vermelho | button-red | Entrada do usuário para vermelho |
| Botão Verde | button-green | Entrada do usuário para verde |
| Botão Azul | button-blue | Entrada do usuário para azul |
| Botão Amarelo | button-yellow | Entrada do usuário para amarelo |
Conexões
O ânodo (A) de cada LED conecta-se a um pino digital do Arduino, e o cátodo (C) vai para o GND através de um resistor limitador de corrente (simulado internamente). Os botões são conectados com uma perna (1.l) a um pino digital e a outra perna (2.l) ao GND, usando os resistores de pull-up internos do Arduino.
- LED Vermelho: Pino 8 (fio vermelho) ao ânodo, cátodo ao GND (fio preto).
- LED Verde: Pino 9 (fio verde) ao ânodo, cátodo ao GND.
- LED Azul: Pino 10 (fio azul) ao ânodo, cátodo ao GND.
- LED Amarelo: Pino 11 (fio amarelo) ao ânodo, cátodo ao GND.
- Botão Vermelho: Pino 2 (fio azul claro) ao 1.l, 2.l ao GND.
- Botão Verde: Pino 3 (fio azul claro) ao 1.l, 2.l ao GND.
- Botão Azul: Pino 4 (fio azul claro) ao 1.l, 2.l ao GND.
- Botão Amarelo: Pino 5 (fio azul claro) ao 1.l, 2.l ao GND.
Todas as conexões de terra compartilham o pino GND do Arduino.
Explicação do Código
Abra o editor de código no Velxio para ver o sketch completo.

Constantes e Variáveis
const int LED_PINS[] = {8, 9, 10, 11};
const int BUTTON_PINS[] = {2, 3, 4, 5};
const int NUM_LEDS = 4;
int sequence[100];
int sequenceLength = 0;
int currentStep = 0;
Definimos arrays para os pinos dos LEDs e botões, correspondendo às conexões. sequence armazena o padrão aleatório (até 100 passos). sequenceLength rastreia quantos passos o jogador deve repetir, e currentStep rastreia o progresso do jogador.
Setup
void setup() {
Serial.begin(9600);
for (int i = 0; i < NUM_LEDS; i++) {
pinMode(LED_PINS[i], OUTPUT);
pinMode(BUTTON_PINS[i], INPUT_PULLUP);
}
randomSeed(millis());
newGame();
}
Definimos os pinos dos LEDs como saídas e os pinos dos botões como entradas com pull-ups internos (assim os botões leem LOW quando pressionados). randomSeed(millis()) garante uma sequência diferente a cada jogo. newGame() inicia a primeira rodada.
Lógica do Jogo
newGame() redefine o comprimento da sequência para 1, adiciona um passo aleatório e reproduz a sequência.
void newGame() {
sequenceLength = 1;
currentStep = 0;
addToSequence();
playSequence();
}
void addToSequence() {
sequence[sequenceLength - 1] = random(0, NUM_LEDS);
}
void playSequence() {
for (int i = 0; i < sequenceLength; i++) {
flashLED(sequence[i]);
delay(500);
}
}
void flashLED(int led) {
digitalWrite(LED_PINS[led], HIGH);
delay(300);
digitalWrite(LED_PINS[led], LOW);
}
playSequence() percorre a sequência armazenada, piscando cada LED por 300ms com um intervalo de 500ms.
Loop Principal
void loop() {
for (int i = 0; i < NUM_LEDS; i++) {
if (digitalRead(BUTTON_PINS[i]) == LOW) {
flashLED(i);
if (i == sequence[currentStep]) {
currentStep++;
if (currentStep == sequenceLength) {
delay(1000);
sequenceLength++;
currentStep = 0;
addToSequence();
playSequence();
}
} else {
// Botão errado - fim de jogo
for (int j = 0; j < 3; j++) {
for (int k = 0; k < NUM_LEDS; k++) {
digitalWrite(LED_PINS[k], HIGH);
}
delay(200);
for (int k = 0; k < NUM_LEDS; k++) {
digitalWrite(LED_PINS[k], LOW);
}
delay(200);
}
newGame();
}
delay(300);
while (digitalRead(BUTTON_PINS[i]) == LOW);
}
}
}
O loop verifica continuamente todos os botões. Quando um botão é pressionado (LOW), ele pisca o LED correspondente. Se o botão pressionado corresponder ao passo esperado (sequence[currentStep]), avançamos. Se o jogador completar a sequência, adicionamos um novo passo e reproduzimos a sequência mais longa. Se estiver errado, todos os LEDs piscam três vezes e um novo jogo começa.
Conceitos Principais
- Arrays: Usar arrays para armazenar números de pinos e a sequência do jogo torna o código escalável e limpo.
- Resistores de Pull-up Internos:
INPUT_PULLUPelimina resistores externos; botões leem LOW quando pressionados. - Debounce: O
delay(300)e o loopwhile(digitalRead(...)==LOW)fornecem um debounce simples. - Aleatoriedade:
randomSeed(millis())erandom()geram sequências imprevisíveis. - Máquina de Estados: O jogo rastreia
currentStepesequenceLengthpara gerenciar o progresso.
Problemas Comuns e Dicas de Depuração
- Botões não respondem? Verifique se os pinos dos botões estão configurados como
INPUT_PULLUPe conectados corretamente (1.l ao pino, 2.l ao GND). - LEDs não acendem? Verifique se os pinos dos LEDs estão como
OUTPUTe as conexões de ânodo/cátodo estão corretas. - Sequência muito rápida? Ajuste os valores de
delay()emflashLED()eplaySequence(). - Jogo reinicia inesperadamente? Certifique-se de que
randomSeed(millis())é chamado apenas uma vez emsetup(). - Use o Monitor Serial: Adicione instruções
Serial.println()para depurar os valores da sequência.
Extensões Sugeridas
- Adicione um buzzer: Toque um tom para cada cor de LED.
- Níveis de dificuldade: Aumente a velocidade conforme a sequência cresce.
- Pontuação máxima: Registre a sequência mais longa alcançada.
- Multijogador: Alterne turnos entre dois jogadores.
- Feedback visual: Use diferentes intensidades ou padrões de LED.
Experimente Você Mesmo!
Pronto para jogar? Abra o exemplo ao vivo no Velxio e inicie a simulação. Pressione os botões para repetir a sequência. Até onde você consegue chegar?
Feliz construção!