Устали от одних и тех же проектов на Arduino: мигающих светодиодов, датчиков температуры и роботов, следующих по линии? Пришло время чего-то интересного. Пора превратить свои навыки в развлечение, создав собственный проект игровой консоли на Arduino. Вместо простого тестирования схем, представьте, что вы включаете устройство, которое сами собрали, и сразу же погружаетесь в мир ретро-игр, заключенных в компактную, карманную систему.

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

Необходимые компоненты
- Плата Arduino Uno R4 WiFi (купить на AliExpress). Основная плата микроконтроллера, запускает все игры и управляет работой консоли.
- 0,96-дюймовый OLED-дисплей с интерфейсом I2C (купить на AliExpress - для данного проекта можно покупать модель с 4-мя контактами поскольку используется его подключение по интерфейсу I2C). Компактный дисплей для отображения игровой графики, интерфейса меню и результатов.
- Тактильные кнопки - 4 шт.
- Перфорированная плата (двусторонняя печатная плата) - специальная плата, используемая для аккуратного монтажа и размещения всех компонентов, выполняющая функцию подключаемого модуля HAT для Arduino.
- Зуммер (купить на AliExpress). Генерирует звуковые эффекты во время игрового процесса, создавая атмосферу ретро-игр.
- Литий-полимерный аккумулятор 1S - портативный источник питания, позволяющий сделать консоль полностью портативной.
- 5-вольтовый повышающий преобразователь - повышает напряжение литий-полимерного аккумулятора до стабильных 5 В, необходимых для работы системы.
- Ползунковый переключатель - используется в качестве главного выключателя питания консоли.
- Соединительные провода - для создания электрических соединений между компонентами.
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Обзор консоли
Созданная мной самодельная ретро-игровая консоль основана на плате Arduino UNO R4 WiFi и собрана из таких компонентов, как 0,96-дюймовый OLED-дисплей SSD1306 (128×64 пикселей), тактильные кнопки (4), активный зуммер, литий-полимерный аккумулятор 1S с повышающим преобразователем 5 В и специально разработанная макетная плата в стиле HAT. Консоль содержит 10 игр, запрограммированных с нуля на Arduino C++, и каждая игра хранится отдельно в заголовочных файлах.
Коллекция игр
Эта игровая консоль на базе Arduino включает в себя коллекцию классических аркадных игр, таких как Asteroids, Breakout, Dino, Flappy Bird, Maze Runner, Pacman, Pong, Snake, Space Invaders и Tetris, оптимизированных для плавной работы на OLED-дисплее с разрешением 128x64 и простым кнопочным управлением. Это не точные оригинальные версии, а реплики, воссозданные и оптимизированные специально для соответствия аппаратным ограничениям консоли.

Компактный и портативный дизайн
Эта игровая консоль на базе Arduino разработана таким образом, чтобы быть компактной и помещаться в карман, что позволяет легко носить её с собой и использовать где угодно. Аппаратная часть проста и аккуратно размещена на специальной плате типа «шляпка», подключенной к Arduino R4 WiFi, что обеспечивает чистый и организованный дизайн. В результате получилась карманная игровая консоль на базе Arduino, которую можно носить с собой и питать где угодно от встроенного литий-полимерного аккумулятора.

Если вы хотите создать что-то более похожее на настоящее игровое устройство коммерческого класса, вы можете ознакомиться со статьей «Самодельная портативная ретро-игровая консоль на базе ESP32», где представлена более продвинутая и мощная версия портативной игровой консоли.
Схема игровой консоли на Arduino
Приведенная ниже принципиальная схема показывает полную схему игровой консоли на основе платы Arduino. На ней четко показаны соединения между OLED-дисплеем, кнопками управления, зуммером, батареей и повышающим преобразователем с платой Arduino. Использование этой схемы при сборке оборудования поможет обеспечить правильную проводку и надежную работу консоли.

