10 серпня 2018 р.

19. Радіо-керований робот

Початковий задум


Набавившись вдосталь з роботом-черепашкою, вирішили ми створити для нього компаньйона. Задум поступово оформився в наступні ідеї:
  • Керування через WiFi навіть при прямому з'єднанні, все ж має деякі затримки на передачу команд. А що, якщо використати для керування звичайні 2.4 GHz радіо-пульти, що використовуються для радіокерованих моделей?
  • Наскільки шасі, виготовлене із підручних матеріалів, буде уступати фірмовому заводському?
  • Маємо кілька LCD дисплеїв - добре би перевірити наскільки їх зручно використовувати в робототехнічних проектах
  • Ніякого більше живлення від NiMH акумуляторів - тільки Li-Ion!
Робот із системою радіокерування

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

Використані компоненти

Деталі з конструктора
Шасі - саморобне, скручене із залишків старого дитячого конструктора
Мікроконтролер - аналог Arduino Nano з монтажним шилдом для зручності підключення
Мікроконтролер - аналог Arduino Nano з монтажним шилдом для зручності підключення
Двигун з редуктором 100 RPM, 6 вольт
Двигуни з редуктором 100 RPM, 6 вольт, 2 шт
Кронштейн для кріплення двигуна до шасі
Кронштейн для кріплення двигуна до шасі, 2 шт
Кронштейн для кріплення колеса на вісь двигуна
Кронштейн для кріплення колеса на вісь двигуна, 4 мм., 2 шт.
Драйвер двигунів з вбудованою схемою перетворення живлення
Драйвер двигунів з вбудованою схемою перетворення живлення
LCD екранчик графічний 128x64, I2C
LCD екранчик графічний 128x64, I2C
LCD екранчик текстовий 1602, I2C
LCD екранчик текстовий 1602, I2C
Пульт радіокерування, 6-канальний
Пульт радіокерування, 6-канальний
Батарея Li-Ion 18650
Батарея Li-Ion 18650, 2 шт. 
Контролер заряду для батареї 2S
Контролер заряду для батареї 2S
Т-конектори
Т-конектори для живлення
Зарядний пристрій
Зарядний пристрій універсальний

Шасі


Основу робота зібрали із залишків старого дитячого конструктора. Для кріплення двигунів довелося докупити спеціальні кронштейни:

Шасі робота з кронштейнами для кріплення двигунів


Двигуни звичайні, в комплекті з редукторами.

Шасі робота з двигунами


Головні параметри, за якими треба пильнувати при виборі двигунів, це робоча напруга і максимальна кількість обертів на хвилину.

Вже з самого початку ми знали, що будемо використовувати Li-Ion батарею з двох послідовно з'єднаних елементів 18650. Тому робоча напруга 6-7 вольт підійшла просто ідеально.

З обертами на хвилину ми трохи не вгадали. І для балансуючого робота, і для нашого триколісного, 100 RPM виявилося явно замало. Порада наступникам - беріть 200 RPM. Краще мати трохи запасу по швидкості - потужності двигунів для такого маленького робота завжди буде вдосталь.

Як приємний бонус, в редуктор вмонтовані давачі Холла (так звані енкодери), які дозволяють рахувати реальну кількість обертів, які виконує двигун. Саме для зчитування цих показників і використовується жмут додаткових провідників. Ми ці показники не читаємо і не враховуємо. Але якби треба було - можливість є.

Роз'єм підключення двигуна
Для кріплення коліс до осей моторів купили спеціальні кронштейни. Головне тут - підібрати правильний діаметр внутрішнього отвору, щоб кронштейн щільно зафіксувався на осі мотора. В нашому випадку - підійшов кронштейн з отвором на 4 мм.

Колеса, запозичені з дитячого конструктора + кронштейни для кріплення
Шасі із приєднаними колесами
Візок-основа робота

Отриманий двоколісний візочок став надійною основою для робота. Можливість добудовувати на ньому які-завгодно конструкції з елементів конструктора дають практично необмежені можливості роботодизайнеру.

Електронна начинка


Загальна схема

 

Схема електрична

В схему включено мінімальний набір компонентів, необхідний для пересуванням робота та реагування на команди пульта радіокерування. Рідкокристалічні екранчики додані з косметичною метою - їхня присутність необов'язкова.

Мікроконтролер


