Картинка Freepik

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

Однако, в целом, сам код прошивки таких машинок, и вся система управления в целом достаточно сложные, и, может быть, чуть позже, я расскажу о прошивке более подробно.

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

При такой системе управления, машинки ещё недоступны для управления через интернет, но ими можно управлять напрямую, имея машинки/иные устройства в прямой видимости.

Чем хорош такой подход: за счёт применения в качестве пультов радиоуправления обычных смартфонов, легко реализовать общедоступную систему игры, где не нужно думать об опасности воровства/ поломки пультов, а сами устройства, которыми происходит управление, могут находиться даже в недоступной для людей в зоне — например, закрытые прозрачным оргстеклом.

Примерно такая система игры, правда, без какого-либо закрытия от контакта с людьми самих машинок, — была реализована мной в одной из школ Москвы, где прошли пробные игры, а дети могли управлять машинками, играя ими в футбол, команда на команду (на фото ниже, предыдущая итерация машинок — с одним аккумулятором 18650, в актуальной версии их два).


При этом, в качестве «мяча» использовался шарик для настольного тенниса, который весьма активно «летал» по игровому полю, от малейшего удара машинок, что делало игру весьма динамичной.

Могу сказать, по результатам игры, что получилось весьма азартно, страсти кипели нешуточные и стояла довольно приличная очередь! :-)

А теперь, представим то же самое, только реализованное в офисе какой-либо компании, где люди могут подойти и поиграть друг с другом, команда на команду, используя для этого свой смартфон! Вот вам и тимбилдинг, да ещё и весьма увлекательный…

При некоторой выдумке, используя либо встроенные в прошивку средства (что вряд ли, так как может не хватить ресурсов), либо внешний сервер (что более вероятно) — можно даже попробовать реализовать компьютерного соперника, примерно также, как в компьютерных играх, только здесь соперник управляет не виртуальными персонажами, а абсолютно реальными устройствами, играя против вас! Думаю, что увлекательность подобной системы будет зашкаливать…

Но это была некоторая предыстория, а теперь перейдём к аппаратной и программной части системы.

Что представляли собой машинки


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

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

При этом движение вперёд/назад осуществлялось одновременным вращением в одну сторону/обратно — двух отдельных микроэлектродвигателей с металлическим редуктором (модель N20), установленных на каждое из двух колёс. Повороты — вращением каждого двигателя — в свою сторону. Двигатели были рассчитаны на 500 об/мин, при питании от 3V.

image
Картинка: aliexpress.ru

Тем не менее чуть позже выяснилось, что при таком питании, машинки были достаточно вялыми. Поэтому пришлось искусственно увеличить питающее напряжение до 12 вольт, используя два параллельно подключённых DC-DC преобразователя.

Предваряя вопросы: нет, двигатели не умерли. Мало того, отработали весьма продолжительное время (суммарно, несколько дней), без каких-либо последствий для себя. По крайней мере, за период множества проведённых игр, эти последствия никак не проявили себя.

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

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

В качестве драйвера двигателей использовался простенький HG7881CP.

image
Картинка: aliexpress.ru

Из основных плюсов которого: простой, дешёвый и маленький. Из минусов: всё остальное:-))) А именно: легко выгорает.

Например, опытным путём было найдено значение ШИМ, при котором не происходит непрогнозируемого выгорания, в неожиданный момент: так как использовался восьмибитный ШИМ (т.е. из 256 значений), то в нашем случае, оптимальное значение составляло 100.

Тут надо сделать оговорку: можно, конечно, гонять и на максимальной скорости, но, тогда, с этим драйвером, возникнет риск непроизвольных выгораний.

В качестве дополнительной информации: было выявлено, что при поворотах, то бишь, при задействовании каналов на максимальном значении ШИМ (255), — выгорания не происходит (так как время осуществления поворота очень мало и драйвер работает малый отрезок времени), в то время как при движении вперёд или назад на максимальной скорости — риск выгорания драйвера возрастает кратно.

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