Конфигурация контактов
Все компоненты консоли подключены к определенным контактам Arduino в зависимости от их функции. OLED-дисплей использует контакты I2C для передачи данных, кнопки подключены к цифровым входным контактам, а зуммер — к цифровому выходному контакту. Правильное сопоставление контактов обеспечивает бесперебойную работу системы и корректную реакцию во время игры. Приведенная ниже таблица является исчерпывающим руководством по подключениям этой игровой консоли на основе платы Arduino.
| Компонент | Контакт | Контакт Arduino | Тип контакта |
| OLED-дисплей | VCC | 5V | Питание |
| OLED-дисплей | GND | GND | Общий провод (земля) |
| OLED-дисплей | SDA | A4 | Данные I2C |
| OLED-дисплей | SCL | A5 | Синхронизация I2C |
| Кнопка – ВВЕРХ | Signal | D4 | Вход |
| Кнопка – ВНИЗ | Signal | D2 | Вход |
| Кнопка – ЛЕВАЯ | Signal | D3 | Вход |
| Кнопка – ПРАВАЯ | Signal | D5 | Вход |
| Другая сторона | GND | Общий провод (земля) | |
| Зуммер | + | D7 | Выход |
| Зуммер | - | GND | Общий провод (земля) |
| 5-вольтовый повышающий преобразователь | OUT + | 5V | Питание |
| 5-вольтовый повышающий преобразователь | OUT - | GND | Общий провод (земля) |
| Литий-полимерный аккумулятор | + | Switch to Boost IN + | Вход питания |
| Литий-полимерный аккумулятор | - | Boost IN - | Общий провод (земля) |
Как видите, схема соединений проекта несложная.
Сборка оборудования
Все компоненты были смонтированы на двухсторонней перфорированной плате, чтобы обеспечить компактность и организованность конструкции. Вся схема была разработана как модуль HAT, который устанавливается непосредственно поверх Arduino R4, что делает консоль аккуратной и портативной. OLED-дисплей, кнопки и зуммер были тщательно припаяны и подключены в соответствии с конфигурацией контактов. Система питается от литий-полимерного аккумулятора 3,7 В вместе с повышающим преобразователем 5 В обеспечивая стабильную работу в портативном форм-факторе.

