Перейти к содержанию

Статья

Как превратить игрушечного робота-доставщика в ровер с беспроводным управлением через мобильное приложение

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

29 апреля 2024 г.9 мин чтенияИмпорт с Habrробот-доставщикинтернет вещей
Оригинальная ссылкаОткрыть оригинал статьи
Я хочу купить такой ровер, что делать?

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

Если вам хочется приобрести такой же управляемый ровер, напишите мне в телеграмме (https://t.me/MaxiEnergy), и он отправится к вам)

Привет, Хабр!

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

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

Игрушка на Яндекс Маркете

Игрушка на Яндекс Маркете

Робот-доставщик

Модель выполнена в виде настоящего ровера 3 от Яндекса в масштабе 1/64. Инерционный механизм делает из него небольшую игрушку, работающую по принципу детских машинок, которые были, вероятнее всего, у каждого в прекрасные времена более голубого неба и самой зеленой травы.

Работа инерционного механизма

Работа инерционного механизма

Также внутри робота расположены светодиоды для подсветки его «глаз» и периметра контейнера, который, к слову, открывается. Работает все великолепие на 3 батарейках типа LR44.

Подсветка ровера

Подсветка ровера

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

А может сделать его управляемым?

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

На самом деле, все просто. Примерно так же, как из инерционной машинки сделать радиоуправляемую. Только зачем радиоуправление, если можно написать мобильное приложение и управлять ей с телефона?

В итоге решил делать следующее:

  1. Управление ровером должно быть реализовано с помощью мобильного приложения на iOS, которое я напишу на Flutter (про мой первый опыт работы с этим фреймворком можно прочитать в статье про Smart Connect)

  2. Беспроводная передача данных будет производиться с помощью BLE, потому что ранее я имел с ним дело (можете ознакомиться со статьями про SmartLight и SmartPulse) и я считаю его идеальным под подобные проекты (имхо)

  3. Ровер должен ездить вперед, назад, поворачивать влево и вправо, а также включать подсветку по кнопке в мобильном приложении

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

Внутри игрушки

Внутри игрушки

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

Что по начинке?

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

Схема направления движения колес при повороте ровера

Схема направления движения колес при повороте ровера

Для управления моторчиками нужен драйвер. Естественно, так как мы имеем дело с небольшим корпусом игрушки, то все платы надо было подобрать так же миниатюрные. Сказано - сделано, и драйвер L298N mini уже был у меня. На него сразу можно было припаять два моторчика, чему я был несказанно рад.

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

А что будет всем этим управлять? Для работы с BLE существует крайне удачная линейка ESP32 контроллеров с различными модификациями. Так как в этом проекте мы ограничиваемся сравнительно небольшим пространством для монтажа плат внутрь устройства, я выбрал ESP32-C3 SuperMini, которая по своим размерам не больше зарядной платы аккумулятора.

Разобранный ровер и все то, что в него предстоит засунуть

Разобранный ровер и все то, что в него предстоит засунуть

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

Схема подключения электронных компонентов

Схема подключения электронных компонентов

Прошивка робота

Перейдем к прошивке ровера, полная версия которой лежит у меня в репозитории на GitHub (всегда рад гостям).

По сути все, что нам нужно для реализации передачи данных на ровер, это поднять BLE-сервер и определить сервис и характеристику, в которую мы будем отправлять значения для включения и выключения моторчиков. Я писал код в Arduino IDE с использованием библиотек BLEDevice.h, BLEUtils.h и BLEServer.h

Инициализируем работу с BLE посредством следующего кода:

BLEDevice::init("Yandex Delivery Robot");
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
BLEService* pMoveService = pServer->createService(BLEUUID((uint16_t)0x170D));
pMoveCharacteristic = pMoveService->createCharacteristic(BLEUUID((uint16_t)0x2A60), BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE);
pMoveCharacteristic->setCallbacks(new MoveCharacteristicCallbacks());
pMoveService->start();
BLEAdvertising* pAdvertising = pServer->getAdvertising();
pAdvertising->addServiceUUID(pMoveService->getUUID());
pAdvertising->setScanResponse(false);
pAdvertising->setMinPreferred(0x06);
pAdvertising->setMinPreferred(0x12);
BLEDevice::startAdvertising();

Здесь мы определяем наименование устройства, а также присваиваем UUID нашему сервису и характеристике pMoveCharacteristic

Запись в характеристики производится с помощью MoveCharacteristicCallbacks, в которой я реализовал switch-case конструкцию. Внизу прикреплен урезанный фрагмент.

class MoveCharacteristicCallbacks : public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic* pCharacteristic) {
        std::string value = pCharacteristic->getValue();
        if (value.length() > 0) {
            switch (value[0]) {
                case 0x01: // Поворот ровера влево
                    ledcWrite(CHANNEL_IN1, 255); 
                    ledcWrite(CHANNEL_IN2, 0);
                    ledcWrite(CHANNEL_IN3, 255);
                    ledcWrite(CHANNEL_IN4, 0);
                    break;
                case 0x02: // Поворот ровера вправо
                    ledcWrite(CHANNEL_IN1, 0);
                    ledcWrite(CHANNEL_IN2, 255); 
                    ledcWrite(CHANNEL_IN3, 0);
                    ledcWrite(CHANNEL_IN4, 255);
                    break;
            }
        }
    }
}

