Двухпользовательская реакционная игра «Кто быстрее?» на базе микроконтроллерной платформы Arduino

XXVII Международный конкурс научно-исследовательских и творческих работ учащихся
Старт в науке

Двухпользовательская реакционная игра «Кто быстрее?» на базе микроконтроллерной платформы Arduino

Соловьев В.И. 1
1МБОУ «Лицей «Технический» г.о. Самара
Андриянова Т.Н. 1
1МБОУ «Лицей «Технический» г.о. Самара
Автор работы награжден дипломом победителя II степени
Текст работы размещён без изображений и формул.
Полная версия работы доступна во вкладке "Файлы работы" в формате PDF

Введение

Микроконтроллерные платформы, такие как Arduino, широко применяются в образовательном процессе для изучения основ встраиваемых систем. Их использование позволяет наглядно продемонстрировать принципы работы электронных устройств, а также связать теоретические знания с практической реализацией [1, 5].

В работе рассматривается процесс разработки электронного устройства для измерения скорости реакции двух пользователей, реализованного на базе микроконтроллерной платформы Arduino Uno. Устройство использует световую и звуковую индикацию, кнопки ввода и жидкокристаллический дисплей для организации игрового процесса и отображения результатов. Проект носит учебный характер и направлен на изучение принципов работы микроконтроллерных систем, цифровых входов и выходов, а также взаимодействия аппаратной и программной частей устройства.

Работа выполнялась в течении 2 месяцев в несколько этапов: изучение и сбор информации по теме, покупка и изготовление необходимых принадлежностей для изготовления устройства, сборка устройства, проведение опытов, выводы.

В ходе работы был создан электронный прибор на базе платы Arduino, предназначенный для игры на скорость реакции двух игроков. Устройство позволяет определить, кто из игроков быстрее нажмёт кнопку после появления сигнала, и ведёт подсчёт очков до победы.

Цель: разработка простого интерактивного устройства, позволяющего измерять реакцию человека на световой сигнал, а также анализ принципов его функционирования с точки зрения аппаратной и программной реализации.

Объект исследования: процесс сравнения скорости реакции игроков с использованием микроконтроллерной системы.

Предмет исследования: аппаратная и программная реализация интерактивного устройства на базе платформы Arduino Uno, предназначенного для определения скорости реакции двух пользователей.

Задачи:

  • изучить принцип работы микроконтроллеров Arduino;

  • построить электрическую схему интерактивной игры;

  • написать программное обеспечение на С++;

  • собрать и протестировать интерактивное устройство на базе микроконтроллерной платформы Arduino Uno и продемонстрировать его работу;

  • проанализировать принципы функционирования устройства с точки зрения аппаратной и программной реализации, сделать выводы;

Методы исследования:

  • поисковый: анализ технической литературы и документации по микроконтроллерам;

  • моделирование: моделирование электрической схемы и программирование на языке C++ в среде разработки Arduino IDE;

  • систематизация: экспериментальное тестирование и отладка устройства;

  • аналитический: сравнительный анализ полученных результатов.

  1. Структура, состав и назначение элементов устройства

Общий список компонентов и функциональных узлов устройства (рисунок 2, на нем пронумерованы основные элементы):

  • микроконтроллер Arduino Uno (1);

  • устройства ввода: две кнопки игроков (2);

  • устройства индикации: светодиод центральный (3), светодиоды игроков (4) и LCD-дисплей 16×2 (5);

  • звуковой сигнализатор (пьезоэлектрический динамик) (6);

  • вспомогательные электронные компоненты: резисторы (7), макетная плата (8), соединительные провода (9);

  • питание - любой источник питания постоянного тока через кабель USB, который выдает примерно 5 вольт: в данном проекте использовался powerbank (10), допустимо использовать вместо него три пальчиковые батарейки, USB вывод компьютера.

Все элементы подключены к микроконтроллеру (1), который осуществляет управление устройством в соответствии с заданным алгоритмом (рисунок 1).

Рисунок 1 – Основные компоненты игры «Кто быстрее?» крупным планом

Рисунок 2 – Основные компоненты игры «Кто быстрее?»

Плата Arduino Uno. Основана на микроконтроллере ATmega328P и является главным управляющим элементом устройства. Она выполняет следующие функции [1]:

• обработку сигналов от кнопок;

• управление световой и звуковой индикацией;

• формирование логики игрового процесса;

• вывод информации на дисплей.

Программирование микроконтроллера осуществляется на языке C++ в среде Arduino IDE [2].

Кнопки игроков. Каждый игрок имеет свою кнопку. Когда игрок нажимает кнопку, Arduino фиксирует нажатие (кнопки подключены к входам Arduino с использованием внутренней подтяжки к логической единице (INPUT_PULLUP). Тот, кто нажал первым после сигнала старта, выигрывает раунд - нажатие кнопки фиксируется изменением логического уровня на входе микроконтроллера.

Центральный светодиод. Этот светодиод загорается в момент начала раунда. Он служит визуальным сигналом, после которого игрокам разрешено нажимать кнопки.

Светодиоды игроков. У каждого игрока есть свой светодиод. Он загорается на одну секунду, если данный игрок выиграл раунд. Это помогает сразу понять, кто победил.

Светодиоды подключены через токоограничивающие резисторы и управляются цифровыми выходами Arduino.

Жидкокристаллический дисплей LCD 16×2. Дисплей используется для отображения счёта игры и текстовых сообщений. В первой строке показывается количество очков первого и второго игрока. Во второй строке выводятся подсказки, такие как подготовка к раунду, ожидание или сообщение о победе.

Дисплей работает в 4-битном режиме, что позволяет сократить количество используемых выводов микроконтроллера.

Пьезо-динамик. Динамик используется для подачи звуковых сигналов. Он сообщает о начале раунда и проигрывает короткую мелодию при победе одного из игроков.

Генерация звуков осуществляется программно с помощью встроенных функций Arduino.

Вспомогательные электронные компоненты: резисторы, макетная плата, соединительные провода.

В данном устройстве резисторы используются для ограничения тока, протекающего через светодиоды. Светодиод является электронным компонентом, который чувствителен к величине тока. Если подключить его напрямую к выходу Arduino без дополнительных элементов, ток может оказаться слишком большим, что приведёт к перегреву и выходу светодиода из строя. Кроме того, избыточный ток может негативно повлиять на работу выходов микроконтроллера.

Чтобы избежать этого, в цепь каждого светодиода последовательно включён токоограничивающий резистор. В проекте применяются резисторы номиналом 220 Ом, которые позволяют снизить ток до безопасного значения при питании от напряжения 5 В, используемого в Arduino Uno.

Резисторы были впаяны в разрывы проводов, соединяющих катоды светодиодов с землёй (GND) Arduino (рисунок 3 а). Такое подключение означает, что электрический ток, протекающий от выхода микроконтроллера через светодиод к земле, в обязательном порядке проходит через резистор и тем самым ограничивается.

Размещение резистора именно в цепи земли выбрано из соображений удобства и наглядности. С электрической точки зрения резистор может быть установлен как со стороны питания, так и со стороны земли - на работу схемы это не влияет, поскольку важен сам факт последовательного включения резистора в цепь светодиода. Однако подключение резистора к земле упрощает монтаж схемы и делает её более понятной при сборке и анализе.

Таким образом, использование токоограничивающих резисторов обеспечивает корректную и безопасную работу светодиодов, а также демонстрирует базовый принцип построения электронных схем - необходимость ограничения тока при подключении полупроводниковых элементов.

   

а)

б)

Рисунок 3 – а) Впайка резисторов в разрывы проводов; б) процесс игры

2. Построение электрической схемы устройства

Рисунок 4 – Электрическая схема устройства

Электрическая схема устройства (рисунок 4) построена на базе микроконтроллерной платформы Arduino Uno [3]. Питание подаётся на плату через USB-разъём, который используется как для подачи напряжения 5 В, так и для загрузки управляющей программы. Общая земля (GND) Arduino используется как опорный потенциал для всех элементов схемы.

Все внешние компоненты размещаются на макетной плате и соединяются с выводами Arduino с помощью соединительных проводов.

Две тактовые кнопки, предназначенные для ввода действий игроков, подключены к аналоговым пинам A0 и A1, которые используются в режиме цифрового ввода. Один контакт каждой кнопки соединён с землёй (GND), а второй — с соответствующим входом микроконтроллера. В программном обеспечении задействована внутренняя подтяжка входов к логической единице (INPUT_PULLUP), что позволяет отказаться от внешних подтягивающих резисторов и упростить электрическую схему.