Советы по быстрой сборке
∗ Используйте разъемы типа «мама» на макетной плате, чтобы плату расширения можно было снять для перепрограммирования без выпаивания.
∗ Проложите провода I2C (SDA/SCL) подальше от сигнальных проводов кнопок, чтобы минимизировать шум на дисплее.
∗ Перед подключением к выводу 5 В Arduino убедитесь с помощью мультиметра, что выходное напряжение повышающего преобразователя составляет ровно 5 В.
∗ Используйте термоусадочную трубку на всех выводах LiPo-аккумулятора, чтобы предотвратить короткое замыкание.
∗ Старайтесь, чтобы соединительные провода были как можно короче для сохранения компактного форм-фактора.
Обзор кода игровой консоли на Arduino
Весь код для этой ретро-игровой консоли (ссылка на него приведена в конце статьи) на базе Arduino был написан с нуля, с упором на модульность и простоту расширения. Каждая игра разрабатывается отдельно и хранится в отдельном заголовочном файле, что делает основную программу чистой и хорошо организованной. Такая структура упрощает добавление новых игр, удаление существующих или модификацию и тонкую настройку игровой механики без влияния на общую систему. Модульная конструкция обеспечивает гибкость и упрощает настройку и модернизацию консоли. Полная прошивка для этого проекта игровой консоли на базе Arduino была написана с нуля с использованием модульной архитектуры.
Шаг 1 ⇒ Подключение библиотек
|
1 2 3 |
#include <Arduino.h> #include <U8g2lib.h> #include <Wire.h> |
Проект начинается с включения необходимых библиотек, требуемых для корректной работы консоли.
- Библиотека Arduino.h предоставляет доступ к основным функциям Arduino, таким как pinMode(), digitalRead(), millis(), delay() и tone(), которые используются во всей программе.
- Библиотека U8g2lib.h отвечает за управление OLED-дисплеем SSD1306 с разрешением 128x64, обеспечивая плавную отрисовку графики, текста, меню и игровых элементов.
- Библиотека Wire.h обеспечивает связь по протоколу I2C между Arduino и OLED-дисплеем, гарантируя корректную передачу данных по выводам SDA и SCL. Вместе эти библиотеки составляют основу игровой консоли Arduino.
Шаг 2 ⇒ Константы и определения контактов
|
1 2 3 4 5 6 7 |
#define SCREEN_W 128 #define SCREEN_H 64 #define BTN_UP 4 #define BTN_DOWN 2 #define BTN_LEFT 3 #define BTN_RIGHT 5 #define BUZZER_PIN 7 |
В этом разделе кода определены важные константы, используемые во всей программе. Ширина и высота экрана установлены на 128 и 64 соответственно, что соответствует разрешению OLED-дисплея SSD1306. Определение этих значений в качестве констант упрощает точное размещение текста и графики на экране.
Далее определяются цифровые контакты, подключенные к кнопкам управления. Кнопки ВВЕРХ, ВНИЗ, ВЛЕВО и ВПРАВО назначаются контактам 4, 2, 3 и 5, что позволяет программе считывать ввод пользователя для навигации по меню и игрового процесса. Наконец, зуммер назначается контакту 7, который используется для генерации звуковых эффектов и простых музыкальных тонов при запуске, выборе и завершении игры.
Шаг 3 ⇒ Подключение заголовочных файлов игр
|
1 2 3 4 5 6 7 8 9 10 |
#include "Asteroids.h" #include "Breakout.h" #include "Dino.h" #include "FlappyBird.h" #include "MazeRunner.h" #include "Pacman.h" #include "Pong.h" #include "Snake.h" #include "SpaceInvaders.h" #include "Tetris.h" |
В этом разделе представлены заголовочные файлы для всех игр, доступных на консоли. Каждая игра написана в отдельном файле, например, Asteroids, Breakout, Dino, Flappy Bird, Maze Runner, Pacman, Pong, Snake, Space Invaders и Tetris. Организация каждой игры в отдельном заголовочном файле обеспечивает чистоту и модульность основной программы. Такое разделение задач упрощает управление, отладку и расширение этого проекта по созданию игровой консоли на Arduino, поскольку новые игры можно добавлять без изменения основной логики консоли.
Шаг 4 ⇒ Функция подавления дребезга кнопок
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
bool btnPressed(uint8_t pin) { static uint32_t lastTime[4] = {0, 0, 0, 0}; static bool lastSt[4] = {true, true, true, true}; uint8_t idx; if (pin == BTN_UP) idx = 0; else if (pin == BTN_DOWN) idx = 1; else if (pin == BTN_LEFT) idx = 2; else if (pin == BTN_RIGHT) idx = 3; else return false; bool cur = (digitalRead(pin) == LOW); bool edge = cur && !lastSt[idx] && (millis() - lastTime[idx] > 40); if (cur != lastSt[idx]) lastTime[idx] = millis(); lastSt[idx] = cur; return edge; } |
Функция btnPressed() отвечает за обнаружение корректного нажатия кнопки, предотвращая при этом нежелательные множественные срабатывания, вызванные механическим дребезгом. Она проверяет текущее состояние кнопки и сравнивает его с предыдущим состоянием для обнаружения корректного события нажатия (обнаружение края). Для хранения последнего записанного времени и предыдущего состояния каждой кнопки используются статические массивы, что позволяет функции отслеживать их индивидуально. Для подавления дребезга контактов кнопки используется небольшая задержка в 40 миллисекунд, измеренная с помощью функции millis(). Функция возвращает true только при обнаружении корректного нажатия, обеспечивая плавную и надежную навигацию по меню и управление игровым процессом.
Шаг 5 ⇒ Функция setup()
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
void setup() { pinMode(BTN_UP, INPUT_PULLUP); pinMode(BTN_DOWN, INPUT_PULLUP); pinMode(BTN_LEFT, INPUT_PULLUP); pinMode(BTN_RIGHT, INPUT_PULLUP); pinMode(BUZZER_PIN, OUTPUT); randomSeed(analogRead(A0)); u8g2.begin(); u8g2.setContrast(200); u8g2.setFont(u8g2_font_6x10_tr); u8g2.setDrawColor(1); u8g2.setBitmapMode(0); showSplash(); } |
Функция setup() выполняется один раз при включении консоли и отвечает за инициализацию аппаратных и графических настроек. Все четыре кнопки управления настраиваются с помощью INPUT_PULLUP, что включает внутренние подтягивающие резисторы для стабильного считывания входного сигнала. Контакт зуммера устанавливается как выход, чтобы он мог генерировать звуковые эффекты. Начальное значение генератора случайных чисел инициализируется с помощью считывания аналогового контакта для обеспечения непредсказуемого поведения игры, где требуется случайность. Затем OLED-дисплей инициализируется с помощью u8g2.begin(), после чего устанавливаются контрастность, стиль шрифта, цвет отрисовки и режим растрового изображения для корректного отображения. Наконец, вызывается функция showSplash() для отображения стартового экрана перед входом в главное меню.
Шаг 6 ⇒ Основной цикл
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
void loop() { int sel = menuSelect(); switch (sel) { case 0: game_asteroids(); break; case 1: game_breakout(); break; case 2: game_dino(); break; case 3: game_flappy(); break; case 4: game_maze(); break; case 5: game_pacman(); break; case 6: game_pong(); break; case 7: game_snake(); break; case 8: game_spaceinvaders(); break; case 9: game_tetris(); break; } } |
Функция loop() выступает в качестве главного центра управления консоли. Сначала она вызывает функцию menuSelect(), которая отображает меню выбора игр и возвращает номер, соответствующий выбранной игре. В зависимости от этого выбранного значения используется оператор switch для запуска соответствующей игровой функции, например, game_snake(), game_pong() или game_tetris(). Каждый случай представляет одну из десяти доступных игр. После завершения игры программа автоматически возвращается к циклу, возвращая пользователя в меню для выбора другой игры. Такая структура обеспечивает плавную навигацию и непрерывный игровой процесс без перезапуска консоли.
Видео, демонстрирующее работу игровой консоли
Ниже вы можете посмотреть видеоролик, демонстрирующий работу игровой консоли.
При включении консоли на дисплее сначала отображается главный экран игровой консоли, предлагающий пользователю нажать любую кнопку для продолжения. После нажатия кнопки появляется список игр. Кнопки ВВЕРХ и ВНИЗ используются для прокрутки списка доступных игр, а игру можно выбрать, нажав кнопку ВЛЕВО или ВПРАВО. Видео ниже демонстрирует работу портативной игровой консоли на базе Arduino, от заставки при запуске и выбора игры до игрового процесса в прямом эфире по нескольким играм.
После выбора игры она мгновенно загружается, и начинается игровой процесс. После окончания игры консоль автоматически возвращается на страницу списка игр, позволяя выбрать другую игру.
И еще одно видео про данную консоль:
Будущие обновления
- Расширьте возможности консоли, добавив больше игр и новых игровых функций.
- Улучшите пользовательский опыт с помощью сохранения рекордов, дополнительных звуковых эффектов и более интерактивного дизайна меню.
- Ввести регулируемые уровни сложности, чтобы предоставить игрокам различные варианты испытаний.
- Включите поддержку беспроводного многопользовательского режима с помощью Arduino UNO R4 WiFi для игры по сети между двумя консолями.
- Повышение производительности оборудования за счет оптимизации энергопотребления для увеличения времени автономной работы и поддержки дисплеев большего размера.
Трудности, возникшие в процессе разработки
Проблема совместимости библиотеки с Arduino UNO R4
Ещё одна проблема, возникшая в процессе разработки, была связана с библиотекой графики для OLED-дисплеев. Широко используемая библиотека Adafruit GFX оказалась не полностью совместима с Arduino UNO R4 в данной конфигурации, что вызвало проблемы с инициализацией и рендерингом дисплея. Для решения этой проблемы была использована библиотека U8g2.
Библиотека U8g2 обеспечивает лучшую совместимость с UNO R4 и предлагает эффективную полнокадровую буферизацию, более плавную отрисовку текста и гибкую поддержку шрифтов. Переход на U8g2 обеспечил стабильную работу OLED-дисплея и улучшил общую обработку изображения на консоли. Не каждая плата Arduino подходит для одновременного управления OLED-дисплеем и выполнения игровой логики. Ознакомьтесь с нашим руководством по сравнению плат Arduino, чтобы понять, почему скорость обработки и объем оперативной памяти важны при выборе оборудования для проектов с интенсивным использованием дисплея.
Подавление дребезга кнопок
Ещё одна распространённая проблема в аппаратных проектах — дребезг кнопок. При нажатии механической кнопки она не переключается плавно из положения «ВКЛ» в положение «ВКЛ». Вместо этого она быстро колеблется между ВЫСОКИМ и НИЗКИМ уровнями в течение нескольких миллисекунд, что может привести к множеству непреднамеренных действий в игре, таких как пропуск пунктов меню или запуск повторяющихся действий.
Для решения этой проблемы в функцию btnPressed() была реализована программная защита от дребезга контактов. Используя проверки времени с помощью millis() и определяя переходы по фронтам сигнала, программа гарантирует, что регистрируется только чистое и целенаправленное нажатие кнопки. Это обеспечивает более плавную навигацию по меню и более точное управление игровым процессом.
Часто задаваемые вопросы об игровой консоли на Arduino
⇥ Можно ли добавить на консоль больше игр?
Да. Поскольку каждая игра написана в отдельном заголовочном файле, новые игры можно легко добавить, создав новый файл игры и включив его в систему главного меню.
⇥ Зачем используется повышающий преобразователь на 5 В?
Консоль питается от литий-полимерного аккумулятора на 3,7 В, но для стабильной работы Arduino требуется 5 В. Повышающий преобразователь увеличивает напряжение батареи до стабильного выходного напряжения 5 В.
⇥ Это оригинальные аркадные игры?
Нет. Это облегченные копии, созданные по мотивам классических аркадных игр. Они воссозданы и оптимизированы для работы в пределах возможностей платформы Arduino, включая объем памяти и производительность.
⇥ Можно ли модернизировать этот проект для более мощной консоли?
Да. Для повышения производительности и качества графики дизайн можно модернизировать до портативной игровой консоли на базе ESP32 с большими дисплеями, поддержкой SD-карт и дополнительными функциями.
⇥ Как в коде обрабатывается дребезг кнопок?
В функции btnPressed() используется программное подавление дребезга контактов для проверки перехода от низкого уровня к высокому и принятия нажатия кнопки в качестве действительного только в том случае, если с момента последнего перехода сигнала в состоянии кнопки прошло не менее 40 миллисекунд. Фильтрация дребезга контактов с помощью таймера позволяет каждой из четырех кнопок иметь собственный статический массив для хранения последнего состояния и метки времени последнего изменения, что обеспечивает независимый опрос и исключает ложные срабатывания кнопок.
Репозиторий игровой консоли на Arduino на GitHub
Изображения проекта и код для портативной игровой консоли на базе Arduino можно найти в репозитории GitHub. Он включает исходный код, схемы подключения и дополнительную документацию, которая поможет вам собрать и модифицировать собственную портативную консоль.
44 просмотров




