Введение
Микроконтроллерные платформы, такие как Arduino, широко применяются в образовательном процессе для изучения основ встраиваемых систем. Их использование позволяет наглядно продемонстрировать принципы работы электронных устройств, а также связать теоретические знания с практической реализацией [1, 5].
В работе рассматривается процесс разработки электронного устройства для измерения скорости реакции двух пользователей, реализованного на базе микроконтроллерной платформы Arduino Uno. Устройство использует световую и звуковую индикацию, кнопки ввода и жидкокристаллический дисплей для организации игрового процесса и отображения результатов. Проект носит учебный характер и направлен на изучение принципов работы микроконтроллерных систем, цифровых входов и выходов, а также взаимодействия аппаратной и программной частей устройства.
Работа выполнялась в течении 2 месяцев в несколько этапов: изучение и сбор информации по теме, покупка и изготовление необходимых принадлежностей для изготовления устройства, сборка устройства, проведение опытов, выводы.
В ходе работы был создан электронный прибор на базе платы Arduino, предназначенный для игры на скорость реакции двух игроков. Устройство позволяет определить, кто из игроков быстрее нажмёт кнопку после появления сигнала, и ведёт подсчёт очков до победы.
Цель: разработка простого интерактивного устройства, позволяющего измерять реакцию человека на световой сигнал, а также анализ принципов его функционирования с точки зрения аппаратной и программной реализации.
Объект исследования: процесс сравнения скорости реакции игроков с использованием микроконтроллерной системы.
Предмет исследования: аппаратная и программная реализация интерактивного устройства на базе платформы Arduino Uno, предназначенного для определения скорости реакции двух пользователей.
Задачи:
изучить принцип работы микроконтроллеров Arduino;
построить электрическую схему интерактивной игры;
написать программное обеспечение на С++;
собрать и протестировать интерактивное устройство на базе микроконтроллерной платформы Arduino Uno и продемонстрировать его работу;
проанализировать принципы функционирования устройства с точки зрения аппаратной и программной реализации, сделать выводы;
Методы исследования:
поисковый: анализ технической литературы и документации по микроконтроллерам;
моделирование: моделирование электрической схемы и программирование на языке C++ в среде разработки Arduino IDE;
систематизация: экспериментальное тестирование и отладка устройства;
аналитический: сравнительный анализ полученных результатов.
Структура, состав и назначение элементов устройства
Общий список компонентов и функциональных узлов устройства (рисунок 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-дисплей и динамик), что полностью соответствует поставленной задаче разработки реакционной игры.
Алгоритм программного обеспечения
Программное обеспечение состоит из стандартных для Arduino функций setup() и loop() [4]. Полный программный код управления микроконтроллером представлен в приложении А.
В функции setup() выполняется:
• инициализация портов ввода и вывода;
• настройка дисплея;
• установка начальных значений счёта.
Функция loop() реализует основной цикл работы устройства:
• управление индикацией;
• генерацию случайных задержек;
• опрос кнопок;
• обработку игровых событий;
• проверку условия завершения игры.
Принцип работы устройства
Работа устройства основана на последовательной смене состояний, реализуемых программным алгоритмом.
Перед началом каждого раунда устройство подаёт три коротких звуковых сигнала с интервалом в половину секунды и затем один длинный сигнал. После этого начинается ожидание.
Через случайный промежуток времени от 3 до 6 секунд загорается центральный светодиод. Это означает, что игроки могут нажимать свои кнопки.
Arduino постоянно проверяет состояние кнопок. Как только один из игроков нажимает кнопку первым, раунд заканчивается, и этому игроку начисляется одно очко. Игра продолжается до тех пор, пока один из игроков не наберёт три очка.
Основные этапы одного игрового раунда:
вывод на дисплей текущего счета;
подача подготовительных звуковых сигналов начала раунда;
формирование случайной временной задержки (от 3 до 6 секунд);
подача светового сигнала начала реакции (загорается центральный светодиод) (рисунок 5а);
ожидание нажатия кнопок игроками (рисунок 5в);
фиксация первого нажатия кнопки (рисунок 5г);
определение победителя раунда и начисление очка победившему игроку (рисунок 5д);
включение светодиода победившего игрока и звукового сигнала (рисунок 5б);
обновление счета на дисплее;
проверка условия победы (3 очка), если счет <3 очков, повторяются пункты 1-10;
завершение игры после определения победителя (рисунок 5е).
|
а |
б |
|
в |
г |
|
д |
е |
Рисунок 5 – Основные этапы игрового раунда
Себестоимость проекта
Весь проект обошёлся примерно в 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); // Пауза перед началом следующего раунда
}