Мини-проект: радиоуправляемая платформа на Arduino

Пост не имеет отношения к D, но я решил опубликовать его тут, так как тематика относительно близкая.

Arduino я начал изучать год назад. Для непосвященных: это созданный итальянскими инженерами недорогой 8-битный микроконтроллер с распиновкой, очень простой для понимания начинающими, в комплекте с работающим из коробки C-тулчейном, юзер-френдли IDE и инструментарием для прошивки платы по COM-порту. Вообще электрическими схемами я увлекаюсь с самого раннего детства – всегда любил что-то делать своими руками из железного конструктора, проводов и лампочек =) С появлением компьютера это хобби не угасло, хотя до недавних пор и отошло на второй план. Мечту сделать игрушечный радиоуправляемый аппарат я не оставлял много лет – и вот, наконец, сумел воплотить ее в жизнь!

За основу я взял китайский клон Arduino Uno R3 (благо они очень дешевые, можно не жалеть для экспериментов). Я использовал, в основном, прилагавшиеся к плате детали, но пришлось также докупить электромоторы и драйвер L298N. Что удобно, моторы можно купить сразу с колесом – таким образом, остается только укрепить ходовую часть на шасси.

Шасси, за неимением лучшего материала, я сделал из Лего. На этом этапе, как ни странно, я застрял надолго, так как электронные компоненты оказалось очень непросто надежно прикрепить к лего-деталям. Для удобства я докупил лего-совместимый корпус для Arduino, однако толкового способа закрепить моторы я так, к сожалению, и не придумал – в итоге ходовая часть получилась немного расхлябанная, но тем не менее работоспособная.

Отдельной проблемой стало питание. Сначала я думал запитать плату от USB-пауэрбанка, но ничего не вышло: Ардуино работает пару секунд и выключается. Пришлось добавить батарейный отсек на 6 элементов AA (9В). Драйвер моторов запитал параллельно с платой, от разъема VIN (который, в отличие от обычных 5-вольтных разъемов питания, напрямую отдает 9В от адаптера, что очень удобно). Теоретически, для большей надежности можно было бы запитать драйвер полностью независимо от Ардуино, добавив клемму между DC-штекером и платой, но я не стал так заморачиваться.

Драйвер L298N – это ключевой компонент двухмоторной ходовой части. Пара моторов нужна для того, чтобы не делать рулевое управление: для поворота аппарата влево-вправо нужно просто вращать моторы в противположных направлениях. L298N нужен именно для этого. Управление этой штукой осуществляется путем подачи сигналов на командные входы. В качестве remote-контроллера я использовал инфракрасный приемник в паре с комплектным пультом – соответствующая программа получилась очень простой:

#include "IRremote.h"

#define IR_RECEIVE_PIN 7

// IN1, IN2 - motor A
// IN3, IN4 - motor B
#define IN1 2
#define IN2 3
#define IN3 4
#define IN4 5

#define ENA A0
#define ENB A1

int receivedValue;
int buttonPressed = 0;

void setup()
{
    pinMode(IN1, OUTPUT);  //motor A
    pinMode(IN2, OUTPUT);  //motor A
    pinMode(IN3, OUTPUT);  //motor B
    pinMode(IN4, OUTPUT);  //motor B
  
    IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);
  
    buttonPressed = 0;
}

void loop()
{
    receivedValue = 0;
    
    if (IrReceiver.decode())
    {
        receivedValue = IrReceiver.decodedIRData.command;
        IrReceiver.resume();
    }
  
    if (receivedValue == 28) // forward
    {
        digitalWrite(IN1, HIGH);
        digitalWrite(IN2, LOW);
        digitalWrite(IN3, LOW);
        digitalWrite(IN4, HIGH);
    }
    else if (receivedValue == 82) // back
    {
        digitalWrite(IN1, LOW);
        digitalWrite(IN2, HIGH);
        digitalWrite(IN3, HIGH);
        digitalWrite(IN4, LOW);
    }
    else if (receivedValue == 8) // left
    {
        digitalWrite(IN1, HIGH);
        digitalWrite(IN2, LOW);
        digitalWrite(IN3, HIGH);
        digitalWrite(IN4, LOW);
    }
    else if (receivedValue == 90) // right
    {
        digitalWrite(IN1, LOW);
        digitalWrite(IN2, HIGH);
        digitalWrite(IN3, LOW);
        digitalWrite(IN4, HIGH);
    }
    else // stop
    {
        digitalWrite(IN1, LOW);
        digitalWrite(IN2, LOW);
        digitalWrite(IN3, LOW);
        digitalWrite(IN4, LOW);
    }
    
    delay(100);
}

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

Итоги 2023 года

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

  • Можно считать, что я достиг своей цели – стать профессиональным разработчиком игр. На сегодняшний день солидную долю моих доходов составляют фрилансерские проекты по разработке рекламных мини-игр и интерактивных баннеров. И, хотя все они пишутся на JavaScript, я стал чаще по работе использовать D для создания различных утилит, что не может не радовать.
  • Выпустил Dagon 0.15, в котором появилась поддержка Hald CLUT, 1D и 3D-текстуры, новые параметры постобработки для ручного управления эффектом Depth of Field, новые методы для текстур, обновлен биндинг Newton.
  • В репозиторий с примерами Dagon добавлены примеры создания ландшафта и работы с пользовательскими шейдерами.
  • Выпустил dlib 1.2.0 и 1.2.1. Добавлены функции гомотетии (масштабирования относительно точки), функции конвертации радианов в обороты и обратно, медианный фильтр, а также функция отрисовки прямоугольника. Спасибо Олегу Бахареву aka aquaratixc, Aaron Nédélec aka ReactiveAlkali, Razvan Nitu aka RazvanN7, Nick Treleaven aka ntrel за багфиксы и новые фичи.
  • Я наконец-то дописал вводную статью о PBR для начинающих, она доступна на сайте журнала “FPS”. Кстати в уходящем году журналу исполнилось уже 15 лет.
  • Начал изучать микроконтроллеры – Arduino и ESP32. Полным ходом иду к своей детской мечте – сделать своими руками радиоуправляемую машинку (как-нибудь напишу пост об этом проекте).

Ну и, конечно, не могу не назвать самые значимые для меня события в мире IT:

  • Выход Blender 4.0
  • Выход Godot 4
  • Смена ценовой политики Unity
  • Появление ChatGPT (хотя я не думаю, что нейросети в обозримом будущем кого-то заменят).