Частота ШИМ была выставлена на 30000 Гц (для верности, за пределами слышимого диапазона в 20000 Гц), так как иначе (например, пробовали на 5000 Гц) при работе двигателей сильно слышен высокочастотный звон, который издают пластины якоря двигателя при появлении импульсов тока.

В качестве идеи: можно просто поставить параллельно два драйвера, если уж так сильно хочется остаться именно на них, таким образом, пропускная способность по току такого составного устройства увеличится: по отдельному драйверу на каждый двигатель. Кроме того: запитывать каждый двигатель не через один канал драйвера, а сразу через оба. Таким образом, с очень большой вероятностью, проблема перестанет существовать. Но, опять же повторюсь, для нас в этом не было нужды, так как мы нашли другое решение (просто ограничив максимальную величину ШИМ).

В качестве источника питания системы, после множества экспериментов, были выбраны два элемента 18650, установленные без какого-либо контролёра разряда.

Да, это плохо, знаю. Поэтому на следующих итерациях, этот момент был пофиксен следующим образом: поставлен делитель напряжения, и установлена библиотека, отслеживающая напряжение на этой сборке аккумуляторов.

При падении до определённого порогового уровня (3 Вольта, если правильно помню), — машинка останавливалась и отказывалась принимать какие-либо команды, и на ней постоянно мигал синий светодиод. То бишь, это означало, что требуется смена аккумуляторов.

Вы же, в качестве источника питания своих машинок, можете использовать обычные батарейки.

Также, в этой итерации отсутствовало какое-либо выравнивание скоростей двигателей. Суть здесь вот в чём: если вы ещё не сталкивались: два двигателя, включенных, даже одновременно, не будут вращаться с одной и той же скоростью.

Обусловлено это несовершенством процесса производства на заводе, в виду чего двигатели имеют небольшое отличие друг от друга: немного не так намотаны обмотки, немного не такой редуктор, другая индукция магнитов, в виду немного другого их размера и т.д. Кроме того, это могут усугублять и чисто электронные процессы (несинхронность подачи управляющих команд). Поэтому, обычно используют электронное выравнивание скоростей двигателей, с постоянным отслеживанием скорости вращения каждого двигателя. В этой итерации — подобное управление отсутствует. Что тем не менее, не делает игру менее увлекательной. Несколько менее предсказуемой — да. Но увлекательность никак не страдает (проверено опытным путём).

Таким образом, машинки представляли собой платформы, имеющие возможность перемещаться строго вперёд/назад/влево/вправо («подруливание» в процессе езды отсутствует), а удар наносить по мячу — с помощью вращения вокруг оси, используя подвешенную сбоку клюшку (планировался изначально хоккей с шайбой, но «хоккей с мячом» оказался интересней).

О прошивке


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

При выборе системы управления машинками, после некоторого обсуждения были приняты следующие принципиальные моменты:

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

В полной мере таким принципам соответствует websocket-подход, когда, на микроконтроллере управляемого устройства (в нашем случае — esp32), запускается маленькая веб-страничка, доступная по определённому адресу и действия пользователя на ней постоянно передаются на исполнение микроконтроллеру.

На этой страничке показываются виртуальные клавиши для управления, постоянно отслеживающие нажатия и отжатия на них:



В качестве «донора» для написания такого кода был взят код вот отсюда. Кстати говоря, он там весьма подробно объяснён, так что рекомендую для прочтения и ознакомления.

Поэтому, чтобы не повторять сказанное там, объясню, буквально в двух словах, как работает код: при запросе по определённому ip-адресу из браузера, в браузере загружается веб-страница с виртуальными кнопками.

Любое нажатие/отжатие такой кнопки — сразу отправляет одно из текстовых сообщений из браузера — на esp32: Forward/Left/LeftSlow/Right/RightSlow/Reverse/Stop.

