В этом проекте мы создадим собственную версию аркадной логической игры Touch me компании Atari, используя четыре светодиода, четыре кнопки, пьезоизлучатель, несколько резисторов и перемычки.
- Плата Arduino Uno
- Макетная плата
- Перемычки
- Пьезоизлучатель
- 4 четырехконтактные кнопки
- 4 светодиода
- 4 резистор с сопротивлением 20 Ом
Требуемые библиотеки
- Tone
Нам понадобитсяПринцип работы
В оригинальной игре компании Atari было четыре оборудованных светодиодами цветных панели, которые загорались в определенном порядке, после чего игрок должен был повторить комбинацию (см. рис. 8.1).
Наша игра на запоминание воспроизводит короткую начальную мелодию и мигает светодиодами в определенном порядке. После того, как вы повторите комбинацию, нажав кнопки в соответствующем порядке, программа выдаст комбинацию, усложненную на 1 шаг. Так происходит при каждом корректном вводе, чтобы усложнить процесс игры. Если вы ошибетесь при повторении комбинации, игра сбрасывается на начальный уровень.
Рисунок 8.1: Оригинальная игра Touch MeСборка
1. Установите кнопки на макетную плату так, чтобы они перекрывали собой канавку (словно мостики), а контакты А и В оказались на одной стороне от канавки, а С и D — на другой (см. рис. 8.2). (См. проект 1 для получения подробной информации о том, как работает кнопка.)
2. Подключите контакт В каждой кнопки к шине заземления макетной платы, а саму шину — к контакту GND платы Arduino.
Рисунок 8.2: Схема четырехконтактного кнопочного переключателя3. Подключите контакт D каждой кнопки к цифровым контактам 2-5 платы Arduino (по порядку).
Установите светодиоды в макетную плату так, чтобы короткая ножка (катод) каждого из них была соединена с контактом С каждой кнопки. Установите длинную ножку (анод) каждого светодиода в отверстие справа, как показано на рис. 8.3.
Подключение5. Установите на макетную плату резисторы с сопротивлением 220 Ом так, чтобы одна из ножек каждого резистора была соединена с длинной ножкой (анодом) каждого светодиода. Другую ножку каждого резистора с помощью перемычек подключите к Arduino к контактам 8-11, как показано на рис. 8.3.
ПодключениеУбедитесь, что красный светодиод, подключенный к контакту 11 платы Arduino, соединен с кнопкой, подключенной к контакту 5. Желтый светодиод, подключенный к контакту 10, соединен с кнопкой, подключенной к контакту 4. Зеленый светодиод, подключенный к контакту 9, соединен с кнопкой, подключенной к контакту 3. Синий светодиод, подключенный к контакту 8, соединен с кнопкой, подключенной к контакту 2.
Подключение7. Подключите черный провод пьезоизлучателя напрямую к контакту GND платы Arduino, а красный — к контакту 12 на плате Arduino.
8. Убедитесь, что ваша цепь соответствует схеме на рис. 8.3, а затем загрузите в память Arduino код скетча, приведенный в разделе «Скетч» далее в этом проекте.
Рисунок 8.3: Принципиальная схема игры на запоминаниеСкетч
Скетч генерирует случайную последовательность, в которой будут зажигаться светодиоды. Случайное значение переменной у, генерируемое в цикле последовательности, определяет, на какой светодиод подается питание (например, если переменной у присваивается значение 2, загорается светодиод, подключенный к контакту 2). Во время игры вы должны запомнить последовательность и повторить ее, чтобы перейти на следующий уровень.
На каждом уровне предыдущая последовательность повторяется и добавляется еще одна вспышка случайного светодиода. Вспышка каждого светодиода сопровождается собственным тоном пьезоизлучателя, поэтому мелодия также меняется. Если вы ошиблись при повторе последовательности, программа перезапускается и воспроизводит другую последовательность. Для корректной компиляции скетча нужно подключить библиотеку Tone (доступную по адресу https://vk.com/s/v1/doc/V3o2X74YY7UA_jYg--f2Mk_V2Fny6W6OuwYaqlnTAnVeJmh9KTQ). Подробнее см. раздел «Библиотеки» в статье "Начало работы с Arduino".
#include <Tone.h>Tone speakerpin; int starttune[] = {NOTE_C4, NOTE_F4, NOTE_C4, NOTE_F4, NOTE_C4, NOTE_F4, NOTE_C4, NOTE_F4, NOTE_G4, NOTE_F4, NOTE_E4, NOTE_F4, NOTE_G4 }; int duration2[] = {100, 200, 100, 200, 100, 400, 100, 100, 100, 100, 200, 100, 500 }; int note[] = {NOTE_C4, NOTE_C4, NOTE_G4, NOTE_C5, NOTE_G4, NOTE_C5}; int duration[] = {100, 100, 100, 300, 100, 300}; boolean button[] = {2, 3, 4, 5}; // Контакты, к которым подключены кнопки boolean ledpin[] = {8, 9, 10, 11}; // Контакты, к которым подключены светодиоды int turn = 0; // Счетчик включений int buttonstate = 0; // Проверка состояния кнопки int randomArray[100]; // Массив, содержащий до 100 вводов int inputArray[100]; void setup() { Serial.begin(9600); speakerpin.begin(12); // Контакт, к которому подключен пьезоизлучатель for (int x = 0; x < 4; x++) { pinMode(ledpin[x], OUTPUT); // Перевод контактов, к которым подключены светодиоды, в режим вывода } for (int x = 0; x < 4; x++) { pinMode(button[x], INPUT); // Перевод контактов, к которым подключены кнопки, в режим ввода digitalWrite(button[x], HIGH); // Включение внутреннего подтягивания; кнопки активны в верхнем положении (логическая инверсия) } // Генерация "большей случайности" функции randomArray, чтобы последовательность каждый раз менялась randomSeed(analogRead(0)); for (int thisNote = 0; thisNote < 13; thisNote ++) { speakerpin.play(starttune[thisNote]); // Воспроизведение следующей ноты if (thisNote == 0 || thisNote == 2 || thisNote == 4 || thisNote == 6) { // Продолжение ноты digitalWrite(ledpin[0], HIGH); } if (thisNote == 1 || thisNote == 3 || thisNote == 5 || thisNote == 7 || thisNote == 9 || thisNote == 11) { digitalWrite(ledpin[1], HIGH); } if (thisNote == 8 || thisNote == 12) { digitalWrite(ledpin[2], HIGH); } if (thisNote == 10) { digitalWrite(ledpin[3], HIGH); } delay(duration2[thisNote]); speakerpin.stop(); // Остановка для воспроизведения следующей ноты digitalWrite(ledpin[0], LOW); digitalWrite(ledpin[1], LOW); digitalWrite(ledpin[2], LOW); digitalWrite(ledpin[3], LOW); delay(25); } delay(1000); } void loop() { // Генерация массива, назначаемого игроку for (int y = 0; y <= 99; y++) { digitalWrite(ledpin[0], HIGH); digitalWrite(ledpin[1], HIGH); digitalWrite(ledpin[2], HIGH); digitalWrite(ledpin[3], HIGH); // Воспроизведение следующей ноты for (int thisNote = 0; thisNote < 6; thisNote ++) { speakerpin.play(note[thisNote]); // Продолжение ноты delay(duration[thisNote]); // Остановка для воспроизведения следующей ноты speakerpin.stop(); delay(25); } digitalWrite(ledpin[0], LOW); digitalWrite(ledpin[1], LOW); digitalWrite(ledpin[2], LOW); digitalWrite(ledpin[3], LOW); delay(1000); // Ограничения переменной turn for (int y = turn; y <= turn; y++) { Serial.println(""); Serial.print("Turn: "); Serial.print(y); Serial.println(""); randomArray[y] = random(1, 5); // Присвоение случайного номера (1-4) // Включение светодиодов в случайном порядке for (int x = 0; x <= turn; x++) { Serial.print(randomArray[x]); for (int y = 0; y < 4; y++) { if (randomArray[x] == 1 && ledpin[y] == 8) { digitalWrite(ledpin[y], HIGH); speakerpin.play(NOTE_G3, 100); delay(400); digitalWrite(ledpin[y], LOW); delay(100); } if (randomArray[x] == 2 && ledpin[y] == 9) { digitalWrite(ledpin[y], HIGH); speakerpin.play(NOTE_A3, 100); delay(400); digitalWrite(ledpin[y], LOW); delay(100); } if (randomArray[x] == 3 && ledpin[y] == 10) { digitalWrite(ledpin[y], HIGH); speakerpin.play(NOTE_B3, 100); delay(400); digitalWrite(ledpin[y], LOW); delay(100); } if (randomArray[x] == 4 && ledpin[y] == 11) { digitalWrite(ledpin[y], HIGH); speakerpin.play(NOTE_C4, 100); delay(400); digitalWrite(ledpin[y], LOW); delay(100); } } } } input(); } } // Проверка ввода на соответствие последовательности void input() { for (int x = 0; x <= turn;) { for (int y = 0; y < 4; y++) { buttonstate = digitalRead(button[y]); // Проверка нажатия кнопки if (buttonstate == LOW && button[y] == 2) { digitalWrite(ledpin[0], HIGH); speakerpin.play(NOTE_G3, 100); delay(200); digitalWrite(ledpin[0], LOW); inputArray[x] = 1; delay(250); Serial.print(" "); Serial.print(1); // Проверка введенного пользователем значения на соответствие сгенерированному массиву if (inputArray[x] != randomArray[x]) { fail(); // If not, fail function is called } x++; } if (buttonstate == LOW && button[y] == 3) { digitalWrite(ledpin[1], HIGH); speakerpin.play(NOTE_A3, 100); delay(200); digitalWrite(ledpin[1], LOW); inputArray[x] = 2; delay(250); Serial.print(" "); Serial.print(2); if (inputArray[x] != randomArray[x]) { fail(); } x++; } if (buttonstate == LOW && button[y] == 4) { digitalWrite(ledpin[2], HIGH); speakerpin.play(NOTE_B3, 100); delay(200); digitalWrite(ledpin[2], LOW); inputArray[x] = 3; delay(250); Serial.print(" "); Serial.print(3); if (inputArray[x] != randomArray[x]) { fail(); } x++; } if (buttonstate == LOW && button[y] == 5) { digitalWrite(ledpin[3], HIGH); speakerpin.play(NOTE_C4, 100); delay(200); digitalWrite(ledpin[3], LOW); inputArray[x] = 4; delay(250); Serial.print(" "); Serial.print(4); if (inputArray[x] != randomArray[x]) { fail(); } x++; } } } delay(500); turn++; // Увеличение значения переменной turn } // Функция, используемая в случае, если игрок ошибся в последовательности void fail() { for (int y = 0; y <= 2; y++) { // Flash lights to indicate failure digitalWrite(ledpin[0], HIGH); digitalWrite(ledpin[1], HIGH); digitalWrite(ledpin[2], HIGH); digitalWrite(ledpin[3], HIGH); speakerpin.play(NOTE_G3, 300); delay(200); digitalWrite(ledpin[0], LOW); digitalWrite(ledpin[1], LOW); digitalWrite(ledpin[2], LOW); digitalWrite(ledpin[3], LOW); speakerpin.play(NOTE_C3, 300); delay(200); } delay(500); turn = -1; // Сбросить значение переменной turn для начала новой игры }
Теги: