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

В статье расскажу, как собрать гусеничную платформу, управляемую ИК-пультом. Платформа будет принимать команды с пульта через ИК-датчик, которые будут обрабатываться платой Iskra mini (российским аналогом Arduino mini).
Также речь пойдет о том, как определить коды кнопок любого ИК-пульта, даже если это старый пульт от видеомагнитофона вашей бабушки. Я напишу код для Iskra mini, который будет принимать команды и управлять платформой. В конце вас ждет видеодемонстрация её возможностей.
На создание этого проекта меня вдохновил интерес к DIY и электронике. Также я хочу поделиться своими знаниями в робототехнике с людьми, которые только начинают осваивать Arduino. Нет ничего лучше, чем начать с простого проекта, который в дальнейшем можно усложнить.
Думаю, статья будет интересна начинающим робототехникам и любителям проектов DIY с микроконтроллерами Arduino. Я буду подробно описывать процесс, чтобы любой желающий мог повторить этот проект на аналогичных или похожих компонентах.
Предисловие
Несколько лет назад у меня был набор радиоуправляемых танков от World of Tanks, который мне подарила жена на день рождения. Танчики стреляли друг в друга ИК-пушками, имели шкалу жизней и издавали звуки стрельбы и попадания.
Они верой и правдой служили мне пару лет, но затем в них сломалась электроника. Я разобрал один из них, вынул радиоуправление и решил оставить корпус и верхнюю часть с башней как возможные доноры для DIY-проекта.
В танке имеются два мотора в гусеничном шасси, мотор для вращения башни и два ИК-датчика. Один из датчиков находится в пушке, а второй — в башне, и он функционирует как мишень. Гусеничное шасси от танка Tiger 1 из этого набора я и решил использовать для этого проекта.

Компоненты
Для реализации проекта понадобятся:
Iskra mini или любая подходящая по размерам плата Arduino;
Гусеничное шасси;
Любой ИК-пульт;
ИК-приёмник TSOP1738;
Драйвер двигателей ЛМ2 130 на базе L293D или его аналог;
Держатель для экшн-камеры (не обязательно);
Небольшая макетная плата mini breadboard;
Небольшой power bank 5V или бокс с двумя аккумуляторами 18650;
Провода дюпонты папа-мама и папа-папа;
Пластины из пластика (можно вырезать из крышки пластикового контейнера);
Ссылки на компоненты приведены для удобства. Компоненты вы можете подобрать сами и приобрести в любом удобном для вас магазине или использовать те, что у вас уже есть.
Способ работы с другими моделями Arduino и драйверами двигателей может отличаться от моего примера. Коды кнопок для вашего пульта вам придётся получить самостоятельно, основываясь на методе, показанном в статье (на разных пультах коды разные).
Сборка
Для начала нужно удалить старый переключатель, который включал питание танка. Его роль будет выполнять кнопка включения питания на плате управления моторами ЛМ2 130.
Для извлечения переключателя я открутил винт крышки, отрезал провод с разъёмом для аккумулятора и выкрутил сам переключатель:

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

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

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

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

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

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

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

Пины питания:
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 нужен для приёма команд с ИК-пульта.

Пины:
1 — GND: Земля;
2 — VS: Рабочее напряжение 5 вольт;
3 — OUT: Контакт для пина управления приёмником;
Дистанция: 45 метров;
Рабочая частота: 38 кГц.
Подключение электроники
Для подключения к power bank потребуется USB-разъём. Провода для плюса и минуса необходимо зачистить и обработать припоем. Обычно «плюс» — красного цвета, а «минус» — чёрного, но на всякий случай лучше проверить вольтметром, подключив USB к power bank.

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

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

Подключение ИК-приёмника 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.
После того, как я подключил всю электронику, платформа стала выглядеть так:

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

Я воспользуюсь кодом для четвёртой версии библиотеки, который возьму из примеров её репозитория 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:

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

Для проверки работоспособности обоих пультов и получения с них кодов кнопок нужно перейти во вкладку Tools → Serial Monitor. Плата Arduino должна быть подключена к компьютеру. В окне Serial Monitor нужно обязательно выбрать скорость 115 200 бод.
Далее нужно направить пульт на ИК-приёмник и нажимать на кнопки пульта, чтобы получить их коды. Эти коды потребуются для использования в программировании в качестве команд для управления гусеничной платформой.

На скриншоте видно, что приняты коды кнопок в шестнадцатеричном виде: 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;


Для загрузки скетча нужно нажать кнопку сброса на плате 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.