Привет, Хабр! Хочу рассказать об одном из своих любимых DIY проектов, который я реализовал еще пару лет назад. Данным проектом я хотел закрыть две цели: во-первых, подготовить подарок на день рождения своей племяннице (Ксюша, привет!), во-вторых, переползти с микроконтроллеров Atmel на ST. Также хотел получить опыт в использовании С++ во embedded устройствах.

Итак, подробнее о девайсе. Устройство представляет собой портативную игровую консоль с (пока что) одной игрой на борту - Змейка. Основные правила игры не отличаются от тех, что мы видели на первых кнопочных телефонах. С помощью джойстика направляем наше пресмыкающееся в сторону еды, кнопкой "speed" изменяем скорость передвижения в любой момент игры. "Бесшовное" игровое поле: змейка не разбивается о край, а появляется на противоположной стороне экрана. Цель - съесть как можно больше, стараясь не перекусить собственный хвост.

Блок схема устройства
Блок схема устройства

Микроконтроллер

В качестве микроконтроллера(далее - МК) выбрал STM32F103C8T6. Так как в наличие была отладочная плата Blue Pill + отдельно лежали камни, которые я мог пустить в ход при работе над своей платой. На тот момент времени заполучить этот МК за приемлемую цену не было проблемой(минутка ностальгии????) . МК обладает всей необходимой периферией для работы с остальными блоками устройства.

Экран

Физически игровое поле представляет собой матрицу адресных светодиодов WS2812B размерностью 16х16 штук. В каждом светодиоде имеется встроенный контроллер, который декодирует полученный цифровой сигнал и преобразует его значение в уровень яркости для каждого из трех основных цветов. Яркость кодируется следующим образом:

Формат данных WS2812B. Источник: https://learn.sparkfun.com/tutorials/ws2812-breakout-hookup-guide/ws2812-hardware-overview

Необходимо передать на вход 24 бита, по 8 бит на каждый цвет в формате G->R->B. Об окончании пакета сигнализирует пауза в передачи данных. Логические уровни удобнее всего генерировать с помощью широтно-импульсной модуляции(PWM), изменяя скважность сигнала. Использовал для этого аппаратный таймер МК. Для того чтобы обновление кадров на экране происходило "на фоне" других задач использовал так блок Direct Memory Access(DMA). Это по сути контроллер внутри МК, который может самостоятельно, без участия процессора, перемещать данные из памяти в периферию.

Процессор, когда это необходимо, обновляет данные для формирования кадра на экране, а DMA благополучно перемещает их в регистры таймера.
Процессор, когда это необходимо, обновляет данные для формирования кадра на экране, а DMA благополучно перемещает их в регистры таймера.

Управление

По сути джойстик представляет собой два переменных резистора. При наклоне ручки по любой из двух взаимно перпендикулярных осей, происходит изменение напряжения на соответствующем выходе. По этим значениям можно найти положение ручки относительно центра. Для измерения напряжений с выходов джойстика использовал встроенный в МК аналого-цифровой преобразователь(АЦП). В основной программе запускается таймер, затем по его переполнении с блока АЦП фиксируется текущее цифровое значение аналогового сигнала на входе. Таким образом, косвенно определяется положение джойстика и соответственно направление движения змейки.

Питание

Как говорят: если хочешь что-то получить, ты должен отдать взамен нечто равноценное. Так вот, чтобы достать элемент питания пришлось принести в жертву одну из своих китайских безделушек. Добытый литиевый аккумулятор оказался без маркировки емкости. Однако судя по габаритам, прикинул, что как минимум на полтора часа работы должно хватить. В реальности автономность устройства оказалась даже больше. Аккумулятор подключал через модуль на TP4056.

Модуль на TP4056
Модуль на TP4056

Это плата контроля заряда. Помимо этого защищает аккумулятор от переразряда и короткого замыкания. Максимальная сила тока, заряжающего батарею, устанавливается резистором R3. Чтобы не допустить перегрева аккумулятора установил практически минимальный ток. Также модуль имеет индикацию: пока идет заряд светит красный светодиод, а когда батарея полностью зарядится вместо красного загорится синий\зеленый светодиод. Чтобы вынести эту информацию на поверхность корпуса пришлось выпаять родные светодиоды и поставить свои, закрепив их в держатели.

На основной плате управления расположил батарейку CR2032 для обеспечения работы часов реального времени(RTC) при отсутствии основного питания. Блок RTC здесь выступает как источник энтропии для генерации случайного числа, которое в свою очередь используется для создания параметров(координаты, цвет) съедобного пикселя для нашей змейки.

Корпус

