DIY-проект: гусеничная платформа с ИК-управлением на Arduino

81041877528396ea87621d8645ea17bc.png

В статье расскажу, как собрать гусеничную платформу, управляемую ИК-пультом. Платформа будет принимать команды с пульта через ИК-датчик, которые будут обрабатываться платой Iskra mini (российским аналогом Arduino mini).

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

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

Предисловие

Несколько лет назад у меня был набор радиоуправляемых танков от World of Tanks, который мне подарила жена на день рождения. Танчики стреляли друг в друга ИК-пушками, имели шкалу жизней и издавали звуки стрельбы и попадания.

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

В танке имеются два мотора в гусеничном шасси, мотор для вращения башни и два ИК-датчика. Один из датчиков находится в пушке, а второй — в башне, и он функционирует как мишень. Гусеничное шасси от танка Tiger 1 из этого набора я и решил использовать для этого проекта.

tank chassis 1.jpg
Шасси платформы

Компоненты

Для реализации проекта понадобятся:

  • Iskra mini или любая подходящая по размерам плата Arduino;

  • Гусеничное шасси;

  • Любой ИК-пульт;

  • ИК-приёмник TSOP1738;

  • Драйвер двигателей ЛМ2 130 на базе L293D или его аналог;

  • Держатель для экшн-камеры (не обязательно);

  • Небольшая макетная плата mini breadboard;

  • Небольшой power bank 5V или бокс с двумя аккумуляторами 18650;

  • Провода дюпонты папа-мама и папа-папа;

  • Пластины из пластика (можно вырезать из крышки пластикового контейнера);

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

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

Сборка

Для начала нужно удалить старый переключатель, который включал питание танка. Его роль будет выполнять кнопка включения питания на плате управления моторами ЛМ2 130.

Для извлечения переключателя я открутил винт крышки, отрезал провод с разъёмом для аккумулятора и выкрутил сам переключатель:

tank chassis bottom.jpg
Днище платформы

После этого я закрыл крышку и закрутил винт обратно. Роль питания выполняет небольшой power bank ёмкостью 4000 мА·ч, так как встроенный аккумулятор оказался слабоват для таких задач (всего 3,7 вольт 700 мА·ч). Драйверу двигателей ЛМ2 130 требуется 4,5–9 вольт напряжения питания, поэтому 3,7 вольт мало для него. Power bank можно заряжать, не снимая с гусеничной платформы, что очень удобно.

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

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

tank chassis and plates.jpg
Примерка пластин к шасси

Далее я прикрутил держатель для экшн-камеры и плату управления двигателями к верхней части платформы:

Установленный держатель экшн камеры и ЛМ2 130 на верхней части платформы
Установленный держатель экшн камеры и ЛМ2 130 на верхней части платформы

После этого присоединил верхнюю часть к платформе:

chassies without powerbank and breadboard.jpg
Прикрученная верхняя часть платформы к шасси

Также мне потребовалось установить на платформу power bank для питания и breadboard. Breadboard (макетная плата) был нужен, чтобы закрепить на платформе Iskra mini и прочую электронику. Чтобы зафиксировать компоненты, я использовал двусторонний скотч.

Приклеиваю скотч к компонентам:

powerbank and bradboard 2.jpg
Наклеенный двусторонний скотч на breadboard и power bank

Клею компоненты на верхнюю часть платформы:

chassies without usb and arduino.jpg
Установленные power bank и breadboard на верхнюю часть платформы

На этом сборка верхней части платформы окончена. Осталось правильно подключить электронику.

Электроника

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

Драйвер электромотора ЛМ2 130

Драйвер ЛМ2 130 нужен для управления электромоторами и подачи питания на Arduino. Плата ЛМ2 130 создана на базе микросхемы L293D и инвертора 74HC00, который упрощает управление электродвигателями.

Пины и схема l293d.jpg
Схема ЛМ2 130

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

Более подробная информация по драйверу мотора ЛМ2 130 доступна в её документации.

Iskra mini

Iskra mini (аналог Arduino mini) — это маленькая плата на базе микроконтроллера Atmega328 для разработки миниатюрных устройств.

iskra-mini_layout.png
Схема Iskra mini

Пины питания:

  • VIN:  Пин для подключения внешнего источника питания;

  • 5V:  На вывод поступает напряжение 5 В от стабилизатора платы;

  • GND:  Земля.

Порты ввода/вывода:

  • Цифровые входы/выходы:  пины 0–13;

  • ШИМ:  пины 3,5,6,9,10 и 11;

  • АЦП:  пины A0–A5;

  • SPI:  пины 10(SS),  11(MOSI),  12(MISO),  13(SCK);

  • UART:  пины 0(RX) и 1(TX).