Для световой индикации в устройстве используются три светодиода. Центральный светодиод, сигнализирующий момент начала реакции, подключён к пину A2. Светодиоды первого и второго игроков подключены к пинам A3 и A4 соответственно. Аноды светодиодов соединены с соответствующими выводами Arduino, а катоды подключены к земле через токоограничивающие резисторы номиналом 220 Ом. Резисторы включены последовательно в цепь светодиодов и служат для ограничения тока, протекающего через них.

Жидкокристаллический дисплей 16×2 подключён к Arduino в параллельном 4-битном режиме. Для передачи управляющих и информационных сигналов используются цифровые пины D2–D7. Пины RS и E дисплея соединены с выводами D2 и D3 соответственно, а линии данных D4–D7 дисплея подключены к пинам D4–D7 Arduino. Контакт RW дисплея соединён с землёй, так как запись данных осуществляется только в одном направлении — от микроконтроллера к дисплею. Питание дисплея подаётся от контактов +5 В и GND Arduino. Для регулировки контрастности используется переменный резистор, подключённый к выводу VO дисплея.

Пьезоэлектрический динамик подключён к пину A5 и к земле. Управление динамиком осуществляется программно с помощью функции tone(), которая формирует на выходе микроконтроллера сигнал заданной частоты. Используемый пьезоэлемент потребляет малый ток, поэтому дополнительное токоограничение в цепи не требуется. Все соединения выполнены на макетной плате с использованием стандартных соединительных проводов. В схеме применяются токоограничивающие резисторы для светодиодов, а также используется внутренняя подтяжка входов кнопок, что обеспечивает корректную и стабильную работу устройства.

Таким образом, электрическая схема реализует взаимодействие микроконтроллера Arduino Uno с устройствами ввода (кнопки), средствами визуальной и звуковой индикации (светодиоды, LCD-дисплей и динамик), что полностью соответствует поставленной задаче разработки реакционной игры.

  1. Алгоритм программного обеспечения

Программное обеспечение состоит из стандартных для Arduino функций setup() и loop() [4]. Полный программный код управления микроконтроллером представлен в приложении А.

В функции setup() выполняется:

• инициализация портов ввода и вывода;

• настройка дисплея;

• установка начальных значений счёта.

Функция loop() реализует основной цикл работы устройства:

• управление индикацией;

• генерацию случайных задержек;

• опрос кнопок;

• обработку игровых событий;

• проверку условия завершения игры.

  1. Принцип работы устройства

Работа устройства основана на последовательной смене состояний, реализуемых программным алгоритмом.

Перед началом каждого раунда устройство подаёт три коротких звуковых сигнала с интервалом в половину секунды и затем один длинный сигнал. После этого начинается ожидание.

Через случайный промежуток времени от 3 до 6 секунд загорается центральный светодиод. Это означает, что игроки могут нажимать свои кнопки.

Arduino постоянно проверяет состояние кнопок. Как только один из игроков нажимает кнопку первым, раунд заканчивается, и этому игроку начисляется одно очко. Игра продолжается до тех пор, пока один из игроков не наберёт три очка.

Основные этапы одного игрового раунда:

  1. вывод на дисплей текущего счета;

  2. подача подготовительных звуковых сигналов начала раунда;

  3. формирование случайной временной задержки (от 3 до 6 секунд);

  4. подача светового сигнала начала реакции (загорается центральный светодиод) (рисунок 5а);

  5. ожидание нажатия кнопок игроками (рисунок 5в);

  6. фиксация первого нажатия кнопки (рисунок 5г);

  7. определение победителя раунда и начисление очка победившему игроку (рисунок 5д);

  8. включение светодиода победившего игрока и звукового сигнала (рисунок 5б);

  9. обновление счета на дисплее;

  10. проверка условия победы (3 очка), если счет <3 очков, повторяются пункты 1-10;

  11. завершение игры после определения победителя (рисунок 5е).

а

б

в

г

д

е

Рисунок 5 – Основные этапы игрового раунда

  1. Себестоимость проекта

Весь проект обошёлся примерно в 1000 рублей:

Arduino Uno ~ 400 р;

ЖК-дисплей LCD 16×2 ~ 150 р;