Мобильное приложение

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

Логика работы кода мобильного приложения также как и в случае с кодом прошивки построена на switch-case конструкции. Я решил расположить на странице управления ровером кнопки в виде стрелок направления (вперед, назад, влево, вправо) и кнопку включения/выключения подсветки в виде горящей лампочки. Когда пользователь нажимает на любую из кнопок направления, в BLE-характеристику подключенного устройства записывается соответствующее значение (к примеру, для поворота ровера влево - 0x01, для правого поворота - 0x02 и тд.).

Positioned(
  bottom: 160,
  left: 80,
  child: controlButton(Icons.arrow_back, 0x01, "Left"),
),
Positioned(
  bottom: 160,
  right: 80,
  child: controlButton(Icons.arrow_forward, 0x02, "Right"),
)

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

onPointerDown: (_) => sendCommand(command),
onPointerUp: (_) => sendCommand(0)

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

Positioned(
  bottom: 40,
  right: 20,
  child: FloatingActionButton(
    onPressed: () {
      setState(() {
        toggleState = !toggleState;
        sendCommand(toggleState ? 3 : 6);
      });
    },
    child: Icon(
      toggleState ? Icons.lightbulb_outline : Icons.lightbulb,
      color: Color.fromRGBO(255, 53, 63, 1),
    ),
    backgroundColor: Colors.white,
  ),
)

Чтобы работать с BLE, я подключил flutter_blue: ^0.8.0 , а сам процесс подключения к устройству построен на определении рассылки от конкретного BLE-сервера по его названию. Запись значений производится по UUID сервиса и характеристики ровера.

List<BluetoothService> services = await widget.device.discoverServices();
var targetService = services.firstWhere((service) =>
    service.uuid == Guid('0000170D-0000-1000-8000-00805f9b34fb'));
var targetCharacteristic = targetService.characteristics.firstWhere(
    (characteristic) =>
        characteristic.uuid ==
        Guid('00002A60-0000-1000-8000-00805f9b34fb'));
await targetCharacteristic.write(value);

После того, как я протестировал работоспособность приложения с микроконтроллером, мне захотелось как-то "довести до ума", чтобы как минимум приложение выглядело чуть более симпатично. На странице управления ровером были только четыре кнопки управления моторами и одна кнопка для подсветки. Это выглядело скучновато, поэтому мне захотелось добавить динамики. Решил изобразить в Adobe Illustrator модельки с направлением ровера.

Изображения направления ровера

Изображения направления ровера

Реализовал обновление картинок по нажатию на соответствующие кнопки управления ровером также через switch по отправляемому с кнопки значению.

setState(() {
  switch (command) {
    case 0x01:
      currentImage = 'assets/Влево.png';
      break;
    case 0x02:
      currentImage = 'assets/Вправо.png';
      break;
    case 0x05:
      currentImage = 'assets/Вперед.png';
      break;
    case 0x04:
      currentImage = 'assets/Назад.png';
      break;
    default:
      break;
  }
});

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

Иконка мобильного приложения

Иконка мобильного приложения

Собираем приложение в Xcode, устанавливаем его на мобильное устройство (в моем случае это iPhone 12 Pro Max) и запускаем для тестирования работоспособности. В итоге мобильное приложение получило следующий внешний вид:

Работа и внешний вид мобильного приложения

Работа и внешний вид мобильного приложения

Пайка, флюс, два колеса

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

Колеса ровера до подключения моторов и после

Колеса ровера до подключения моторов и после

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

Разобранный ровер со срезанными креплениями

Разобранный ровер со срезанными креплениями

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

Модифицированное днище ровера

Модифицированное днище ровера

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

Пайка электронных компонентов ровера

Пайка электронных компонентов ровера