Характеристики:

  • Микроконтроллер: ATmega328;

  • Тактовая частота: 16 МГц;

  • Flash-память: 32 КБ (из которых 2 КБ используются загрузчиком);

  • SRAM: 2 КБ;

  • EEPROM: 1 КБ;

  • Рабочее напряжение: 5 В;

  • Рекомендуемое входное напряжение: 5,3–9 В;

  • Портов ввода-вывода общего назначения: 20;

  • Портов с поддержкой ШИМ: 6;

  • Портов, подключённых к АЦП: 8;

  • Максимальный ток одного вывода: 40 мА;

  • Габариты: 33×20 мм.

Более подробную информацию о Iskra mini можно найти на странице её wiki.

IR приёмник

IR приёмник TSOP-1738 нужен для приёма команд с ИК-пульта.

TSOP_17381_Layout.jpeg
Схема TSOP-1738

Пины:

  • 1 — GND: Земля;

  • 2 — VS: Рабочее напряжение 5 вольт;

  • 3 — OUT: Контакт для пина управления приёмником;

  • Дистанция: 45 метров;

  • Рабочая частота: 38 кГц.

Подключение электроники

Для подключения к power bank потребуется USB-разъём. Провода для плюса и минуса необходимо зачистить и обработать припоем. Обычно «плюс» — красного цвета, а «минус» — чёрного, но на всякий случай лучше проверить вольтметром, подключив USB к power bank.

usb for the power bank.jpg
USB с проводом

Я установил платы Arduino и IR приёмника в breadboard, а также подключил питание двигателей в разъёмы Motor2-left и Motor2-right на плате управления двигателями. Провод минуса нужно вставить в BAT с »-», а провод плюса в BAT с »+», после этого закрутить винты маленькой плоской отвёрткой.

chassis without duponts 2.jpg
Вид платформы после установки компонентов

Если теперь нажать на кнопку питания ЛМ2 130, то моторы начнут вращаться и гусеничная платформа поедет по прямой. Главное, чтобы моторы вращались в одну сторону. Полностью отладить правильное направление вращения моторов можно будет во время тестирования управления с пульта. Если что-то будет неправильно, можно поменять полярности на разъёмах Motor2-left и Motor2-right.

Для подключения Arduino, ЛМ2 130 и ИК-приёмника между собой потребуются 6 проводов дюпонтов папа-мама и 3 папа-папа (на фото их 4 шт.).

duponts.jpg
Провода дюпонты папа-мама и папа-папа

Подключение ИК-приёмника TSOP-1738 к Arduino:

  • 1 — GND TSOP-1738 → GND Arduino;

  • 2 — VS TSOP-1738 → 5 вольт Arduino;

  • 3 — OUT → 2й пин Arduino.

Подключение Arduino к ЛМ2 130:

  • 5 вольт Arduino → VIN + ЛМ2 130;

  • GND Arduino → VIN — ЛМ2 130;

  • Шим 5 Arduino → PWM-left ЛМ2 130;

  • 4 Arduino → In left ЛМ2 130;

  • Шим 6 Arduino → PWM-right ЛМ2 130;

  • 7 Arduino → In right ЛМ2 130.

После того, как я подключил всю электронику, платформа стала выглядеть так:

chassis assembly 1.jpg
Подключенная электроника

На фото видно, что я поменял полярности на правом моторе. Я понял, что нужно это сделать после проверки работоспособности модели. Во время подключения лучше ориентироваться не на фото, иначе есть риск ошибиться!

Платформа полностью собрана, а электроника подключена. Теперь можно переходить к написанию кода.

Программирование Arduino

Код для Arduino пишется на упрощённых версиях языков C/C++. Затем код компилируется и загружается на плату Arduino. Я буду писать код в Arduino IDE.

Получение кодов для кнопок

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

Тестировать коды кнопок на плате Iskra mini не очень удобно, так как у неё нет USB для удобного подключения к ПК. Поэтому я воспользуюсь платой Arduino Uno, которая имеет USB-разъём. Всё, что нужно, это вынуть ИК-приёмник из breadboard гусеничной платформы или взять ещё один такой же и подключить его к плате Arduino Uno. Подключение производится к тем же пинам, что и в Arduino mini.

IR with arduino uno.jpg
ИК-датчик подключенный к Arduino Uno

Я воспользуюсь кодом для четвёртой версии библиотеки, который возьму из примеров её репозитория Example IRremote.

