Введение
Помните классическую игру Simon Says? Это идеальный проект для изучения массивов, конечных автоматов и обработки пользовательского ввода на Arduino. В этом руководстве мы создадим полнофункциональную игру Simon Says с использованием четырех светодиодов и четырех кнопок, полностью смоделированную прямо в вашем браузере с помощью Velxio. Никакого оборудования не требуется!

Обзор схемы
Давайте рассмотрим компоненты и то, как они подключены.
Компоненты
| Компонент | ID | Назначение |
|---|---|---|
| Arduino Uno | arduino-uno | Мозг игры |
| Красный светодиод | led-red | Вывод для красной последовательности |
| Зеленый светодиод | led-green | Вывод для зеленой последовательности |
| Синий светодиод | led-blue | Вывод для синей последовательности |
| Желтый светодиод | led-yellow | Вывод для желтой последовательности |
| Красная кнопка | button-red | Ввод пользователя для красного |
| Зеленая кнопка | button-green | Ввод пользователя для зеленого |
| Синяя кнопка | button-blue | Ввод пользователя для синего |
| Желтая кнопка | button-yellow | Ввод пользователя для желтого |
Подключение
Анод (A) каждого светодиода подключается к цифровому выводу Arduino, а катод (C) — к GND через токоограничивающий резистор (симулируется внутренне). Кнопки подключаются одним контактом (1.l) к цифровому выводу, а другим контактом (2.l) к GND, используя внутренние подтягивающие резисторы Arduino.
- Красный светодиод: Пин 8 (красный провод) к аноду, катод к GND (черный провод).
- Зеленый светодиод: Пин 9 (зеленый провод) к аноду, катод к GND.
- Синий светодиод: Пин 10 (синий провод) к аноду, катод к GND.
- Желтый светодиод: Пин 11 (желтый провод) к аноду, катод к GND.
- Красная кнопка: Пин 2 (голубой провод) к 1.l, 2.l к GND.
- Зеленая кнопка: Пин 3 (голубой провод) к 1.l, 2.l к GND.
- Синяя кнопка: Пин 4 (голубой провод) к 1.l, 2.l к GND.
- Желтая кнопка: Пин 5 (голубой провод) к 1.l, 2.l к GND.
Все соединения с землей используют общий пин GND Arduino.
Разбор кода
Откройте редактор кода в Velxio, чтобы увидеть полный скетч.

Константы и переменные
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;
Мы определяем массивы для пинов светодиодов и кнопок, соответствующие схеме подключения. sequence хранит случайный шаблон (до 100 шагов). sequenceLength отслеживает, сколько шагов игрок должен повторить, а currentStep отслеживает прогресс игрока.
Настройка
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();
}
Мы устанавливаем пины светодиодов как выходы, а пины кнопок как входы с внутренней подтяжкой (поэтому кнопки читаются как LOW при нажатии). randomSeed(millis()) гарантирует разную последовательность в каждой игре. newGame() запускает первый раунд.
Игровая логика
newGame() сбрасывает длину последовательности до 1, добавляет случайный шаг и воспроизводит последовательность.
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() проходит по сохраненной последовательности, зажигая каждый светодиод на 300 мс с интервалом 500 мс.
Основной цикл
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 {
// Неправильная кнопка - игра окончена
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);
}
}
}
Цикл постоянно проверяет все кнопки. Когда кнопка нажата (LOW), он зажигает соответствующий светодиод. Если нажатая кнопка совпадает с ожидаемым шагом (sequence[currentStep]), мы продвигаемся дальше. Если игрок завершает последовательность, мы добавляем новый шаг и воспроизводим более длинную последовательность. Если ошибка, все светодиоды мигают три раза, и начинается новая игра.
Ключевые концепции
- Массивы: Использование массивов для хранения номеров пинов и игровой последовательности делает код масштабируемым и чистым.
- Внутренние подтягивающие резисторы:
INPUT_PULLUPустраняет необходимость во внешних резисторах; кнопки читаются как LOW при нажатии. - Антидребезг: Цикл
delay(300)иwhile(digitalRead(...)==LOW)обеспечивают простой антидребезг. - Случайность:
randomSeed(millis())иrandom()генерируют непредсказуемые последовательности. - Конечный автомат: Игра отслеживает
currentStepиsequenceLengthдля управления прогрессом.
Частые ошибки и советы по отладке
- Кнопки не реагируют? Проверьте, что пины кнопок установлены как
INPUT_PULLUPи правильно подключены (1.l к пину, 2.l к GND). - Светодиоды не горят? Убедитесь, что пины светодиодов установлены как
OUTPUTи соединения анода/катода правильные. - Последовательность слишком быстрая? Отрегулируйте значения
delay()вflashLED()иplaySequence(). - Игра неожиданно перезапускается? Убедитесь, что
randomSeed(millis())вызывается только один раз вsetup(). - Используйте Serial Monitor: Добавьте операторы
Serial.println()для отладки значений последовательности.
Предлагаемые расширения
- Добавьте зуммер: Воспроизводите тон для каждого цвета светодиода.
- Уровни сложности: Увеличивайте скорость по мере роста последовательности.
- Рекорд: Отслеживайте самую длинную пройденную последовательность.
- Многопользовательский режим: Чередуйте ходы между двумя игроками.
- Визуальная обратная связь: Используйте разную яркость или шаблоны светодиодов.
Попробуйте сами!
Готовы играть? Откройте живой пример на Velxio и запустите симуляцию. Нажимайте кнопки, чтобы повторить последовательность. Как далеко вы сможете зайти?
Запустить Simon Says на Velxio
Удачного конструирования!