Управляем сервопріводамі з OpenWRT без Arduino

    

Короткий пост про те як можна уникнути зайвих елементів у системі з сервопріводамі і використовувати залізо по максимуму

 
 

Передісторія

Я вельми давно і щільно хворий Linux, OpenWRT, мережевими і бездротовими технологіями, безпекою, а тепер ще й став потихеньку заражатися роботобудуванні і розумними будинками. Все це дуже круто, особливо коли є стільки готових шаблонів, вільного і відкритого вихідного коду, а часами можна зовсім перейти на сторону зла і швиденько накидати логіку в Scratch.
Але потім прокидається інтерес вже не просто покліпати світлодіодами, вау-ефект проходить і необхідно вирішувати прикладні завдання. Ніби й тут слід було б захопитися великою кількістю готового, але диявол як завжди в деталях. Одна справа — керувати логікою
ЕСТЬ/НЕТ
, це дозволяє легко включати або відключати світло, можна навіть датчик якості повітря (MQ-135) підчепити і включати витяжку при необхідності. Все це круто, але на дворі 21 століття, космічні кораблі борознять великий театр і душа просить чогось по-крутіше. Погляд мій упав на управління сервопріводамі. Чому б і ні? Тема вельми широка, адже вони присутні в багатьох механізмах, від роботів до простих откривалок-закривалок. Плюсом так само є і те що в літальних апаратах двигуни управляються аналогічно і це розширює діапазон використання просто в рази.
 
Заинтересовавшихся запрошую під кат
 
UPD: Ті хто вже давно знайомий з темою і хоче перейти відразу до суті — сміливо промотувати до розділу & quot; Покрокова інструкція & quot ;.
 
 
 

Почнемо з початку

Щоб суть цієї замітки була зрозуміла всім, варто спершу звернути увагу на складові сервоприводу.
 
 image
 
Електродвигун, редуктор, потенціометр і контролер. Все геніальне просто, чи не так? =)
 
Для управління сервоприводом використовується широтно-імпульсна модуляція або ШІМ. Нічого складного, це просто сигнал у вигляді імпульсів прямокутної форми. основними параметрами є ширина імпульсу і ширина «паузи». «Пауза», а краще називати її правильно — період, задає частоту сигналу. Скажімо, якщо у нас ширина періоду дорівнює 100 мс, то частота дорівнюватиме 10 Гц. Порахувати дуже просто: переводимо мілісекунди в секунди і ділимо одиницю на це число. Відповідно, 100мс = 0,1 с і якщо 1 розділити на 0,1 то отримаємо 10. Можете перевірити на калькуляторі =)
Ширина імпульсу задає кут повороту сервоприводу, а у випадку з моторами літального апарату задає швидкість і напрямок обертання.
Схематично це виглядає приблизно так:
 
 
А на осцилографі ось так:
 
 
Тепер поговоримо про те як сервопривід сприймає такий сигнал. І вже тихенько підкрадається диявол з деталями.
Справа в тому що контролер може бути цифровий або аналоговий.
Якщо зовсім по-простому, то різниця в тому що аналоговий контролер подає або не подає напругу тільки в момент імпульсу. Виставивши інтервал імпульсу 40, 120 або, скажімо, 240 мс можна помітити як сервопривід почне «смикатися» при роботі. Все тому що всередині стоїть мікросхема і частота роботи всього сервоприводу дорівнює частоті зовнішнього сигналу. Стандартні 20 мс це 50 Гц, 40 мс це 25 Гц, і за аналогією. Відповідно, 50 або 25 разів на секунду на двигун подається (або не подається) напруга. Знизивши частоту можна істотно зменшити крутний момент і домогтися більш повільної роботи механізму, правда ціною вже описаного «смикання».
Цифрові контролери, як правило, представляють із себе невеликий мікропроцесор з обв'язкою. Ключова відмінність від аналогової мікросхеми в тому що внутрішня частота роботи постійна. Ви можете скільки завгодно знижувати частоту керуючого сигналу, це впливатиме тільки на час реакції, але крутний момент буде постійним. Хоча, видаючи зміна положення через довгі проміжки і невеликими порціями, можна домогтися повільній швидкості обертання. Тут вже залежить від конкретного сервоприводу і його параметрів.
 
 