#include  // Подключение библиотеки Arduino-IRremote для работы с IR

#define IR_RECEIVE_PIN 2 // Пин 2й на Arduino Mini/Iskra Mini

void setup() {
  Serial.begin(115200); // Инициализация Serial-порта со скоростью 115200 бод
  IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); // Запуск IR-приёмника и включение встроенного светодиода во время получения данных с пульта
}

void loop() {
    if (IrReceiver.decode()) {
        Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX); // Вывод декодированных ИК-данных в Serial в шестнадцатеричном формате
        IrReceiver.resume(); // Сброс IR-приемника для приема следующего сигнала
    }
}

Для работы с ИК-пультами я воспользуюсь библиотекой IRremote. Чтобы начать работать с библиотекой, потребуется её установить и подключить глобально, написав строку кода для подключения библиотеки #include , либо скачать с её репозитория и подключить локально, используя строку кода #include "IRremote.hpp".

Для загрузки кода или скетча необходимо выбрать модель Arduino и её порт и нажать на кнопку »Upload», которая в Arduino IDE похожа на стрелочку.

Если загрузка кода прошла успешно, то вы увидите вывод, похожий на тот, что на моём скриншоте, с надписью Done compiling:

code upload.png
Процесс загрузки кода в Arduino Uno

У меня есть два ИК-пульта: один от старого видеомагнитофона AKAI и второй — маленький и современный пульт, который часто используют в Arduino проектах. Для проекта я выбрал маленький и удобный пульт.

ir pults.jpg
ИК-пульты

Для проверки работоспособности обоих пультов и получения с них кодов кнопок нужно перейти во вкладку Tools Serial Monitor. Плата Arduino должна быть подключена к компьютеру. В окне Serial Monitor нужно обязательно выбрать скорость 115 200 бод.

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

serial monitor.png
Получение кодов кнопок в Serial Monitor

На скриншоте видно, что приняты коды кнопок в шестнадцатеричном виде: F9067789 и E718FF00. Hex-код кнопки — это декодированный в шестнадцатеричном формате ИК-сигнал с пульта. Оба пульта отлично работают, и каждый из них отправил по одному hex-коду кнопки. Далее необходимо получить код для каждой кнопки пульта и записать их в отдельный документ для удобства последующего использования.

У меня получились следующие коды для кнопок:

1 - BA45FF00
2 - B946FF00
3 - B847FF00
4 - BB44FF00
5 - BF40FF00
6 - BC43FF00
7 - F807FF00
8 - EA15FF00
9 - F609FF00
0 - E619FF00
* - E916FF00
# - F20DFF00

ок - E31CFF00
left - F708FF00
right - A55AFF00
down - AD52FF00
up - E718FF00

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

Код для управления роботом

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

Когда кнопка пульта не нажата, следует посылать команду «стоп», иначе платформа не остановится.

#include  // Новая версия библиотеки

// Порт для IR-приемника
int RECV_PIN = 2;

// Хранит время последнего нажатия кнопки
unsigned long _time;

// Motor Shield использует пины 4, 5, 6, 7 для управления моторами
// 4 и 7 — направление, 5 и 6 — скорость
#define SPEED_1 5
#define DIR_1 4

#define SPEED_2 6
#define DIR_2 7

void setup() {
  // Настраиваем выводы 4, 5, 6, 7 на выход
  for (int i = 4; i < 8; i++) {
    pinMode(i, OUTPUT);
  }

  // Запуск IR-приемника с указанием пина и включением LED-обратной связи   (опционально)
  IrReceiver.begin(RECV_PIN, ENABLE_LED_FEEDBACK);

  // Инициализация времени в миллисекундах
  _time = millis();

  // Остановка двигателей при старте
  _stop();
}

  

void loop() {
  if (IrReceiver.decode()) { // Проверка приема сигнала
    _time = millis(); // Обновляем время последнего сигнала

    // Сравниваем полученный код с ожидаемыми значениями
    switch (IrReceiver.decodedIRData.decodedRawData) {
      // Вперед
      case 0xE718FF00:
        forward();
        break;
      // Назад
      case 0xAD52FF00:
        backward();
        break;
      // Влево
      case 0xF708FF00:
        left();
        break;
      // Вправо
      case 0xA55AFF00:
        right();
        break;
      // Стоп
      case 0xE31CFF00:
        _stop();
        break;
    }
    IrReceiver.resume(); // Готовим приемник к следующему сигналу
  }

  // Если с последнего сигнала прошло более 300 мс, останавливаем моторы
  if ((millis() - _time) > 300) {
    _stop();
  }
}