В принципі, в габарити нашого шасі можна вписати плату мікроконтролера майже будь-якого типу. Але нам було цікаво поекспериментувати з Arduino Nano. Оскільки під'єднувати до нього провідники не дуже зручно - ми зразу ж в комплекті взяли плату розширення, яка виводить всі контакти Nano в окремі зручні до під'єднання роз'єми.

Arduino NANO на монтажному шилді


Єдине чого бракнуло у платі розширення - розпаяного контакту підводу зовнішнього живлення Vin. Але відповідне гніздо у платі було - до нього легко припаялася стандартна гребінка.

Система живлення


Живлення побудоване на основі двох елементів Li-Ion 18650 (типу таких), з'єднаних послідовно. В основу покладено ідеї, описані в попередній статті (Як нагодувати робота).

Деталі для побудови батареї
Акумуляторна батарея в зібраному стані


Для керування батареєю використали контролер батареї 2S - саме ця маленька платка відповідає за захист елементів батареї від надмірного заряджання чи розряджання.

Для заряджання батареї ми купили універсальний пристрій Eachine WT50. З усіх варіантів, саме він здався нам найбільш дружелюбним, і універсальним. Кабелі, які ідуть в комплекті з ним передбачають під'єднання батарей за допомогою T-подібного штекера. Саме такі ми поставили і на нашу батарею.

Простий двохпозиційний вимикач зі старої китайської іграшки під'єднує  позитивну лінію батареї або до першого Т-подібного гнізда, або до другого. Технічно - обидва гнізда абсолютно ідентичні. Одне з них можна використовувати для живлення робота, інше - для під'єднання зарядного пристрою. Вимикач дозволяє відімкнути робота від живлення, і захистити його від потенційно небезпечних навантажень, які можуть виникнути під час заряджання батареї.

Драйвер двигунів


В ролі драйвера двигунів використовуємо версію на базі елемента L298N. Особливістю саме цього модуля є наявність схеми перетворення живлення.
Модуль драйвера двигунів
Ця схема може з напруги живлення двигунів (7-35 V) добувати напругу 5 V, необхідну для живлення мікросхем самого драйвера. Запасу потужності тих 5 V достатньо, щоб використати їх для живлення всіх інших схем робота (включно із модулем мікроконтролера, сенсорами і приймачем радіокерування).

Детальніше про використання такого модуля драйвера можна почитати тут (англ), тут (рос.) або тут (рос.).

Ключові кроки:
  • Живлення двигунів подаємо на вхід +12V (насправді тут буде 7.2 V, отримані з нашої батареї)
  • Замикаємо перемичку біля входу +12V, щоб задіяти схему перетворення напруги
  • До виводу +5V підключаємо лінію живлення всіх схем робота
  • Двигуни під'єднуємо до відповідних роз'ємів OUT1-4
  • Контакти ENA та ENB на +5 V НЕ ЗАКОРОЧУЄМО, а під'єднуємо до PWM виводів Arduino Nano. Так ми зможемо керувати швидкістю обертання двигунів.
  • Контакти IN1-4 під'єднуємо до будь-яких виводів мікроконтролера. Виставляючи різні комбінації напруги на цих виводах ми зможемо задавати напрямок обертання двигунів.

Програмний код для керування драйвером двигунів зведений в один максимально спрощений клас (модуль).

Для початку роботи з ним - створюємо об'єкт цього класу, вказавши номери виводів Arduino, до яких ми під'єднали керуючі лінії драйвера:

const uint8_t ENA = 10;
const uint8_t IN1 = 9;
const uint8_t IN2 = 8;
const uint8_t IN3 = 7;
const uint8_t IN4 = 6;
const uint8_t ENB = 5;

MotorL298NController motorController(ENA, IN1, IN2, ENB, IN3, IN4);

Потім в будь-якому місці програми можна викликати метод go() створеного об'єкта, передаючи як параметр бажану швидкість двигунів. Значення швидкості може змінюватися від -255 (повний назад) до +255 (повний вперед). Виклик методу з одним параметром запустить двигуни на однаковій швидкості. Виклик методу з двома параметрами дозволяє встановлювати швидкість кожного двигуна окремо.

motorController.go(255); // повний вперед!
motorController.go(255,100); // плавно повертаємо по дузі вправо

Зверніть увагу - двигуни не будуть обертатися при значеннях швидкості близьких до нуля. В нашому випадку - двигуни зовсім не реагують на швидкості в діапазоні від -30 до +30. Але при цьому можуть досить противно пищати. Щоб цього уникнути - знайдіть робочий діапазон швидкостей для ваших двигунів, і уникайте цієї мертвої зони. Нижче я покажу як ми уникали цього ефекту в нашій програмі.