В итоге не без проблем, но у меня получилось разместить все компоненты внутри ровера. Зарядка устройства производится со стороны нижней части корпуса. Это напоминает мне подключение Magic Mouse, но только я это сделал за неимением других вариантов, а не потому что не люблю людей. Можно было бы расположить зарядную плату как-то иначе, но я не хотел портить внешний вид ровера (днище не считается, потому что его не видно).

Процесс зарядки ровера от сети

Процесс зарядки ровера от сети

Поехали!

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

В качестве демонстрации управления ровером я записал небольшое видео:


Большое спасибо всем, кто прочитал эту статью!

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

UPD: Прошло уже полгода с момента публикации этой статьи. Мне стали активно писать абсолютно разные люди с просьбой модифицировать для них игрушечный ровер на заказ. Я с удовольствием выполнил уже серию заказов и продолжаю это делать до сих пор. Если вам хочется приобрести такого же управляемого робота-доставщика, напишите мне в телеграмме (https://t.me/MaxiEnergy), и он отправится к вам)

Граф связей

Как эта работа связана с другими

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

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

ПостСтатьяПроект
100%
Как превратить игрушечного робота-доставщика в ровер с беспроводным управлением через мобильное приложение. Открыть работу⚠️ Очень важное объявление по поводу роверов ⚠️ 💬 Сегодня я разослал всем свои…. Открыть работу👀 Фото не для слабонервных 🐦‍⬛️ Маленький ровер со всеми внутренностями наруж…. Открыть работу👋 Вот и наступил вечер среды Тараканы в моей голове говорят, что это лучшее вр…. Открыть работу👋 Когда я впервые модернизировал игрушечный ровер, то написал приложение тольк…. Открыть работу👋 После того, как я опубликовал свою статью на Хабре, где модифицировал игруше…. Открыть работу🤒 Боли пост, хотя… Несмотря на то, что изначально приложение для ровера я писа…. Открыть работу🥳 Свершилось, товарищи! 🥳 Я дописал и опубликовал веб-приложение My Rover, с…. Открыть работу🥳 Урааааа 🥳 Приложение под Android для управления роверами прошло модерацию и…. Открыть работу🫢 Из чего же, из чего же, из чего же сделаны наши... роверы Подробно весь проц…. Открыть работуА вот и долгожданный анбоксинг/обзор/реакция на новый радиоуправляемый игрушечн…. Открыть работуА вот и обещанное мной продолжение. В прошлом посте я рассказал, как написал ст…. Открыть работуА вот и ответ на вопрос 😉 Я купил портативный лазерный гравер, чтобы выжигать…. Открыть работуА вот так теперь выглядит само приложение 🤩 🔝 Вместо изображения ровера на эк…. Открыть работуА помните, ребята из Яндекса подарили мне радиоуправляемую модель ровера на Нов…. Открыть работуВсем привет ❤️ Так как вот на этот пост вы активно ставили реакции в виде ⚡️, к…. Открыть работуВсем привет 👋 Вот тут я рассказывал, в каких городах сейчас находятся модифици…. Открыть работуВсем привет 👋 Мне наконец-то пришли моторчики с планетарными редукторами. На д…. Открыть работуВсем привет 🤘 Вчера ещё один модифицированный ровер доехал до своего получател…. Открыть работуМилоты пост 😍 Иногда ты просто модифицируешь игрушечные роверы, пишешь научные…. Открыть работуМне написали из Яндекса В декабре уже прошлого года Яндекс выпустил радиоуправл…. Открыть работуМой комментарий под игрушечным роботом-доставщиком на Яндекс.Маркете, в котором…. Открыть работуНаконец-то я допилил и протестировал порт приложения для операционной системы A…. Открыть работуПомните, недавно я писал, что со мной связались ребята из Яндекса и решили пода…. Открыть работуПосмотрите, какая красота 😍 Уже совсем скоро с помощью них начнут ездить ваши…. Открыть работуПоставил моторы с редукторами на свой ровер 🚗 Несмотря на то, что ровер стал о…. Открыть работуПривет, айотовчане 👋 Сегодня случилось кое-что очень приятное, и я просто не м…. Открыть работуС гордостью заявляю, что теперь один модифицированный игрушечный ровер есть в с…. Открыть работуDeliveryRobotApp. Открыть работуDeliveryRobotFirmware. Открыть работуMyRoverWeb. Открыть работу

Обсуждение

Комментарии

Комментарии доступны только подтверждённым email-подписчикам

Подключиться к обсуждению

Введите ту же почту, которую вы уже использовали для подписки на сайт

Пока нет ни одного комментария