Пол — это лава: разработка прототипа интерактивной светодиодной игровой платформы

87d36119a6275f3a446850673291c67f.png

Дурная голова рукам покоя не даёт… история началась несколько месяцев назад: я увидел в интернете забавное видео игры в комнате с пиксельным светодиодным полом и решил сделать подобное для своих детей. За эти месяцы я получил массу удовольствия от процесса разработки и даже заразился идеей масштабирования проекта, но обо всём по порядку! Внимание, ниже будет много фото! А в конце статьи есть видео работы.

Идея

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

Пара слов обо мне

Пользуясь случаем, позвольте кратко представиться, так текст будет менее обезличенным.

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

Меня весьма вдохновляет прорабатывать полный производственный цикл изделия: от разработки схемотехники и написания низкоуровневого ПО на микроконтроллеры до продумывания конструктива и поиска редких метизов для сборки (это когда ты немного ошибся в 3D модели крепления датчика, а их уже напечатано более 320 штук *facepalm*).

Концепция

Вот примерный концепт того, каким я видел проект:

81bebe798729b0dd19e22ea4ce443192.png

Игровая комната:

  • пиксельный RGB-светодиодный интерактивный игровой пол с адекватным временем реакции на нажатие;

  • настенные кнопки для разнообразия игрового процесса;

  • табло с информацией по игре (название игры, общее время, время этапа, очки, жизни и т.п.);

  • колонки со звуковым сопровождением игры (озвучивать ошибки/победы/поражения, называть цели этапов, цвета и прочее).

Игровой контроллер:

  • приёмопередатчик для шины данных;

  • Ethernet / Wi-Fi канал для связи с внешним миром;

  • аудио выход для звукового сопровождения;

  • видео выход для табло.

Админ интерфейс:

  • отображение текущего состояния платформы и информации по игре;

  • запуск/остановка игр;

  • индивидуальная настройка пикселей (назначение адресов, коэффициентов, калибровка, дефектовка и т.д.);

  • конструктор игр;

  • всякого рода журналирование (игры, логи контроллера, ошибки и пр.).

Основная цель:  на старте заложить техническую возможность масштабирования платформы до размеров средней комнаты ~20–30 м2. На этом этапе лбами сталкиваются проблемы частоты обновления платформы и надёжности связи. По своей сути это взаимовытесняющие вещи: хочешь надёжно — пожертвуй скоростью, хочешь быстро — будь готов к потерям данных. Я не хотел тупо гнать сигнал через адресную ленту на базе WS2812B, это путь в никуда.

Скриншот из видео Activate Games

Скриншот из видео Activate Games

По итогу всех изысканий, в качестве интерфейса связи к пикселям, мной была выбрана шина CAN, я считаю она идеально ложится на вышеизложенную концепцию:

  • количество устройств в одной подсети может достигать до 120 шт. При группировке по 4 пикселя это обеспечит мне теоретический предел в 476 пикселей или примерно 34 м2, чего более чем достаточно на начальном этапе. Далее можно расширять путём введения дополнительных подсетей или увеличения количества пикселей в группах;

  • скорость передачи данных до 500 Кбит/с на 100 метров кабеля, чего как раз должно хватить, чтобы окольцевать 34 м2 площади. В эту скорость для тех же 476 пикселей, в зависимости от выбора протокола цветопередачи, можно будет уложить от 20 до 80 кадров в секунду;

  • возможность выстраивания приоритета сообщений в сети и разруливание коллизий через аппаратный механизм арбитража, что хорошо ложится на концепцию быстрого реагирования на нажатия. Короче говоря, сообщения о нажатии отправляются в шину вне очереди;

  • достаточно устойчивая связь вследствие использования дифференциального сигнала;

  • широкое распространение и дешевизна микросхем, что немаловажно.

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

Пиксель

Пиксель представляет собой классическую рамку с боковым расположением светодиодов, накрытую оргстеклом. Рамку выгрызали на ЧПУ фрезере из чёрной ламинированной фанеры толщиной 21 мм. Оргстекло мне тоже раскроили на ЧПУ при заказе, так доставка ТК обошлась в копейки, нежели доставлять лист 2×3 метра.

9b3f06cfde129cead357a573ade3d433.jpg1c5b1b31fd2be1a25c4be03b864a2098.jpg

Первая сложность возникает при выборе типа датчика нажатия. Рассматривал несколько вариантов:

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

То ли дело работа с аналоговыми тензодатчиками, когда свободный ход практически отсутствует (вспомните ваши напольные весы). К тому же есть пара идей, как применить аналоговый сигнал в играх… 

Так и поступил: было решено собирать ~85 напольных весов собственной разработки с проводным каналом связи и RGB подсветкой. Крепления для датчиков рисовал сам и заказывал печать на 3D принтере. Было напечатано около 340 таких креплений. Конструкцией доволен, получилось весьма надёжно и доступно для массового производства, в т.ч. и для литья. Нижняя часть пикселя выглядит колхозно, но это прототип, да простят меня эстеты.

c70163aedeba51c7a58e4dfaf6bb1e0e.jpg1a2b854246204e014d6ffe43bbc0125f.jpg

Электронная начинка и встроенное ПО пикселя

Как я упомянул ранее, я сгруппировал пиксели по 4 шт, а значит нужно два вида плат: групповая плата с модулем связи и контроллером и 4 маленьких платы просто с внешним АЦП для датчиков. По итогу я собрал 21 большую и 84 маленьких платы (на фото маленьких — это только половина от общего количества).

a5c6c932fed9d805e13e38c568b797f9.jpg94485d124787cdd5648e5edb8e185790.jpg

Основная идея была сделать пиксель максимально тупым. Он должен принимать/отображать цвет и отправлять нажатие. На словах это просто, а на деле, т.к. работа идёт с аналоговыми датчиками, нужен был периодический опрос с цифровыми фильтрами, всякими коэффициентами к ним, калибровками нуля и чувствительности и т.д., чтобы, в случае чего, можно было с бэкенда подкрутить параметры прямо на ходу, в т.ч. вывести пиксель из игры, если он начал неадекватно себя вести или залип.

Контроллер и управляющее ПО

Сначала у меня была идея делать собственный 3х канальный USB-CAN преобразователь и управлять платформой с обычного компьютера. Я даже успел развести и заказать платы, но потом передумал и в качестве контроллера выбрал обычную Raspberry Pi 4. В ней есть всё необходимое: Wi-Fi, аудио/hdmi выходы, а также к ней продаются готовые модули CAN шины. Сложной математики там нет, так что процессор справляется легко, я даже вывел метрики в админку на всякий случай.

aca8fd626d82b1c0077b4dc1955d167c.png21283ff43202eb5224c67e72a717855b.png

Управляющее ПО писал сам полностью с нуля: фронтенд — Vue.js, бэкенд — Golang, база данных — SQLite. Из того, что реализовано на данный момент:

  • отображение текущего состояния платформы (подсветка нажатий и текущего веса в кг);

  • игровое табло (время, очки, жизни);

  • просмотр информации по каждому пикселю в отдельности и отправка индивидуальных команд;

  • отправка широковещательных команд;

  • вывод метрик контроллера (загрузка/температура CPU, потребление памяти, основные метрики бэкенда);

  • простой конструктор кадров для игр;

  • несколько игровых механик: пол — это лава (нужно собрать все синие, не наступая на красные), море волнуется/пиксель дуэль (соревновательные режимы по сбору своего цвета, побеждает самый ловкий), безопасный цвет (робот озвучивает цвет, нужно успеть его найти и занять), классики (пропрыгать случайный паттерн), несколько демо режимов;

  • старт/стоп/пауза игр с возможностью конфигурации непосредственно в момент старта игры (например, для детей я отключал контроль жизней и увеличивал время этапа);

  • имитация игр мышкой прямо через админку для непосредственного тестирования игры после конструктора (ну или вмешивания прямо в процесс игры… хе-хе, я так помогал своей дочке побеждать пару раз, чтоб не расстраивалась).

Сборка прототипа и выявленные проблемы

Сборка такого количества плат и пикселей в одиночку у меня заняла больше месяца: сверлить, прикручивать, приклеивать, паять, отлаживать и перепаивать сгоревшее. К расстановке компонентов на платы я привлекал даже дочь… как говорится, любишь играть, люби и платы собирать!  

44863532196956e4ce8f0fbffee49c28.jpg

Какие ошибки допустил в процессе разработки:

Ошибка 1:  Оргстекло

Найти оргстекло или поликарбонат подходящей толщины оказалось проблемой. В наличии из импортного ничего нет, толстое вообще не в почёте, а если заказывать, то нужен объём + большие сроки. Взял лист оргстекла от какого-то российского производителя, а оно оказалось недостаточно молочным (см. фото), очень сильно просвечивал источник света, пришлось каждый квадратик вручную дополнительно матовать шлиф машинкой… то ещё удовольствие.

7986041f84bbf4d462ffda408e71b308.jpgb8566336db0f90f8d4667cb6984c2a85.jpg

Ошибка 2: Россыпь плат, а не панель