Система радіокерування

 

Базові принципи

 

Радіокерований робот + RC пульт

Пульти керування фірми FlySky це саме те, що потрібно для аматорів нашого рівня. Досить недорогі, вони все ж багаті функціями. Хоча в цьому проекті ми використали лише два канали з шести, і то в найпростішому режимі PWM, все ж варто брати апаратуру із запасом. Різниця в ціні не настільки суттєва, а в майбутньому вам точно захочеться поекспериментувати з додатковими функціями.

Система радіокерування складається з двох частин - пульта керування (передавача) і приймача. За допомогою радіохвиль стан перемикачів і важелів на пульті передається на приймач, і приймач вже передає цю інформацію до виконавчих механізмів моделі чи робота. Сучасні системи забезпечують передачу інформації і в зворотному напрямку - тобто ваша радіокерована модель може передавати дані про свій стан (наприклад заряд батареї чи температуру двигунів) назад на пульт керування, і ця інформація буде відображатися на екранчику пульта.

Виконавчі механізми у більшості випадків це або двигуни, які запускаються подаванням високої напруги на якесь реле, або сервомашинки, які керуються спеціальним сигналом з використанням Широтно-Імпульсної Модуляції (ШІМ або PWM - див попередній допис на цю тему). Перші версії систем радіокерування проектувалися саме із такою задумкою - щоб можна було підключити сервомашинку прямо до гнізда приймача і відхилення важеля на пульті керування негайно відгукувалося відхиленням сервомашинки від початкового положення. Для такого під'єднання навіть нічого перепаювати не треба - сервомашинка разом із керуючим сигналом отримає і +5V живлення та GND. Більше того - PWM сигнал є абсолютно таким же ж, який видає на свої виводи Arduino.
Схема принципу роботи системи радіокерування


Відповідно в приймачі шестиканальної системи буде 6 трьохконтактних гнізд, до яких можна підключити 6 сервомашинок (або інших пристроїв).

Наступним кроком еволюції стало створення протоколу PPM (Pulse Position Modulation). Його ще деколи називають CPPM або PPMSUM. Задумка в тому, щоб одним каналом передавати інформацію про кілька важелів керування одночасно. Спочатку передається імпульс про положення першого важеля, потім другого і так далі. Таким чином для керування багатьма пристроями (аж до 12 ) достатньо одного радіоканалу, і одного роз'єму на приймачі. Однак використовувати PPM сигнал напряму з приймача не можна. Його треба спочатку розшифрувати і розділити на складові, окремі для кожного виконавчого механізму.

Ще складнішим є сімейство протоколів Serial RX. На відміну від попередніх він є цифровим. Тут вже не треба міряти тривалість імпульсу в мікросекундах і на основі цього намагатися зрозуміти до якої швидкості слід розігнати двигун, чи наскільки повернути сервомашинку. Вся інформація передається у вигляді одиничок і нуликів, і на виході ми отримуємо інформацію у вигляді "Канал 1: 1345; Канал 2: 1800". Проблема лише в тому, що кожен виробник використовує свій протокол (S.Bus, i-Bus, XBus, Graupner Hott) і між собою вони несумісні. Свій цифровий протокол мають і системи від FlySky.

Більше деталей про ті всі протоколи можна прочитати в спеціалізованих статтях (англ.). Ми ж зупинимося на найпростішому варіанті - протоколі PWM. SparkFun має гарну статтю (англ.) про те, як підключити приймач системи радіокерування до Arduino.

Підключення приймача


Все що треба для підключення - завести на приймач лінії живлення від Arduino (+5V та GND - вони є спільними для всіх каналів). Сигнальні виводи каналів треба підключити напряму до будь-яких цифрових виводів Arduino.

Набагато складнішим може бути правильне налаштування пульта керування. Знайти які саме канали відповідають яким саме важелям керування на пульті. А також не забудьте перевести потрібні вам канали в режим PWM.

Приймач на робота можна монтувати як завгодно. А от зовнішню антену - з виконанням певних рекомендацій:
  1. Бажано уникати контакту антени з металевими елементами корпусу робота
  2. Якщо антена має два відгалуження - бажано розвести їх під прямим кутом один відносно другого.

Читання в програмі команд з пульта


