Игра «Память» на Arduino (клон Simon) — пошаговая инструкция
Компоненты и материалы
| Компонент | Количество | Примечание |
|---|---|---|
| Arduino Uno | 1 | |
| Светодиоды разного цвета (красный, зеленый, синий, желтый) | 4 | По одному на кнопку |
| Тактильные кнопки (6x6 мм) | 4 | Одна под каждый светодиод |
| Резисторы 330 Ом | 4 | Ограничение тока светодиодов |
| Резисторы 10 кОм | 4 | Pull-down для кнопок |
| Пьезо-пищалка (мини-динамик) | 1 | Опционально, для звука |
| Макетная плата (полноразмерная) | 1 | |
| Перемычки | 1 набор |
О проекте
Классическая игра «Simon» (1978): 4 цветные кнопки загораются в случайной последовательности, игрок должен повторить её. Каждый раунд последовательность удлиняется на 1. Игра заканчивается при ошибке или таймауте (2 сек на нажатие). Реализация на Arduino Uno с минимальными компонентами.
Схема подключения
Каждая кнопка + светодиод делят один пин Arduino (через резисторы). Пин переключается между OUTPUT (светодиод) и INPUT (кнопка).
- Пины (по умолчанию): 2, 13, 10, 8
- Пьезо-пищалка: пин 5 (PWM)
- Pull-down 10кОм на каждом пине кнопки
- 330Ом последовательно со светодиодом
Схема в формате Fritzing (.fzz) прилагается.
Алгоритм работы
- Старт: 3 сек пауза, 5 медленных вспышек всех светодиодов.
- Ход Arduino: добавляет случайный пин в последовательность, воспроизводит всю последовательность (свет + звук).
- Ход игрока: ждет нажатий. Проверяет каждое нажатие с эталоном. Таймаут 2 сек = проигрыш.
- Проигрыш: быстрая вспышка всех светодиодов, показ последней правильной последовательности (для подсчета очков), рестарт.
Настройка сложности
Измените константу в начале скетча:
#define PLAYER_WAIT_TIME 2000 // мс на нажатие (уменьшите для сложнее)
Можно добавить 5-й, 6-й светодиод: расширьте массивы pins[] и noPins.
Полный код игры
#define PLAYER_WAIT_TIME 2000
byte sequence[100];
byte curLen = 0;
byte inputCount = 0;
byte lastInput = 0;
byte expRd = 0;
bool btnDwn = false;
bool wait = false;
bool resetFlag = false;
byte soundPin = 5;
byte noPins = 4;
byte pins[] = {2, 13, 10, 8};
long inputTime = 0;
void setup() {
delay(3000); // Важно: задержка для восстановления после загрузки
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);
curLen = 0; inputCount = 0; lastInput = 0; expRd = 0;
btnDwn = false; wait = false; resetFlag = false;
}
void Lose() { flash(50); }
void playSequence() {
for (int i = 0; i < curLen; i++) {
digitalWrite(sequence[i], HIGH); delay(500);
digitalWrite(sequence[i], LOW); delay(250);
}
}
void DoLoseProcess() {
Lose(); delay(1000);
playSequence(); delay(1000);
Reset();
}
void loop() {
if (!wait) { // Ход Arduino
setPinDirection(OUTPUT);
randomSeed(analogRead(A0));
sequence[curLen] = pins[random(0, noPins)];
curLen++;
playSequence();
beep(50);
wait = true;
inputTime = millis();
} else { // Ход игрока
setPinDirection(INPUT);
if (millis() - inputTime > PLAYER_WAIT_TIME) { DoLoseProcess(); return; }
if (!btnDwn) {
expRd = sequence[inputCount];
for (int i = 0; i < noPins; i++) {
if (pins[i] == expRd) continue;
if (digitalRead(pins[i]) == HIGH) { // Неправильная кнопка
lastInput = pins[i];
resetFlag = true;
btnDwn = true;
}
}
}
if (digitalRead(expRd) == HIGH && !btnDwn) { // Правильная кнопка
inputTime = millis();
inputCount++;
btnDwn = true;
} else {
if (btnDwn && digitalRead(lastInput) == LOW) { // Отпустили
btnDwn = false;
delay(20);
if (resetFlag) { DoLoseProcess(); }
else {
if (inputCount == curLen) { // Раунд пройден
wait = false;
inputCount = 0;
delay(1500);
}
}
}
}
}
}
Советы
- Первым делом в
setup()ставьтеdelay(3000)— спасает от зацикливания при ошибках. - Кнопки могут выпадать из макетки — припаяйте их к штырьковым разъемам или используйте PCB.
- Для переносной версии: Arduino Pro Mini + LiPo + корпус (пример: Lego Mini Memory Game).
Производственный процесс
- Создание потрясающей системы Ambilight для монитора на Arduino
- Создание игры в реальном времени на Arduino Nano с гироскопом MPU-6050 и OLED-дисплеем
- Интерактивный гироскопический LED-дисплей на NeoPixel Ring и Arduino
- Создание классической игры Pong на Arduino UNO с OLED-дисплеем: пошаговый урок
- DIY USB-геймпад на Arduino: собственный высокопроизводительный контроллер
- Arduino Breakout на сенсорном TFT 2.4″: классическая аркада своими руками
- Pixie: DIY-наручные часы на Arduino Pro Mini и NeoPixel — стильный светодиодный тахометр времени
- Pixel Chaser: игра на один тап с NeoPixel Ring и Arduino Nano
- Автоматизация игры «Динозавр» в Chrome на Arduino и LDR с Python
- Переносная система видеонаблюдения: робот с камерой на Raspberry Pi и Arduino