Я торопился и заказал платы не панелями, а россыпью… это было немного больно и приходилось наносить пасту на платы поштучно. Я купил трафаретный принтер для нанесения пасты и мини стол для оплавления припоя, это в десятки раз ускорило процесс. Трафаретный принтер — самоделка одного замечательного человека с ютуба, кому будет интересно, могу дать контакт в комментариях.

8da9f9c8a74b38230dd596b72119f2a7.jpg

Ошибка 3:  Танталовые конденсаторы

Танталовые конденсаторы сами по себе достаточно капризная штука, а заказывать их с Китая было вдвойне ошибкой… брака было около 40%: они просто взрывались при напряжении в половину от номинала. Я проверял их непосредственно перед пайкой, но даже это не помогло… несколько штук вышло из строя прямо в день мероприятия, проработав перед этим около месяца дома. В следующий раз поставлю бочонки, благо высота позволяет, они не так горят.

7ebe5bd1dfe5196a0fcbbd32d29e1d59.jpg

Ошибка 4:  Таблица на фронтенде

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

d51e061eaa774a0de22b9da0e707e154.png

Ошибка 5:  Экономия на протоколе передачи

Цветовые эффекты немного скудные, недостаточная цветопередача, т.к. сэкономил на протоколе. Рассчитать всё в теории — легко, но опыт подсказывал, что теоретические пределы скорости не практике недостижимы, боялся не получить требуемую частоту обновления, поэтому заранее ужимал протокол, хотя при таком размере поля можно было особо не беспокоиться.

2116d2919f3aa2bab99c7125eb9345e3.jpg

Ошибка 6:  Размытая граница пикселя и неравномерность засветки

Мне не нравятся размытые контура пикселей, хочется сделать их более чёткими, это будет смотреться гораздо круче. Качество засветки тоже можно улучшить, используя более глубокую рамку и правильное оргстекло.

5b94856dd8ed937c0e58bd7c0521084e.png

Ошибка 7:  Дешёвая светодиодная лента

Было куплено около 90 метров «высококлассной» китайской светодиодной ленты… которая оказалась явно б/у, имела разное свечение и много раз перегорала. Но тут вынужденная экономия на прототипе.

cbbc2f1f86ea2a609661173a3d676292.jpg

Идеи на будущее:

  • Расширение группы до 9 шт. — это будет явное удешевление, повышение надёжности связи за счёт уменьшения устройств на шине и расширение теоретического предела площади игровой зоны;

  • Соты! Очень хочу гексагональное игровое поле, это должно выглядеть весьма круто!

  • Настенные кнопки;

  • Быстрые соединения. Из-за использования в прототипе винтовых клеммников, сборка платформы перед детским праздником у меня заняла около 2.5 часов, что очень много. Буду прорабатывать быстрые соединения;

  • Ну и конечно, разные-разные механики игр! В голове масса идей: всякого рода змейки, пакман, эстафеты, арканоид, захват территорий, повтор рисунка, те же танцы, твистер…

75285fb02ba3e76b239852956e1620f5.jpeg

Как корабль назовёшь… и заключение

При выборе кодового имени проекта было несколько разных вариантов. Больше всего мне симпатизирует название «Pixel Quest» ввиду широкого распространения в народе понятия «квест-комната». Сразу занял под это дело домен и, как это водится, завёл отдельный ТГ канал @pixel_quest для публикации прогресса разработки и дальнейших обсуждений с заинтересовавшимися читателями. Заходите в гости, буду держать в курсе событий.

Статью пишу ради новых знакомств, поиска поддержки и идей для дальнейшего развития проекта. Я технарь, а не предприниматель, и, если честно, плохо представляю, как правильно превратить это в бизнес. Я не умею в эти ваши «найди инвестиции / собери команду / захвати мир» (но это пока что), не умею писать бизнес-планы, хочу просто делать интересный продукт и радовать людей. Буду рад любым советам! Личный телеграм для связи:  @AnatoliyB

В ближайший планах найти подходящее помещение у себя в городе (Смоленске) для построения первой комнаты с увеличенной игровой зоной и полноценного тестирования. Хочу развивать идею как по направлению целых игровых квест-комнат, так и небольших игровых платформ 4–6 м2 для установки в детских комнатах или сдачи в аренду на детские праздники.

4c17a01ac4df041661067df0217799c6.jpeg

Итого:

  • Потрачено:  ~300 тыс. руб.

  • Заработано:  0 руб.

  • Удовольствие от процесса разработки и праздника для детей:  бесценно!

Спасибо всем, кто дочитал! Пишите свои мысли и идеи игр в комментариях!

© Habrahabr.ru