В програмному коді працюємо з радіо каналами наступним чином:

  1. Переконуємося, що виводи, під'єднані до радіоприймача переведені в режим вводу:

    pinMode(RC_CH_TURN, INPUT);
    pinMode(RC_CH_THROTTLE, INPUT);
       
  2. Визначаємо тривалості імпульсу на каналі ручки газу та на каналі повороту

    long chThrottle = pulseIn(RC_CH_THROTTLE, HIGH, 30000);
    long chTurn = pulseIn(RC_CH_TURN, HIGH, 30000);

    В нашому випадку (на  Arduino Nano) довелося передати третім параметром 30000. При менших значеннях сигнал не зчитувався правильно.
  3. Значення тривалості імпульсу менші, ніж 900, означають, що канал не підключено. Можливо приймач взагалі не отримує сигналу з пульта. Краще тоді взагалі зупинити двигуни повністю і не робити нічого.
  4. Значення від 900 до 1000 також ігноруємо. Щоб надійно зафіксувати робота в точці зупинки і не смикати його даремно через випадковий шум.
  5. Беремо до уваги лише значення від 1000 до 2000 і пропорційно "розмазуємо" їх по шкалі швидкості двигуна (від 30 до 255). Про 30 - пам'ятаєте? На менших швидкостях мотори будуть противно свистіти, але з місця зрушити не зможуть
    speedL = map(chThrottle, 1000, 2000, 30, 255);
  6. Далі вже починається проста логіка опрацювання крутості повороту і віддавання  остаточної команди двигунам на зміну швидкості.

Зверніть увагу - значення тривалостей імпульсів, так само як і діапазон робочих швидкостей моторів, у вас можуть трохи відрізнятися. Будьте готові підбирати потрібні вам значення експериментальним шляхом.

Інформаційні екранчики

 

Передній графічний 128x64


Для розширення сценічного образу робота ми на нього повішали два екранчики.

Передній - для малювання смайликів і відображення емоцій. Це графічний одноколірний LCD екран 128x64 пікселів, підключений до мікроконтролера шиною I2C - тобто за допомогою двох сигнальних провідників.

Вся робота з ним відбувається через бібліотеку U8g2, яку можна підключити прямо в середовищі програмування Arduino. Все що ми робимо зараз - малюємо щасливий смайлик, який не сходить з лиця робота весь час, поки він працює:


U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0);

u8g2.begin();
u8g2.firstPage();
do {
    u8g2.drawLine(41, 8, 45, 32);
    u8g2.drawLine(83, 8, 87, 32);
    u8g2.drawEllipse(65, 43, 29, 8,
            U8G2_DRAW_LOWER_LEFT | U8G2_DRAW_LOWER_RIGHT);
    u8g2.drawLine(73, 51, 78, 55);
    u8g2.drawLine(61, 51, 66, 55);
    u8g2.drawLine(67, 51, 72, 57);
    u8g2.drawEllipse(72, 55, 6, 8,
            U8G2_DRAW_LOWER_LEFT | U8G2_DRAW_LOWER_RIGHT);
} while (u8g2.nextPage());

Графічний екранчик зображає веселого смайлика

Спробуйте змінювати смайлик на здивований, якщо робот не може встановити зв'язок із пультом керування :-)

Задній текстовий екран 1602


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


Цифри 1602 в назві екранчика означають, що він може показати два рядки по 16 символів в кожному. Цей екран також підключений до мікроконтролера через шину I2C, що дозволило зекономити з десяток виводів Arduino та ще й розділити цю шину з переднім екранчиком.

Робота з такими екранами відбувається за допомогою бібліотеки LiquidCrystal-I2C. Приклади з нашого коду:

// I2C адреса = 0x27, 16 символів, 2 рядки
LiquidCrystal_I2C backLCD = LiquidCrystal_I2C(0x27, 16, 2);



// ініціалізуємо
backLCD.init();

// вимикаємо автопрокрутку
backLCD.noAutoscroll();

// вмикаємо підсвітку
backLCD.backlight();

// виводимо якийсь текст
backLCD.print("Initializing...");

Єдиним не зовсім очевидним кроком може бути вгадування адреси I2C до якої треба звертатися, щоб працювати з конкретними пристроями. Зазвичай вони співпадають з тими, які показані в прикладах. Для пошуку адрес, на які налаштовані I2C пристрої також можна використати програмку I2C Scanner.

В загальному про роботу з I2C шиною можна почитати на форумі Ніка Гаммона (англ.). Або подивитися у Джеремі Блума (англ. або рос.).

Немає коментарів:

Дописати коментар