Автобот — ардуїновий Хижак. Частина 1: Ми поїхали
Хто читав мою попередню статтю про IoT PowerHub — той знає, що я люблю робити велосипеди. Красиві чи не дуже, кульгаві і навіть складні, з місяцями розробки. Але цього разу велосипед буде на чотирьох колесах і з пультом керування.

Ця історія почалася ще до IoT PowerHub. Років дванадцять тому я дивився відео з боїв роботів знаєте, ті змагання де металеві монстри на манежі намагаються знищити один одного. Оскільки в той час марив проектами та спільнотами, то задумав зробити клуб і навіть вийшло років через п’ять коли я почав працювати розробником (до того був менеджером) ми зробили клуб сумоїстів, ну знаєте таке — малюється коло, туди ставляться машинки роботи і вони виштовхують один одного за коло, тобто опинився за колом програв і от перебираючі коробки їз старими проектами я знайшов його.

Тож платформа в мене вже була — шасі, мотори, колеса. Не вистачало одного: нормального пульта. Не іграшкового, а справжнього, щоб відчувати себе інженером.

Тому купив FlySky FS-i6. Поклав на полицю. І... забув. І ось воно лежало. Дивилось на мене. Чекало. Але оскільки я шукаю просвітління настав час закрити гештальт.
Чому знову Raspberry Pi Pico
Хто читав попередню статтю — не дивується. Pi Pico це моя улюблена платформа на зараз. Два ядра, 264KB RAM, і можна писати на C, MicroPython або Arduino, як душа забажає, ну і в мене є ще один гештальт, колись купив книгу «TinyML Книга рецептів» і там приклади з нейромережеми саме з цим контроллером (маю ще один незакритий гештальт). Тут буде простіше, але платформа та сама.

До речі, в коментарях до тієї статті мені дохідливо пояснили що моя система — «не промислова», «курсова робота» і взагалі «ефект Дунінга-Крюгера» ну час покаже. Цього разу набагато усе скромніше. Просто машинка з клешнею і відеопередачею, такий собі Хижак на мінімалках. Без претензій. Хіба що якщо вона стане прототипом переможця в боях роботів, тоді вже можна. До речі українська команда теж колись брала там участь але за браком фінансування, щось там наче пішло не так, але то вже було так давно...
Компоненти: нічого зайвого
- FlySky FS-i6 — передавач, який 2 роки чекав свого часу
- FlySky FS-iA6B — приймач з підтримкою iBUS
- Raspberry Pi Pico — мозок операції
- TB6612FNG — драйвер моторів
- 4x TT мотори — жовті, ардуїнівські, знайомі кожному хто хоч раз замовляв щось на Аліекспрес
- Павербанк 5V — живить все господарство
- Шасі 4WD — основа

Але для початку тре кабель з роємом USB для живлення, оскільки я давно вже нічого не друкую та і загалом нічого не роблю, за мене усе пише і робить chatGPT, то ж вибір очевидний де я візьму кабель і так я відразав його від клавіатури.
Підключення
1.1 FS-iA6B → Raspberry Pi Pico
|
FS-iA6B |
Raspberry Pi Pico |
Примітка |
|
Signal (білий) |
GP1 (UART0 RX) |
Дані iBUS |
|
+ (червоний) |
VBUS (5V) |
Живлення приймача |
|
— (чорний) |
GND |
Земля |
Увага: GP1 — єдиний правильний пін! iBUS потребує апаратний UART. На Pico це GP1 (UART0) або GP5 (UART1).
1.2 TB6612FNG → Raspberry Pi Pico
|
TB6612FNG |
Raspberry Pi Pico |
Примітка |
|
AIN1 |
GP6 |
Лівий напрямок 1 |
|
AIN2 |
GP7 |
Лівий напрямок 2 |
|
PWMA |
GP8 |
Лівий швидкість |
|
BIN1 |
GP9 |
Правий напрямок 1 |
|
BIN2 |
GP10 |
Правий напрямок 2 |
|
PWMB |
GP11 |
Правий швидкість |
|
STBY |
GP12 |
Увімкнення драйвера |
|
VCC |
3.3V |
Логічне живлення |
|
GND |
GND |
Земля |
1.3 TB6612FNG → Мотори та живлення
|
TB6612FNG |
Підключення |
Примітка |
|
VM |
Павербанк 5V + |
Живлення моторів! |
|
GND |
Павербанк 5V - |
Спільна земля |
|
AO1, AO2 |
Ліві мотори паралельно |
Обидва лівих |
|
BO1, BO2 |
Праві мотори паралельно |
Обидва правих |
Критично важливо: VM обов’язково підключити до живлення! Без VM мотори не отримають струм навіть якщо логіка працює.
Мотори підключаються парами паралельно: лівий передній і лівий задній разом до AO1/AO2, правий передній і правий задній до BO1/BO2.
iBUS: один дріт замість шести
НЕ шукаю легких шляхів і не буду використовувати піни каналів, а одразу iBUS. До тогож, то зручно, замість того щоб тягнути окремий дріт на кожен канал (а їх 6!), iBUS передає все по одному дроту зі швидкістю 115200 baud. 32 байти, 6 каналів, все чисто.
Ще приємніше: на приймачі FS-iA6B iBUS вже працює з коробки. Жодних налаштувань. Просто підключи один дріт до GP1 на Pico — і вперед. Але був дещо неприємний сюрпиз DATA запрацював лише на GP1, що є UART0 Rx. Та перед цим думав, що щось в налаштуваннях тре змінити.