На esp32 запущен асинхронный веб-сервер, получающий входящие сообщения с помощью функции onEvent() после чего функция handleWebsocketMessage() и производит определённые манипуляции с двигателями.

Код до конца не оптимизирован, так как уже тогда предполагались дальнейшие апгрейды системы, тем не менее, всё работает.

Скачать прошивку можно здесь.

При желании вы можете оптимизировать его по своему усмотрению (как минимум создать отдельную функцию, по-разному управляющую двигателями, в зависимости от получаемых на вход данных).

Дальнейшие улучшения


Для осуществления непосредственной связи между смартфоном и машинкой, на смартфоне запускается точка доступа, а в машинку забивается название этой сети и её пароль. При включении машинки, и точки доступа на смартфоне — они коннектятся.

Тут была выявлена проблема: постоянная смена ip-адреса машинки, что весьма неудобно (в момент проведения игр, так как не было времени проапгрейдить всю систему, приходилось подключать машинку к компьютеру, и смотреть в мониторе порта, какой ip-адрес получила машинка в данный момент). Возникали даже идеи по приделыванию к машинке OLED экранчика, с отображением актуального ip-адреса.

Тем не менее, существует более простой вариант: переделать машинку в точку доступа. Так как в данный момент точкой доступа является смартфон, то, при таком подходе, машинка постоянно будет иметь один и тот же ip-адрес, который можно просто-напросто написать на её корпусе! Подробное описание решения с созданием своей точки доступа описано вот здесь.

Либо же использовать другой подход: так как создание точки доступа автоматически подразумевает задание ей уникального имени (то есть названия сети, которое будет отображаться в эфире), то в момент проведения игр можно просто на доске написать все названия сетей (mashinka_1, mashinka_2 и т.д.) и их пароли (или раздать их только игрокам, чтобы не видели зрители). А пульт управления каждой машинки будет всегда доступен по одному и тому же ip-адресу, в рамках конкретной сети, это существенно упростит всё.

Но есть один ещё более интересный вариант, который можно попробовать — использование протокола Multicast Domain Name System (mDNS), представляющего собой протокол, который даёт возможность в небольших сетях обнаруживать устройствам друг друга не по ip-адресу, а по «человекопонятному» названию.

То есть, другими словами, преобразование IP адресов в имена, и, теоретически, при использовании такого решения, наши машинки/некие устройства в локальной сети будут доступны по названиям, подобным таким: mashinka_1.local, mashinka_2.local и т.д.

Причём, что особенно удобно, несмотря на смены ip-адреса, например, при перезагрузках машинки или подключении/отключении клиента, — машинка всегда будет доступна по одному и тому же адресу (например, mashinka_1.local) и вам не нужно будет отслеживать изменения ip-адреса.

Но, насколько мне удалось выяснить, этот протокол не работает на Андроид, версии 11 и ниже, так что надо иметь это в виду.

Почитать подробнее об этом можно здесь.

Перспективы?


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

Тем не менее, всё можно ещё больше улучшить, при этом, достаточно сильно упростив, как ни парадоксально!

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


Естественно, у любого, наверное, возникнет вопрос: «а можно ли проще?».

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

Смотря на всё это, у меня появлялась одна единственная мысль: " нет, ребята, надо проще, ещё проще".

И в ходе обдумывания всего этого у меня родилась одна любопытная мысль… А что если, взять старую настольную игру советского типа, которых существовало некоторое количество, например, футбол.

Первый вариант такого футбола (со смещением игроков):

Второй вариант такого футбола (с пружинными игроками):

Или, например, такого же типа игру, баскетбол:

Как можно видеть, в последних двух видео, управление весьма простое, и может быть легко реализовано, с использованием самого простого соленоида! Не нужно никаких шаговых двигателей, вращений, сопутствующей механики и всех этих сложностей — нужен один, единственный соленоид (на каждого игрока), и всё! Ну, может, только вратарь будет несколько более сложным (и то, не факт).