Як генерувати сигнал?

Для цього зазвичай застосовують який-небудь мікроконтролер, особливу любов живлять до платформи Arduino. Там все просто. Використовується готова бібліотека, скармливаем потрібної функції параметри сигналу і отримуємо на заданому GPIO потрібної ширини імпульси.
Але що робити якщо немає можливості використовувати мікроконтролер, зв'язаний з основним пристроєм, а потужності самого контролера для вирішення задач, ну, ніяк не вистачає? Залишається шукати альтернативні варіанти. І таких є у мене!
Як вже стало зрозумілим з заголовка, використовуватиметься операційна система OpenWrt. Яка по суті своїй є повноцінним дистрибутивом на ядрі Linux. А це дає широкі можливості і гнучкість настройки. OpenWrt та її похідні активно використовуються в різних системах «розумний дім», але про це в іншій статті. Як же генерувати ШІМ (або на буржуйському PWM) сигнал? Виявляється, не багатьом складніше ніж на Arduino. Для цього необхідно задіяти всі ті ж GPIO, а замість бібліотеки модуль ядра під назвою PWM-GPIO-Custom. Остання стабільна версія OpenWrt де він працює — 12.09, але щоб це зрозуміти я витратив близько тижня, намагаючись змусити працювати на поточному Trunk. Не знаю з якої причини, але в офіційному репозиторії пакета з цим модулем немає і доведеться збирати його самостійно, але це не так складно. Нижче я напишу як.
 
 

Покрокова інструкція

Отже, для початку нам необхідно завантажити складальний інструментарій OpenWrt. Хоча, якщо зовсім чесно, то почати потрібно з ВСТАНОВЛЕННЯ Linux, але я сподіваюся що багато з вас цей пункт вже виконали =)
Отже, ви створили папку для інструментарію, перейшли в неї
Виконати завантаження початкових кодів можна командою
 
git clone git://git.openwrt.org/12.09/openwrt.git

У вас же є присутнім термінал в нижній частині вікна, правда?
Шкода, це дуже зручно =)
 
Після завантаження потрібно перейти в папку openwrt і завантажити пакети командою
 
git clone git://git.openwrt.org/12.09/packages.git

 
Тепер у нас є всі вихідні коди пакетів. Хоча стривайте… А як же pwm-gpio-custom? Його немає.
Не впадайте у відчай, ось він
Потрібно просто розпакувати вміст в openwrt / package і все буде добре =)
 
Тепер перейдемо безпосередньо до складання.
Перебуваючи в папці openwrt необхідно виконати
make -j n kernel_menuconfig

Замість n потрібно підставити число ваших ядер + 1.
Відкриється синє меню. Вибираємо пункт Device Drivers.
 
 
Знаходимо PWM Support
 
 
Активуємо пункт PWM emulation using GPIO. Вибирати пропуском. Потрібно щоб скрізь стояли зірочки, це важливо =)
 
 
Після цього потрібно небагато переконфигурировать ядро. Шукаємо відповідний пункт.
 
 
Ставимо зірочку на пункті High Resolution Timer Support, виставляємо значення Timer frequency на 1000HZ, а в параметрі Premption Model вибираємо Low-Latency Desktop.
 
 
Необхідно напевно знати апаратну платформу свого роутера. Але ще важливіше вказати її в конфігурації. У мене це Atheros ar71xx
 
 
 
Необхідна настройка ядра завершена. Тепер як тільки ви натиснете фінальний Exit система запитає вас про те чи варто зберігати зміни, на що потрібно відповісти ствердно.
Тепер потрібно таким же способом конфігурувати збірку самої ОС командою
make -j n menuconfig