Так сложилось, что первым моим CADом для 3D моделирования стал OnShape, который я благополучно использовал для всех своих DIY проектов. Это замечательный тул, для тех кто не хочет устанавливать какое-либо ПО, а работать прямо из браузера. Но самое большое преимущество, по крайней мере для меня, это то, что я обладал учебной лицензией:) Потом, в 2022 году так вышло, что аккаунт вместе с десятком моих моделей деактивировали. Это вынудило меня пересесть на SolidWorks, о чем я нисколько не жалею.

Верх. Управляющая плата крепится на стойки через три отверстия в центре верхней крышки.
Верх. Управляющая плата крепится на стойки через три отверстия в центре верхней крышки.
Низ. Не забыл про отверстия под тумблер питания и разъема для зарядки.
Низ. Не забыл про отверстия под тумблер питания и разъема для зарядки.
Внутри. Соединение крышки и основания выполнено на 4 винтах. Этого оказалось достаточно - зазоров почти нет.
Внутри. Соединение крышки и основания выполнено на 4 винтах. Этого оказалось достаточно - зазоров почти нет.
Для защиты матрицы от попадания влаги натянул полимерную пленку Lomond
Для защиты матрицы от попадания влаги натянул полимерную пленку Lomond

Самая большая сложность в работе над корпусом это было перенести его из виртуального мира в физический. Большая площадь и изгибы поверхности девайса доставляли неудобства при настройке 3D принтера на печать. ABS пластик норовил отклеится от стола, а обилие поддержек давало большой перерасход материала. Делить деталь и печатать по частям я не хотел, по той причине, что потом после склейки будут видны стыки и швы.

В дальнейшем планирую расширить список доступных игр на консоли. Вполне получится добавить тетрис. Это не потребует изменений в органах управления.

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

Комментарии (15)


  1. dlinyj
    07.08.2023 14:50
    +5

    Очень круто! Правда в статье хотелось бы больше разбора полётов по ПО, по проектированию и изготовлению. Но изделие получилось очень крутым!


  1. Ivnika
    07.08.2023 14:50
    +4

    Надо было затемненное стекло поставить :)

    Кстати, разве в классической змейке можно в стены врезаться?!


    1. retrodolivo Автор
      07.08.2023 14:50

      Затемнить экран это отличная идея! Совершенно не приходила в голову. А змейки с бесшовной картой наверное тоже уже можно считать классическими :)


      1. tormozedison
        07.08.2023 14:50

        Существуют и те и другие.


  1. alef13
    07.08.2023 14:50

    специально для левшей?


    1. jamiederinzi
      07.08.2023 14:50

      Крестик / стик под левой рукой это же классика.


      1. retrodolivo Автор
        07.08.2023 14:50

        Все верно. Опирался на дизайн геймпадов - передвижения слева, действия справа


  1. deema35
    07.08.2023 14:50

    Я конечно понимаю что автор без ума от подобных diy штук. Но мне кажется что племянница вряд ли будет в восторге от такой гигантской штуковины, которая ещё не во всякий карман влезет. Молодёжь сейчас предпочитает играть в змейку на мобильных телефонах.


    1. koresh_builder
      07.08.2023 14:50
      +3

      У- уникальность. Телефон покупной, а тут личный персональный дядька запилил хитрую штуку. Не у каждой племянницы есть такой дядя.)


      1. deema35
        07.08.2023 14:50
        +5

        Просто когда человек сам сделал подобный аппарат и играет на нем он как-бы бросает вызов обществу. Он как-бы говорит "вот смотрите я сам сделал этот аппарат, который в сто раз круче вашего жалкого, никчемного айфона". А если ты не сам его сделал ты даже этого сказать не можешь.


    1. acsent1
      07.08.2023 14:50

      Такая штука хороша для детской комнады с игрушками. Типо посмотреть, потрогать, понажимать. Чисто играть в нее интересно наверно мин 5


  1. latonita
    07.08.2023 14:50

    Отличная штука! Только вот бы затонировать стекло, чтобы глаза не разрывало от клеточек выключённых светодиодов)


    1. aumi13
      07.08.2023 14:50

      белый листик подложыть)


  1. DrGluck07
    07.08.2023 14:50

    BTW, сейчас можно брать всяких китайцев и устанавливать их вместо родных STM. Например сюда прекрасно встанет GD32F103C8T6. Но, как мне кажется, работа с периферией там немного отличается, т.е. придётся переписывать уровень HAL.


  1. Khan54rus
    07.08.2023 14:50
    +1

    Красота. К тонированию стекла предлагаю добавить сетку для каждого пикселя, как, например, в видео AlexGyver https://youtu.be/WtiJ0cg-Mpc
    Её не обязательно вырезать, можно распечатать.