image
Картинка: amperkot.ru

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

Для упрощения системы управления — пульт управления для всех игроков доступен по одному и тому же адресу, а разбор команд, от какого конкретно клиента она пришла — идёт уже на самой esp32:



Таким образом, мы легко можем реализовать весьма интересную и увлекательную игру, очень простую технически, которую можно использовать как для локальных соревнований между друзьями, так и для тимбилдинга и, даже (что самое интересное!) — для открытия доступа к ней через интернет и проведения своих собственных чемпионатов — стать владельцем своего собственного чемпионата весьма привлекательно, не так ли? ;-) Всё равно, что стать владельцем «Формулы-1». Стартап? Очень даже запросто…

Почему вообще появилась у меня эта мысль: на youtube, некоторое время назад, сильно «взлетел» и стал популярным канал, где проводятся гонки стеклянных шариков.
Владелец канала просто запускает шарики по трекам, разным сложным трассам и собирает большую аудиторию на этом:



Думаю, что общедоступная футбольная лига с реальными физическими устройствами будет собирать не меньше :-)

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

В первой итерации, для локального управления и игры — можно взять тот код для машинок, который я приложил к этой статье и модифицировать его (он будет существенно проще, если управлять соленоидами).

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

И на этом я заканчиваю, так как если буду продолжать, то сам зажгусь и побегу делать:-)

Удачи всем, кто захочет построить свою собственную систему!