Потім в меню Kernel Modules
 
 
Вибрати Other modules
 
 
І поставити зірочку на пункті kmod-pwm-gpio-custom
 
 
Все, можна приступити до складання. Все та ж команда
make -j n 

 
Залишається відкинутися на спинку крісла і що-небудь подивитися, можна попити чаю / кави, процес збірки не швидкий.
Як тільки збірка закінчиться, можна переходити в папку bin . У ній буде папка з вашою платформою і образи. ПРОШУ можна в повній відповідності зі стандартною інструкцією. Як тільки завершиться процес прошивки, можна сміливо заходити через telnet. Необхідно буде ще додатково закачати пакет kmod-pwm-gpio-custom на сам пристрій. Це можна зробити через SCP, або через wget, або ж встановити openssh-sftp-server і скористатися FileZilla.
Завантажувати сам пакет краще в директорію / tmp, так як ПЗУ не гумова, а дана директорія фізично розташовується в оперативній пам'яті, якої зазвичай від 32 до 64 Mb. Після закачування пакет необхідно встановити командою
opkg install /tmp/kmod-pwm-gpio-custom_xxx.ipk.
Можна сильно не заморочуватися з назвою пакета, автодоповнення по TAB прекрасно працює =)
 
 

Генерація ШІМ сигналу

 
Після установки пакета можна переходити до безпосереднього управління GPIO і генерації ШІМ сигналу.
Для цього необхідно активувати модуль ядра. Зробити це можна командою
insmod pwm-gpio-custom bus0=0,23 bus1=1,20

Це просто приклад того як воно може бути. busX задає номер шини, якою можна керувати через символьний пристрій під цим самим номером в
/sys/сlass/pwm
У нас їх з'явиться два: gpio_pwm.0: 0 і gpio_pwm.1: 0 . Маніпулювати параметрами ШІМ можна просто записуючи відповідні змінні у файли. Так, ледве не забув, всі значення задаються в наносекундах. Поїхали:
 
 
echo 10000000 > /sys/class/pwm/gpio_pwm.0\:0/period_ns
Задає період. В даному випадку це 100 Гц.
 
echo 8500000 > /sys/class/pwm/gpio_pwm.0\:0/duty_ns
Задає шпаруватість.
Так, деякі висновки інвертовані за замовчуванням і необхідно задати час «порожнечі» всередині періоду. Якщо ж значенням High для GPIO явдяєтся 1, то потрібно задати
echo 1500000 > /sys/class/pwm/gpio_pwm.0\:0/duty_ns
Буде вказуватися час самого імпульсу.
Перевірити можна дослідним шляхом. Можливо я знайду або хтось підкаже спосіб зробити це більш красиво =)
Тепер залишилося тільки активувати подачу сигналу.
 
echo 1 > /sys/class/pwm/gpio_pwm.0\:0/run
І ми отримуємо на осцилографі щось на зразок цього
 
 
Якщо підключити до висновку PWM кабель сервоприводу — він встане рівно в центральне положення. Зрозуміло, харчування теж потрібно підключити =)
 
 

Висновок

 
Таким способом можна домогтися генерації сигналу на частоті 200 Гц, а це означає що час реакції для одного приводу знизиться до 5 мс. Для відкривання-закривання замка, може, і не критично, а от для літальних апаратів буде вельми актуально. Сподіваюся що я обзаведуся найближчим часом мотором і контролером, або добрий читач з міста Єкатеринбург погодиться позичити мені такий для експериментів і з'явиться друга стаття =)
Спасибі що дочитали до кінця. На закуску дозвольте представити вам трохи відео. =)
 
Демонатрація роботи. Два канали, налаштовані на крайнє праве і крайнє ліве положення.
  
Відеодемонстрація ШІМ сигналу.
  
 

P.S.

 
Хочу висловити величезну подяку автору модуля Claudio Mignanti , який відповів поштою і роз'яснив необхідні питання.
 
Схема сервоприводу і керуючих сигналів були взяті на wiki.amperka.ru
 
Якщо у вас є якісь доповнення чи побажання — пишіть в коментарях.
    
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.