Щоправда, я спочатку знайшов в меню передавача пункт
«i-BUS Setup / Assigning CH1» і почав радісно щось там натискати. Виявилось це для розширювача каналів і до нашого випадку не має жодного відношення. Класика: спочатку тикати, потім читати документацію.
Парсер написав вручну — без бібліотек, просто 32 байти і трохи логіки:
void readIBUS() {
while (Serial1.available()) {
uint8_t b = Serial1.read();
if (bufIdx == 0 && b != 0×20) continue;
if (bufIdx == 1 && b != 0×40) { bufIdx = 0; continue; }
buf[bufIdx++] = b;
if (bufIdx == IBUS_BUFFSIZE) {
for (int i = 0; i < 6; i++) {
channels[i] = buf[2+i*2] | (buf[3+i*2] << 8);
}
bufIdx = 0;
}
}
}
Значення каналів — від 1000 до 2000, центр 1500. Просто і зрозуміло.
TB6612FNG і, як завжди усе через ж... бо спочатку тре читати доку, а не йти методом втику
Підключив все. Завантажив код. Мотори мовчать. Починаю вимірювати. AIN1 є. PWMA є. STBY є. На виходах нуль. Десять хвилин дивлюсь на схему. П’ять хвилин дивлюсь на плату. І тут доходить. VM не підключений. VM це живлення моторів. Без нього драйвер отримує сигнали, розуміє що робити, але фізично нікуди струм не подає. Як дуже мотивований айтішнік без зарплати.

Підключив VM до 5V павербанку. Мотори радісно заторохтіли. Але тут виявилась друга проблема. Я підключив чотири мотори по одному на кожен вихід драйвера. AO1, AO2, BO1, BO2 по мотору на кожен. Логічно ж? Чотири виходи, чотири мотори. Ні. AO1 і AO2 це плюс і мінус одного мотора. Це не чотири окремі виходи, це два канали по два полюси. TB6612FNG керує двома моторами, не чотирма.
Рішення просте: ліві мотори паралельно на канал A, праві паралельно на канал B. Машинка поїхала.
Танкове керування
Для чотириколісної платформи без керованих коліс єдиний спосіб повертати — це танкове мікшування: одна сторона вперед, інша назад.
int throttle = map(channels[1], 1000, 2000, -255, 255); int steering = map(channels[3], 1000, 2000, -255, 255); int leftSpeed = constrain(throttle + steering, -255, 255); int rightSpeed = constrain(throttle - steering, -255, 255);
Чотири рядки коду і машинка крутиться на місці, їде вперед, назад, повертає. Це той рідкісний момент коли все працює з першого разу і ти сидиш і думаєш: «невже?».
Каналів вистачає на все
FlySky FS-i6 дає 6 каналів. Чотири займають два джойстики, ще два крутилки VrA і VrB. Плюс чотири тумблери SWA, SWB, SWC, SWD.