Telegram-канал со скидками, розыгрышами призов и новостями IT ?

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


  1. Jury_78
    30.05.2024 13:11

    Здесь не используется esp-now?


    1. DAN_SEA Автор
      30.05.2024 13:11

      Нет, пользвался стандартным.


    1. nikolz
      30.05.2024 13:11

      Нет, тогда смартфоны нельзя использовать.


  1. N-Cube
    30.05.2024 13:11
    +3

    Вот уж намудрили. Ставить step-up на 12 вольт, чтобы затем с помощью ШИМ снижать эффективное напряжение в 100/255 раз (до 4.7 вольт)? При этом у автора еще и контроллер перегревается и драйверы моторов сгореть норовят. Есть же прямой путь - от 5 вольт прекрасно работают и моторы (для управления хватит и транзистора, если реверс не нужен) и esp32. Использовать смартфон для игры тоже неудобно, а во избежание порчи ценного оборудования можно воспользоваться копеечными ИК пультом и приемником (ценой в около половины доллара за комплект на алиэкспресс).


    1. DAN_SEA Автор
      30.05.2024 13:11

      Возможно;-) Но реверс в моём случае был нужен - именно за счёт него и совершался разворот на месте.


    1. AlexanderS
      30.05.2024 13:11

      Разделять каналы питания идея здравая. Иначе при клине двигателя напряжение может кратковременно просеть так, что сбросится контроллер. Лучше будет в защищаемый перегруз уводить какую-то одну линию питания. Правда так получилось, что здесь роль защиты играют драйверы моторов)


  1. nikolz
    30.05.2024 13:11

    А если вместо HG7881CP взять MX1508 или DRV8833.?

    А вместо ESP32 взять ESP8285?

    Машинки будут меньше и легче. Батарейка будет дольше работать.


    1. DAN_SEA Автор
      30.05.2024 13:11

      Попробуйте...по крайней мере, DRV8833 я купил себе пару штук на пробу и гонял их с такими же двигателями - и довольно нещадно, правда, в другом проекте - и выгораний не заметил.


      1. nikolz
        30.05.2024 13:11
        +1

        В DRV8833 и MX1508 на выходе стоят Low MOSFET ON-Resistance, что обеспечивает меньшее падение напряжения и меньший нагрев.


    1. DAN_SEA Автор
      30.05.2024 13:11
      +1

      Можно попробовать вообще esp32 C3 SuperMini;-) Я как раз сейчас на неё активно перехожу - размер у неё существенно меньше стандартной esp32, энергопотребление меньше, на первый взгляд (но надо предметно сравнивать).

      Взял себе сначала пару штучек. Сейчас во вкус вошёл - купил ещё 20 штук:-))

      Она полностью с обвесом, как и большая, паять ничего не надо - подключай периферию и работай...


      1. nikolz
        30.05.2024 13:11
        +1

        esp32 C3  менее избыточен. У него одно ядро.

        Но потребляет он больше и размер у него больше, чем у ESP8285.

        Если делать очень маленькие, дешевые и экономичные wifi управляемые игрушки( авто), то оптимальным будет ESP8285+.( DRV8833 / MX1508 )


  1. NutsUnderline
    30.05.2024 13:11

    virt2real так вот и начиналась, правда не особо долго прожила


    1. DAN_SEA Автор
      30.05.2024 13:11

      Ага, тоже следил за этим проектом, даже лично общался с автором. Нравятся мне роботы, ничего не могу с этим поделать:-)


  1. Misery
    30.05.2024 13:11

    Привет,

    Веб страничка с органами управления обычно весьма глючна и периодически подвешивает есп (правда я последний раз пробовал на 8266). Есть еще решение wifi to uart bridge. Не знаю, есть ли прошивки на есп32 с таким функционалом, но китайцы раньше продавали готовые платы, смысл а том, что всё, что приходит на вайфай, просто ретранслируется в уарт. Ну а там уже в зависимости от передаваемого символа или мк выполняет действие. Конечно же, только по удп, дабы исключить задержки. Простой, рабочий способ,

    Удачи


    1. DAN_SEA Автор
      30.05.2024 13:11

      А здесь это даже не нужно ;-). Прямо сразу принимай байты через wifi и делай что то - в зависимости от того, что пришло. Никаких преобразований - сразу действие...


  1. FGV
    30.05.2024 13:11

    1. Все таки подобные вещи лучше реализовывать через udp, без всяких веб страниц. Приложение для андройда - довольно простое выйдет, за день можно накидать и отладить.

    2. А где схема машинки?


  1. AlexanderS
    30.05.2024 13:11

    двух отдельных микроэлектродвигателей с металлическим редуктором (модель N20)

    ...

    Поэтому пришлось искусственно увеличить питающее напряжение до 12 вольт, используя два параллельно подключённых DC-DC преобразователя.

    ...

    В качестве драйвера двигателей использовался простенький HG7881CP ... Например, опытным путём было найдено значение ШИМ, при котором не происходит непрогнозируемого выгорания, в неожиданный момент: так как использовался восьмибитный ШИМ (т.е. из 256 значений), то в нашем случае, оптимальное значение составляло 100.

    Вы взяли мотор, номинально рассчитанный на 6В с номинальным током 160мА и потреблением при блокировке в 550мА. И драйвер каждый канал которого может выдать до 800мА. Потом вы даёте на мотор 12В (ШИМ=256), как следствие токи будет выше. Конечно драйвер может и не справиться с всплеском тока в начале движения. ШИМ=100 - это запитка моторов номинальным напряжением, при котором у драйверов есть какой-то запас.

    Также, в этой итерации отсутствовало какое-либо выравнивание скоростей двигателей.

    ...

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

    У меня когда не было двигателей с энкодерами я просто калибровал ШИМ на каждый мотор и оно прямо даже очень неплохо ездило)


    1. DAN_SEA Автор
      30.05.2024 13:11

      В конечном итоге, после множества тестов я понял, в чем проблема (прямой езды) и как её решать: даже ШИМ-контроль скорости вращения двигателей не поможет. Причина- несовершенство рамы/самых двигателей. Они устанавливаются тоже не идеально. Соответственно единственный вариант для прямолинейного движения (если не по полу, по нарисованной линии :-) ) - ШИМ дополнить ещё акселерометром/гироскопом.