[Перевод] Самодельная портативная консоль microByte
В реальности качество изображения лучше, но это сложно передать на фотографии.
В феврале этого года ко мне прибыл дисплейный модуль ST7789; качество картинки и цветов, несмотря на маленький размер, было впечатляющим, поэтому в голову пришла одна идея…
Может, разработать брелок, на котором можно будет играть в Pokemon?
В этот момент зародилась примитивная идея microByte. Спустя более семи месяцев идея брелока эволюционировала в полнофункциональную портативную консоль, способную эмулировать:
- NES
- GameBoy
- GameBoy Color
- Sega Master System
- GameGear
И всё это в крошечном размере картриджа первого GameBoy. Самое важное, что тексты в игре читаемы, нужна только лупа. Размеры устройства: 78×17x40 мм
С другой стороны, вы можете задаться вопросом, зачем добавлять раскладку геймпада SNES (кнопки направлений, 4 кнопки действий, Start, Select, L и R.), если устройство может эмулировать только 8-битные игры?
Ну да, пока она способна запускать только 8-битные игры, но проведя тщательные поиски, я выяснил, что для ESP32 уже существуют первые порты эмулятора SNES и SCRUMV. Поэтому стало очевидно, что устройству требуется полная раскладка геймпада SNES с перспективой на дальшейшие обновления.
К тому же я считаю, что кроме игр, устройство может быть очень полезным инструментом в разработке проектов на ESP32, потому что можно запускать скетчи Arduino и/или двоичные файлы проектов ESP-IDF с SD-карты как приложения, не удаляя при этом основную прошивку. Ниже я расскажу об этом подробнее.
Вот краткий видеообзор:
Я разделю спецификации устройства на аппаратные и программные, чтобы подробнее рассказать о них.
Оборудование
Мы начнём с общего списка характеристик оборудования:
- ESP32 WROVER E (16 МБ)
- 8 МБ ОЗУ
- 16 МБ флэш-памяти
- 1,3-дюймовый IPS-дисплей ST7789 с разрешением 240×240 пикселей
- Разъём для карты micro-SD.
- Встроенный динамик с усилителем звука MAX98357AETE+T I2S.
- 13 встроенных кнопок, подключенных к мультиплексору TCA9555RTWR.
- 8 индуктивных кнопок с резиновой мембраной (кнопки направлений и действий)
- 3 кнопки-переключателя (Start, Select и Menu)
- 2 горизонтальных кнопки-переключателя (левый и правый триггеры).
- Цепь аккумулятора с защитой зарядки.
- Аккумулятор 500 мАч (этого достаточно для 6–7 часов автономной игры).
- Разъём USB-C.
В этом репозитории можно найти проект KiCad со схемой и конструкцией печатной платы проекта microByte: прошивка/конструкция печатной платы
Фотографии платы:
Вид сверху
Вид снизу
Я думал добавить поддержку наушников через разъём USB-C, но отказался от этой идеи, потому что не нашёл достаточно информации о стандарте реализации. Похоже, каждый производитель реализует звук через USB-C по-своему. Поэтому в этой версии печатной платы разъём используется только для зарядки устройства и подключения к последовательной консоли для просмотра лога отладки.
Как видно на втором фото, для подключения аккумулятора я использовал стандартный разъём PH 2.0. Это позволяет использовать аккумулятор большей ёмкости. Если вы хотите использовать меньшую ёмкость, то важно заменить резистор R2, чтобы значение было соответствующим. Этот резистор задаёт конфигурацию зарядки для чипа TP4056. Если не поменять значение резистора R2, то это приведёт к повреждению литий-полимерного аккумулятора. Также устройство содержит повышающий преобразователь, гарантирующий стабильные 3,3 В на выходе; это решение позволяет избежать снижения яркости экрана и нестабильного поведения при разрядке аккумулятора.
Используется усилитель звука MAX98357AETE+T. Этот драйвер выполняет преобразование из I2S на ADC, его можно настроить на работу с моно-/стереосигналом, а коэффициент усиления конфигурируется. По умолчанию я установил коэффициент усиления в 9 дБ. Думаю, этого достаточно, чтобы избежать повреждения динамика. Кстати, о динамике: очень сложно найти дешёвый SMD-динамик, на который хватит места на плате, поэтому я нашёл пищалку с хорошим диапазоном частот, помещающуюся на печатной плате.
Качество звука оставляет желать лучшего, некоторые звуки теряются, но в целом звук получился вполне достойный. Динамик можно увидеть на первой фотографии печатной платы.
Наконец, должен ещё раз повториться — экран потрясающий по цене и размеру. Качество картинки превосходно. Также меня впечатлила возможность получения стабильной скорости связи на 60 МГц при использовании простого SPI (то есть не quad-SPI).
Программное обеспечение
ПО было разработано при помощи фреймворка ESP-IDF и freeRTOS в качестве ОСРВ.
Прошивку и руководство по настройке можно найти здесь: прошивка microByte.
При проектировании я стремился к модульной архитектуре. Такая модульность обеспечивает возможность добавления и/или модифицирования новых программных функций, например, новых эмуляторов.
Всей архитектурой управляет задача-менеджер, эта задача проверяет уровень заряда аккумулятора, уведомления LED, проверяет обновления и контролирует задачи GUI и эмуляторов, приостанавливая и продолжая их работу в зависимости от происходящих событий.
На нижнем слое ПО есть HAL (Hardware abstraction layer, слой абстрагирования от оборудования), который упрощает доступ к аппаратным ресурсам эмуляторам, задаче-менеджеру и GUI. Наконец, на самом дне есть драйверы, взаимодействующие с HAL.
Все эмуляторы и GUI работают в одном приложении ESP32, это обеспечивает очень хорошее время загрузки игр и системы в целом. Игры размером меньше 4 МБ могут загружаться менее чем за две секунды!
GUI спроектирован с помощью библиотеки LVGL. Это библиотека с открытыми исходниками, позволяющая создавать очень хороший и современно выглядящий графический интерфейс пользователя. Я стремился сделать GUI этого проекта простым, но с большим количеством опций. Добавлено красивое меню конфигурации, позволяющее настроить поведение каждого эмулятора и опции устройства.
На данный момент оно содержит только следующие опции:
- Изменение яркости.
- Изменение уровня громкости.
- Смена цвета интерфейса.
- Включение тёмного режима.
- Получение данных об устройстве.
- Получение информации об SD-карте.
- Получение данных об аккумуляторе.
Ещё один важный аспект устройства — это эмуляторы. Они были усовершенствованы и адаптированы к устройству. Эмуляция GameBoy/GameBoy Color и Game Gear обеспечивает очень хорошие результаты с полной частотой кадров.
Работа внешних приложений похожа на «трюк», но позволила добиться очень хороших результатов. Устройство имеет два раздела OTA и любой из них может быть основным разделом. То есть если на раздел OTA 0 записана версия 1.0 прошивки и вы хотите обновить устройство до версии 1.1 через SD-карту, то в случае успешного обновления при следующем перезапуске основным разделом для приложений будет OTA 1 с версией 1.1, а раздел OTA 0 будет стёрт.
То есть для загрузки внешних двоичных файлов без потери основной прошивки microByte мы прошиваем двоичный файл на свободный раздел OTA, не отправляя устройству сигнал подтверждения, потому что в противном случае при сбросе устройства раздел OTA с приложением будет стёрт, ведь устройство посчитает, что обновление выполнить не удалось.
Это довольно быстрый процесс, но он сильно зависит от размера двоичного файла. Например, загрузка простого примера Blink займёт 5–10 секунд, а игра Doom 1 — до 20 секунд.
Корпус спроектирован так, чтобы его можно было легко напечатать на 3D-принтере, но в то же время чтобы он обеспечивал удобство игры. Все файлы можно найти в этом репозитории: файлы stl microByte.
С другой стороны, потратив много часов на размышления о том, какой тип кнопок подойдёт больше, я понял, что должен добавить резиновую мембрану, чтобы создать чёткое ощущение «клика». С другой стороны, я протестировал некоторые из самых новых портативных консолей, и понял, что моё устройство имеет идеальный размер для небольшого модульного геймпада.
Как говорилось выше, корпус очень легко печатается, я выполнял печать материалами PLA и PTEG на Ender 3, и результаты вышли очень хорошими. Кроме того, я напечатал несколько корпусов на разных SLA-принтерах наподобие Eleegoo Mars, и результаты тоже были потрясающими.
Вскоре я дополню репозиторий инструкциями по печати.
Процесс сборки очень прост, я записываю небольшое видео с демонстрацией сборки. Упрощённая схема показана на изображении:
Вот несколько рендеров корпуса в разных цветах:
На данном этапе производительность в целом стабильна и хороша, устройство выдаёт полную частоту кадров в играх GameBoy/GameBoy Color и GameGear.
Однако я считаю, что в будущем нужно решить следующие важные проблемы:
- Улучшить производительность NES. Большинство игр работает хорошо, но имеет некоторые глитчи и нестабильность скорости.
- Снижение эффекта тиринга (tearing, разрыва кадра). В некоторых играх заметен эффект тиринга, хоть это и небольшая проблема, но её может быть неприятно наблюдать.
- Небольшое усовершенствование GUI. В игре есть внутриигровое меню, в котором можно управлять яркостью экрана, громкостью звука, сохранять игру… Это меню иногда вызывает проблемы и может блокировать систему паузы, которая запускается нажатием кнопки меню.
Также я запланировал добавить в будущих обновлениях следующее:
- Поддержку эмуляции SNES. Я нахожусь в самом начале процесса, но мне кажется, что её можно заставить работать.
- Добавить репозиторий с внешними приложениями, как то:
- Bluetooth-геймпад.
- Анализатор сети Wi-Fi.
- Doom.
- Создать библиотеку Arduino для удобного создания скетчей для этого устройства.
Эмулятор GameBoy/GameBoy Color является портом эмулятора GNUBoy.
Эмулятор NES — это порт эмулятора Nofrendo, который изначально разрабатывался Espressif.
Эмулятор Sega Master System и Game Gear — это порт, реализованный Espressif.
Также стоит сказать, что на создание этого проекта меня вдохновили потрясающие устройства ESPlay micro и Odroid GO.
На правах рекламы
Воплощайте любые идеи и проекты с помощью наших серверов с мгновенной активацией на Linux или Windows. Сервер готов к работе через минуту после оплаты!