Макетная плата ~ 100 р;

Кнопки (2 шт.) ~ 40 р;

Светодиоды (3 шт.) ~ 30 р;

Пьезоэлектрический динамик ~ 60 р;

Резисторы (набор) ~ 50 р;

Потенциометр 10 кОм (контраст LCD) ~ 70 р;

Соединительные провода ~ 200 р.

Аналог изготовленной в ходе проекта игры – промышленная игра «Кнопочный бой» (рисунок 6) стоит от 55 000 до 269 000 рублей и является усложненной и усовершенствованной версией со встроенным столом и увеличенным количеством кнопок.

Рисунок 6 – игра «Кнопочный бой»

Заключение

Цель исследования достигнута: было разработано и реализовано электронное устройство на базе Arduino Uno, предназначенное для измерения скорости реакции пользователя. Проект позволил на практике получить опыт проектирования простых интерактивных электронных устройств, а также изучить основные принципы работы микроконтроллеров:

• взаимодействие аппаратных и программных компонентов;

• обработку пользовательского ввода;

• управление периферийными устройствами;

• реализацию алгоритмов с использованием случайных величин.

Работая над проектом, я изучил технику спаивания проводов, разобрался в прошивке плат. Заказать комплектующие и написать программный код мне помогли родители. Стоимость данного проекта составила – 1000 рублей, что в 50-200 раз дешевле, чем купить аналогичный в магазине. Я считаю, что данный проект может мотивировать юных исследователей и инженеров на создание подобных интересных вещей у себя дома. Созданную мной в рамках проекта игру можно использовать в учебном процессе для изучения основ микроконтроллерной техники, а также для демонстрации инженерных навыков в области математики, физики и информатики. Базовые знания этих предметов помогли в разработке данного проекта.

Список использованных источников и литературы

1. Блум, Дж. Изучаем Arduino: инструменты и методы технического волшебства. 2-е изд.:пер. с англ. – СПб.: БХВПетербург, 2020.

2. Муромцев Д.И., Шматков В.Н. «Интернет Вещей: Введение в

программирование на Arduino» – СПб: Университет ИТМО, 2018.

3. Аппаратная часть платформы Arduino [Электронный ресурс] //Arduino.ru Официальный сайт компании Arduino., URL: http :// arduino. ru / (Дата обращения: 25.01.2026)

4. Программирование на C и C++ [Электронный ресурс] // C-cpp.ru Онлайн справочник программиста на C и C++., URL: http :// www. c - cpp. ru / books / define (Дата обращения: 25.01.2026)

5. Строим роботов и другие устройства на Arduino. От светофора до 3Dпринтера [Электронный ресурс] // Coursera.org Coursera., 2020, URL:

https://www.coursera.org/learn/roboty-arduino/ (Дата обращения: 27.12.2025)

Приложение А. Программный код управления микроконтроллером

#include <LiquidCrystal.h> // Подключение библиотеки для работы с LCD-дисплеем

// ===== LCD =====

LiquidCrystal lcd(2, 3, 4, 5, 6, 7); // Создание объекта lcd и указание пинов: RS, E, D4, D5, D6, D7

// ===== ПИНЫ =====

const int btn1 = A0; // Пин кнопки первого игрока

const int btn2 = A1; // Пин кнопки второго игрока

const int centerLED = A2; // Пин центрального светодиода (сигнал старта)

const int led1 = A3; // Пин светодиода первого игрока

const int led2 = A4; // Пин светодиода второго игрока

кconst int buzzer = A5; // Пин пьезоэлектрического динамика

// ===== СЧЁТ =====

int score1 = 0; // Переменная для хранения очков первого игрока

int score2 = 0; // Переменная для хранения очков второго игрока

// ===== ЗВУК =====

void beep(int freq, int dur) { // Функция для воспроизведения одного звукового сигнала

tone(buzzer, freq, dur); // Генерация звука заданной частоты и длительности

delay(dur); // Задержка на время звучания сигнала

noTone(buzzer); // Остановка генерации звука

}

void trill() { // Функция для воспроизведения короткой звуковой трели

beep(1200, 80); // Первый звук трели

beep(1600, 80); // Второй звук трели

beep(2000, 80); // Третий звук трели

}

// ===== LCD =====

