Пол — это лава: разработка прототипа интерактивной светодиодной игровой платформы
Дурная голова рукам покоя не даёт… история началась несколько месяцев назад: я увидел в интернете забавное видео игры в комнате с пиксельным светодиодным полом и решил сделать подобное для своих детей. За эти месяцы я получил массу удовольствия от процесса разработки и даже заразился идеей масштабирования проекта, но обо всём по порядку! Внимание, ниже будет много фото! А в конце статьи есть видео работы.
Идея
Идея в целом не уникальна, но я не нашёл в продаже каких-то готовых решений. В том же Китае продаются платформы без обратной связи и без игровых возможностей, у них это называется светодиодный танцевальный пол. Но это всё не то, что я хотел, а значит надо делать самому. Всегда любил работать со светодиодами, это приносит огромное эстетическое удовольствие, и в целом я скучал по работе с электроникой, так что решил сдуть пыль с паяльной станции и прикупить ещё некоторое оборудование.
Пара слов обо мне
Пользуясь случаем, позвольте кратко представиться, так текст будет менее обезличенным.
В жизни меня зовут Анатолием, в прошлом я более 5 лет проработал на крупном заводе инженером-схемотехником-программистом (нужное подчеркнуть), так что присутствует какой-никакой реальный опыт и понимание процесса массового производства электроники, надеюсь ещё пригодится. Последние 5 лет работаю фуллстек разработчиком. Так и решил совместить эти две области в одном проекте.
Меня весьма вдохновляет прорабатывать полный производственный цикл изделия: от разработки схемотехники и написания низкоуровневого ПО на микроконтроллеры до продумывания конструктива и поиска редких метизов для сборки (это когда ты немного ошибся в 3D модели крепления датчика, а их уже напечатано более 320 штук *facepalm*).
Концепция
Вот примерный концепт того, каким я видел проект:
Игровая комната:
пиксельный RGB-светодиодный интерактивный игровой пол с адекватным временем реакции на нажатие;
настенные кнопки для разнообразия игрового процесса;
табло с информацией по игре (название игры, общее время, время этапа, очки, жизни и т.п.);
колонки со звуковым сопровождением игры (озвучивать ошибки/победы/поражения, называть цели этапов, цвета и прочее).
Игровой контроллер:
приёмопередатчик для шины данных;
Ethernet / Wi-Fi канал для связи с внешним миром;
аудио выход для звукового сопровождения;
видео выход для табло.
Админ интерфейс:
отображение текущего состояния платформы и информации по игре;
запуск/остановка игр;
индивидуальная настройка пикселей (назначение адресов, коэффициентов, калибровка, дефектовка и т.д.);
конструктор игр;
всякого рода журналирование (игры, логи контроллера, ошибки и пр.).
Основная цель: на старте заложить техническую возможность масштабирования платформы до размеров средней комнаты ~20–30 м2. На этом этапе лбами сталкиваются проблемы частоты обновления платформы и надёжности связи. По своей сути это взаимовытесняющие вещи: хочешь надёжно — пожертвуй скоростью, хочешь быстро — будь готов к потерям данных. Я не хотел тупо гнать сигнал через адресную ленту на базе WS2812B, это путь в никуда.
Скриншот из видео Activate Games
По итогу всех изысканий, в качестве интерфейса связи к пикселям, мной была выбрана шина CAN, я считаю она идеально ложится на вышеизложенную концепцию:
количество устройств в одной подсети может достигать до 120 шт. При группировке по 4 пикселя это обеспечит мне теоретический предел в 476 пикселей или примерно 34 м2, чего более чем достаточно на начальном этапе. Далее можно расширять путём введения дополнительных подсетей или увеличения количества пикселей в группах;
скорость передачи данных до 500 Кбит/с на 100 метров кабеля, чего как раз должно хватить, чтобы окольцевать 34 м2 площади. В эту скорость для тех же 476 пикселей, в зависимости от выбора протокола цветопередачи, можно будет уложить от 20 до 80 кадров в секунду;
возможность выстраивания приоритета сообщений в сети и разруливание коллизий через аппаратный механизм арбитража, что хорошо ложится на концепцию быстрого реагирования на нажатия. Короче говоря, сообщения о нажатии отправляются в шину вне очереди;
достаточно устойчивая связь вследствие использования дифференциального сигнала;
широкое распространение и дешевизна микросхем, что немаловажно.
Пессимистично делим все теоретические пределы на 4 и всё равно остаёмся в рамках разумного, жить будет. Поехали дальше!
Пиксель
Пиксель представляет собой классическую рамку с боковым расположением светодиодов, накрытую оргстеклом. Рамку выгрызали на ЧПУ фрезере из чёрной ламинированной фанеры толщиной 21 мм. Оргстекло мне тоже раскроили на ЧПУ при заказе, так доставка ТК обошлась в копейки, нежели доставлять лист 2×3 метра.
Первая сложность возникает при выборе типа датчика нажатия. Рассматривал несколько вариантов:
Мне сразу не понравилась идея использовать механический переключатель, т.к. для этого потребуется обеспечить подпружиненный свободный ход оргстекла и при этом избежать залипаний. В эту же категорию идут и датчики из двух пластин, работающих на замыкание, как в танцевальных аппаратах.
То ли дело работа с аналоговыми тензодатчиками, когда свободный ход практически отсутствует (вспомните ваши напольные весы). К тому же есть пара идей, как применить аналоговый сигнал в играх…
Так и поступил: было решено собирать ~85 напольных весов собственной разработки с проводным каналом связи и RGB подсветкой. Крепления для датчиков рисовал сам и заказывал печать на 3D принтере. Было напечатано около 340 таких креплений. Конструкцией доволен, получилось весьма надёжно и доступно для массового производства, в т.ч. и для литья. Нижняя часть пикселя выглядит колхозно, но это прототип, да простят меня эстеты.
Электронная начинка и встроенное ПО пикселя
Как я упомянул ранее, я сгруппировал пиксели по 4 шт, а значит нужно два вида плат: групповая плата с модулем связи и контроллером и 4 маленьких платы просто с внешним АЦП для датчиков. По итогу я собрал 21 большую и 84 маленьких платы (на фото маленьких — это только половина от общего количества).
Основная идея была сделать пиксель максимально тупым. Он должен принимать/отображать цвет и отправлять нажатие. На словах это просто, а на деле, т.к. работа идёт с аналоговыми датчиками, нужен был периодический опрос с цифровыми фильтрами, всякими коэффициентами к ним, калибровками нуля и чувствительности и т.д., чтобы, в случае чего, можно было с бэкенда подкрутить параметры прямо на ходу, в т.ч. вывести пиксель из игры, если он начал неадекватно себя вести или залип.
Контроллер и управляющее ПО
Сначала у меня была идея делать собственный 3х канальный USB-CAN преобразователь и управлять платформой с обычного компьютера. Я даже успел развести и заказать платы, но потом передумал и в качестве контроллера выбрал обычную Raspberry Pi 4. В ней есть всё необходимое: Wi-Fi, аудио/hdmi выходы, а также к ней продаются готовые модули CAN шины. Сложной математики там нет, так что процессор справляется легко, я даже вывел метрики в админку на всякий случай.
Управляющее ПО писал сам полностью с нуля: фронтенд — Vue.js, бэкенд — Golang, база данных — SQLite. Из того, что реализовано на данный момент:
отображение текущего состояния платформы (подсветка нажатий и текущего веса в кг);
игровое табло (время, очки, жизни);
просмотр информации по каждому пикселю в отдельности и отправка индивидуальных команд;
отправка широковещательных команд;
вывод метрик контроллера (загрузка/температура CPU, потребление памяти, основные метрики бэкенда);
простой конструктор кадров для игр;
несколько игровых механик: пол — это лава (нужно собрать все синие, не наступая на красные), море волнуется/пиксель дуэль (соревновательные режимы по сбору своего цвета, побеждает самый ловкий), безопасный цвет (робот озвучивает цвет, нужно успеть его найти и занять), классики (пропрыгать случайный паттерн), несколько демо режимов;
старт/стоп/пауза игр с возможностью конфигурации непосредственно в момент старта игры (например, для детей я отключал контроль жизней и увеличивал время этапа);
имитация игр мышкой прямо через админку для непосредственного тестирования игры после конструктора (ну или вмешивания прямо в процесс игры… хе-хе, я так помогал своей дочке побеждать пару раз, чтоб не расстраивалась).
Сборка прототипа и выявленные проблемы
Сборка такого количества плат и пикселей в одиночку у меня заняла больше месяца: сверлить, прикручивать, приклеивать, паять, отлаживать и перепаивать сгоревшее. К расстановке компонентов на платы я привлекал даже дочь… как говорится, любишь играть, люби и платы собирать!
Какие ошибки допустил в процессе разработки:
Ошибка 1: Оргстекло
Найти оргстекло или поликарбонат подходящей толщины оказалось проблемой. В наличии из импортного ничего нет, толстое вообще не в почёте, а если заказывать, то нужен объём + большие сроки. Взял лист оргстекла от какого-то российского производителя, а оно оказалось недостаточно молочным (см. фото), очень сильно просвечивал источник света, пришлось каждый квадратик вручную дополнительно матовать шлиф машинкой… то ещё удовольствие.
Ошибка 2: Россыпь плат, а не панель
Я торопился и заказал платы не панелями, а россыпью… это было немного больно и приходилось наносить пасту на платы поштучно. Я купил трафаретный принтер для нанесения пасты и мини стол для оплавления припоя, это в десятки раз ускорило процесс. Трафаретный принтер — самоделка одного замечательного человека с ютуба, кому будет интересно, могу дать контакт в комментариях.
Ошибка 3: Танталовые конденсаторы
Танталовые конденсаторы сами по себе достаточно капризная штука, а заказывать их с Китая было вдвойне ошибкой… брака было около 40%: они просто взрывались при напряжении в половину от номинала. Я проверял их непосредственно перед пайкой, но даже это не помогло… несколько штук вышло из строя прямо в день мероприятия, проработав перед этим около месяца дома. В следующий раз поставлю бочонки, благо высота позволяет, они не так горят.
Ошибка 4: Таблица на фронтенде
Я ненастоящий фронтендер и умею клепать только админки для внутреннего использования. Как мне кажется, было ошибкой использовать на фронтенде простую таблицу. Хоть обновление ячеек и сделано реактивно на тегах, но рендер всего поля разом немного подтормаживает. Скорее всего нужно будет переходить на графику, проконсультируюсь чуть позже с опытными коллегами.
Ошибка 5: Экономия на протоколе передачи
Цветовые эффекты немного скудные, недостаточная цветопередача, т.к. сэкономил на протоколе. Рассчитать всё в теории — легко, но опыт подсказывал, что теоретические пределы скорости не практике недостижимы, боялся не получить требуемую частоту обновления, поэтому заранее ужимал протокол, хотя при таком размере поля можно было особо не беспокоиться.
Ошибка 6: Размытая граница пикселя и неравномерность засветки
Мне не нравятся размытые контура пикселей, хочется сделать их более чёткими, это будет смотреться гораздо круче. Качество засветки тоже можно улучшить, используя более глубокую рамку и правильное оргстекло.
Ошибка 7: Дешёвая светодиодная лента
Было куплено около 90 метров «высококлассной» китайской светодиодной ленты… которая оказалась явно б/у, имела разное свечение и много раз перегорала. Но тут вынужденная экономия на прототипе.
Идеи на будущее:
Расширение группы до 9 шт. — это будет явное удешевление, повышение надёжности связи за счёт уменьшения устройств на шине и расширение теоретического предела площади игровой зоны;
Соты! Очень хочу гексагональное игровое поле, это должно выглядеть весьма круто!
Настенные кнопки;
Быстрые соединения. Из-за использования в прототипе винтовых клеммников, сборка платформы перед детским праздником у меня заняла около 2.5 часов, что очень много. Буду прорабатывать быстрые соединения;
Ну и конечно, разные-разные механики игр! В голове масса идей: всякого рода змейки, пакман, эстафеты, арканоид, захват территорий, повтор рисунка, те же танцы, твистер…
Как корабль назовёшь… и заключение
При выборе кодового имени проекта было несколько разных вариантов. Больше всего мне симпатизирует название «Pixel Quest» ввиду широкого распространения в народе понятия «квест-комната». Сразу занял под это дело домен и, как это водится, завёл отдельный ТГ канал @pixel_quest для публикации прогресса разработки и дальнейших обсуждений с заинтересовавшимися читателями. Заходите в гости, буду держать в курсе событий.
Статью пишу ради новых знакомств, поиска поддержки и идей для дальнейшего развития проекта. Я технарь, а не предприниматель, и, если честно, плохо представляю, как правильно превратить это в бизнес. Я не умею в эти ваши «найди инвестиции / собери команду / захвати мир» (но это пока что), не умею писать бизнес-планы, хочу просто делать интересный продукт и радовать людей. Буду рад любым советам! Личный телеграм для связи: @AnatoliyB
В ближайший планах найти подходящее помещение у себя в городе (Смоленске) для построения первой комнаты с увеличенной игровой зоной и полноценного тестирования. Хочу развивать идею как по направлению целых игровых квест-комнат, так и небольших игровых платформ 4–6 м2 для установки в детских комнатах или сдачи в аренду на детские праздники.
Итого:
Потрачено: ~300 тыс. руб.
Заработано: 0 руб.
Удовольствие от процесса разработки и праздника для детей: бесценно!
Спасибо всем, кто дочитал! Пишите свои мысли и идеи игр в комментариях!