Розкладка вийшла така:
| Канал | Джойстик | Функція |
|---|---|---|
| CH2 | Лівий ↑↓ | Газ вперед/назад |
| CH4 | Лівий ←→ | Поворот |
| CH3 | Правий ↑↓ | Серво основа |
| CH1 | Правий ←→ | Серво поворот клешні |
| CH5 | VrA крутилка | Серво клешня хватати |
| CH6 | SWA тумблер | Ручне/авто |
Правильно, наступний крок — рука хижака. Але про це в наступній частині.
Результат першої частини
За один вікенд:
- iBUS протокол читається і дає всі 6 каналів ✅
- TB6612FNG керує чотирма моторами ✅
- Машинка їде вперед, назад, повертає ✅
- Гештальт починає закриватись ✅
FlySky більше не пилиться на полиці. Він нарешті робить те для чого куплявся.
У наступних частинах: додаємо серво, складаємо Клешню, відеопередачу і перетворюємо просту машинку на справжнього Автобота Хижака.
Фінальний код
Повний код для керування машинкою через iBUS з підтримкою танкового керування:
#define IBUS_BUFFSIZE 32
// TB6612FNG піни
#define AIN1 6 // Лівий напрямок 1
#define AIN2 7 // Лівий напрямок 2
#define PWMA 8 // Лівий PWM швидкість
#define BIN1 9 // Правий напрямок 1
#define BIN2 10 // Правий напрямок 2
#define PWMB 11 // Правий PWM швидкість
#define STBY 12 // Увімкнення драйвера
#define DEAD_ZONE 30 // Мертва зона джойстика
uint8_t buf[IBUS_BUFFSIZE];
uint8_t bufIdx = 0;
int channels[6] = {1500,1500,1500,1500,1500,1500};
void setup() {
Serial.begin(115200); // USB дебаг
Serial1.begin(115200); // GP1 = iBUS
pinMode(AIN1, OUTPUT); pinMode(AIN2, OUTPUT);
pinMode(BIN1, OUTPUT); pinMode(BIN2, OUTPUT);
pinMode(PWMA, OUTPUT); pinMode(PWMB, OUTPUT);
pinMode(STBY, OUTPUT);
digitalWrite(STBY, HIGH); // увімкнути драйвер
Serial.println("Autobot Ready!");
}
void loop() {
readIBUS();
// CH3 = лівий джойстик вертикаль (газ)
// CH4 = лівий джойстик горизонталь (поворот)
int throttle = map(channels[2], 1000, 2000, -255, 255);
int steering = map(channels[3], 1000, 2000, -255, 255);
// Мертва зона
if (abs(throttle) < DEAD_ZONE) throttle = 0;
if (abs(steering) < DEAD_ZONE) steering = 0;
// Танкове мікшування
int leftSpeed = constrain(throttle + steering, -255, 255);
int rightSpeed = constrain(throttle - steering, -255, 255);
setLeft(leftSpeed);
setRight(rightSpeed);
}
void readIBUS() {
while (Serial1.available()) {
uint8_t b = Serial1.read();
if (bufIdx == 0 && b != 0x20) continue;
if (bufIdx == 1 && b != 0x40) { bufIdx = 0; continue; }
buf[bufIdx++] = b;
if (bufIdx == IBUS_BUFFSIZE) {
for (int i = 0; i < 6; i++) {
channels[i] = buf[2+i*2] | (buf[3+i*2] << 8);
}
bufIdx = 0;
}
}
}
void setLeft(int spd) {
if (spd > 0) { digitalWrite(AIN1,HIGH); digitalWrite(AIN2,LOW); }
else if(spd<0){ digitalWrite(AIN1,LOW); digitalWrite(AIN2,HIGH); spd=-spd; }
else { digitalWrite(AIN1,LOW); digitalWrite(AIN2,LOW); }
analogWrite(PWMA, spd);
}
void setRight(int spd) {
if (spd > 0) { digitalWrite(BIN1,HIGH); digitalWrite(BIN2,LOW); }
else if(spd<0){ digitalWrite(BIN1,LOW); digitalWrite(BIN2,HIGH); spd=-spd; }
else { digitalWrite(BIN1,LOW); digitalWrite(BIN2,LOW); }
analogWrite(PWMB, spd);
}Якщо маєте питання або свій досвід з FlySky чи Pi Pico — пишіть в коментарях. Тільки, будь ласка, без «ефекту Дунінга-Крюгера» 😄
Сподобалась стаття? Підписуйтесь на автора, щоб отримувати сповіщення про нові публікації на пошту.

21 коментар
Додати коментар Підписатись на коментаріВідписатись від коментарів