void showScore() { // Функция вывода текущего счёта на LCD

lcd.setCursor(0, 0); // Установка курсора в начало первой строки

lcd.print("P1: "); // Вывод надписи для первого игрока

lcd.print(score1); // Вывод счёта первого игрока

lcd.print(" P2: "); // Пробелы и надпись для второго игрока

lcd.print(score2); // Вывод счёта второго игрока

}

void showMessage(const char* msg) { // Функция вывода сообщения во второй строке LCD

lcd.setCursor(0, 1); // Установка курсора в начало второй строки

lcd.print(" "); // Очистка второй строки (16 пробелов)

lcd.setCursor(0, 1); // Повторная установка курсора

lcd.print(msg); // Вывод переданного текстового сообщения

}

// ===== SETUP =====

void setup() { // Функция начальной настройки, выполняется один раз

pinMode(btn1, INPUT_PULLUP); // Настройка кнопки 1 как входа с внутренней подтяжкой

pinMode(btn2, INPUT_PULLUP); // Настройка кнопки 2 как входа с внутренней подтяжкой

pinMode(centerLED, OUTPUT); // Настройка центрального светодиода как выхода

pinMode(led1, OUTPUT); // Настройка светодиода первого игрока как выхода

pinMode(led2, OUTPUT); // Настройка светодиода второго игрока как выхода

lcd.begin(16, 2); // Инициализация LCD-дисплея размером 16×2

randomSeed(analogRead(A6)); // Инициализация генератора случайных чисел

lcd.clear(); // Очистка дисплея

showScore(); // Вывод начального счёта

showMessage("Reaction game"); // Вывод стартового сообщения

delay(1500); // Задержка для отображения сообщения

}

// ===== LOOP =====

void loop() { // Основной цикл программы, выполняется постоянно

// --- стартовые сигналы ---

showMessage("Get ready!"); // Вывод сообщения о подготовке

for (int i = 0; i < 3; i++) { // Цикл для трёх коротких сигналов

beep(1000, 100); // Короткий звуковой сигнал

delay(400); // Пауза между сигналами

}

beep(500, 400); // Длинный звуковой сигнал

showMessage("WAIT..."); // Сообщение ожидания

delay(random(3000, 6000)); // Случайная задержка от 3 до 6 секунд

// --- старт реакции ---

digitalWrite(centerLED, HIGH); // Включение центрального светодиода

showMessage("PRESS!"); // Сообщение о начале реакции

while (true) { // Бесконечный цикл ожидания нажатия кнопки

if (!digitalRead(btn1)) { // Проверка нажатия кнопки первого игрока

score1++; // Увеличение счёта первого игрока

digitalWrite(led1, HIGH); // Включение светодиода первого игрока

trill(); // Воспроизведение трели

showScore(); // Обновление счёта на дисплее

showMessage("Player 1 wins"); // Сообщение о победе первого игрока

delay(1000); // Задержка для отображения результата

digitalWrite(led1, LOW); // Выключение светодиода первого игрока

break; // Выход из цикла ожидания

}

if (!digitalRead(btn2)) { // Проверка нажатия кнопки второго игрока

score2++; // Увеличение счёта второго игрока

digitalWrite(led2, HIGH); // Включение светодиода второго игрока

trill(); // Воспроизведение трели

showScore(); // Обновление счёта на дисплее

showMessage("Player 2 wins"); // Сообщение о победе второго игрока

delay(1000); // Задержка для отображения результата

digitalWrite(led2, LOW); // Выключение светодиода второго игрока

break; // Выход из цикла ожидания

}

}

digitalWrite(centerLED, LOW); // Выключение центрального светодиода

// --- проверка победы ---

if (score1 >= 3 || score2 >= 3) { // Проверка достижения победного счёта

lcd.clear(); // Очистка дисплея

if (score1 > score2) // Проверка, кто набрал больше очков

lcd.print("PLAYER 1 WINS!"); // Сообщение о победе первого игрока

else

lcd.print("PLAYER 2 WINS!"); // Сообщение о победе второго игрока

lcd.setCursor(0, 1); // Переход на вторую строку

lcd.print("Game over"); // Сообщение о завершении игры

while (true); // Остановка программы

}

delay(1000); // Пауза перед началом следующего раунда

}

Просмотров работы: 4