// Движение вперед
void forward() {
  digitalWrite(DIR_1, HIGH); // Мотор 1 вперед
  analogWrite(SPEED_1, 255); // Максимальная скорость

  digitalWrite(DIR_2, HIGH); // Мотор 2 вперед
  analogWrite(SPEED_2, 255); // Максимальная скорость
}

// Поворот налево
void left() {
  digitalWrite(DIR_1, HIGH); // Мотор 1 вперед
  analogWrite(SPEED_1, 255); // Максимальная скорость

  digitalWrite(DIR_2, LOW); // Мотор 2 назад
  analogWrite(SPEED_2, 255); // Максимальная скорость
}

// Поворот направо
void right() {
  digitalWrite(DIR_1, LOW); // Мотор 1 назад
  analogWrite(SPEED_1, 255); // Максимальная скорость

  digitalWrite(DIR_2, HIGH); // Мотор 2 вперед
  analogWrite(SPEED_2, 255); // Максимальная скорость
}

// Движение назад
void backward() {
  digitalWrite(DIR_1, LOW); // Мотор 1 назад
  analogWrite(SPEED_1, 255); // Максимальная скорость

  digitalWrite(DIR_2, LOW); // Мотор 2 назад
  analogWrite(SPEED_2, 255); // Максимальная скорость
}

// Остановка
void _stop() {
  digitalWrite(DIR_1, LOW);
  analogWrite(SPEED_1, 0); // Мотор остановлен

  digitalWrite(DIR_2, LOW);
  analogWrite(SPEED_2, 0); // Мотор остановлен
}

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

Как залить код на Iskra mini/Arduino mini

Платы Iskra mini и Arduino mini не имеют USB-разъёма, поэтому залить код на них можно либо при помощи специальной платы UART, либо при помощи другого Arduino. Я буду показывать на примере UART PL2303.

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

UART PL2303 — это устройство, которое представляет собой преобразователь интерфейса USB в UART (Universal Asynchronous Receiver-Transmitter). Оно используется для связи между компьютером (через порт USB) и устройствами, работающими с последовательным интерфейсом UART, такими как микроконтроллеры, модули GSM, GPS, Bluetooth и другие.

Пины UART PL2303 для работы:

  • TX (Transmit): Пин передачи данных;

  • RX (Receive): Пин приема данных;

  • GND: Земля;

  • VCCIO: +5 или 3.3 (есть перемычка для переключения).

Подключение:

  • TX PL2303 → RX Arduino;

  • RX PL2303 → TX Arduino;

  • GND PL2303 → GND Arduino;

  • +5 PL2303 → +5 Arduino;

Uart with arduino mini.jpg
Подключение Iskra mini к UART
Uart with arduino mini 2.jpg
Пины Iskra mini, подключенные к UART

Для загрузки скетча нужно нажать кнопку сброса на плате Iskra mini, а затем на кнопку »Upload» (кнопка загрузки скетча/кода) в Arduino IDE.

Как работает загрузка скетча:

  • Когда вы загружаете скетч через Arduino IDE, программа сначала компилирует код, а затем передаёт его загрузчику (bootloader), который прошит в микроконтроллер (например, ATmega328P);

  • Загрузчик активируется только в течение короткого времени после сброса микроконтроллера. Если он не получает данные в этот момент, микроконтроллер переходит к выполнению уже загруженного скетча;

  • Не все адаптеры, подобные PL2303, правильно настроены для автоматического сброса. Из-за этого микроконтроллер не сбрасывается автоматически, и загрузчик не активируется в нужный момент. Нажатие на кнопку сброса на плате Iskra mini устраняет эту проблему.

Подключение Iskra mini к Arduino Uno в качестве программатора (для заливки скетча) можно найти на странице её wiki.

Робот в действии

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

Робот довольно шустро забрался по наклонной поверхности, развернулся и проехал по препятствию в виде разбросанного LEGO.

Заключение и планы на будущее

  • Получился довольно интересный и простой DIY-проект;

  • Есть нюансы заливки скетча для плат Iskra mini и Arduino mini;

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

Планы на будущие статьи:

  • Расширить функционал гусеничной платформы;

  • Оживить с помощью Arduino танк ИС (второй танк из набора), который будет стрелять ИК-пушкой.

Автор @Arduinum

НЛО прилетело и оставило здесь промокод для читателей нашего блога:
— 15% на заказ любого VDS (кроме тарифа Прогрев) — HABRFIRSTVDS.

© Habrahabr.ru