3.16. Керування сервоприводом¶
Хобі-сервопривід (RC) — це невеликий редукторний двигун у закритому корпусі із вбудованим замкненим контуром керування положенням. Всередині корпусу знаходяться двигун постійного струму, редукторний знижувач, потенціометр, підключений до вихідного валу, і невелика плата драйвера, яка порівнює показання потенціометра із заданим значенням, що надходить ззовні. Драйвер запускає двигун у тому напрямку, який зменшує помилку, і зупиняється, коли положення збігається. З боку камери нічого з цього не видно – ви просто вказуєте сервоприводу, куди рухатись.
3.16.1. Сигнал ШІМ¶
Сервопривід отримує своє задане значення як сигнал ШІМ із фіксованою частотою кадрів 50 Гц, де ширина імпульсу вибирає положення:
Імпульс 1,0 мс переміщує вал на один кінець його ходу.
Імпульс 1,5 мс зупиняє вал у центрі.
Імпульс 2,0 мс переміщує вал на інший кінець.
Будь-яке значення між ними відповідає проміжному положенню.
Кадр ШІМ сервопривода становить 20 мс; ширина імпульсу (1,0 – 2,0 мс) вибирає положення.¶
На відміну від світлодіодів і двигунів, сервопривід не усереднює ШІМ. Сама ширина імпульсу є командою: внутрішня логіка сервопривода вимірює кожен імпульс, відповідно встановлює ціль і запускає двигун, поки вихід не збіжиться. Робочий цикл як частка (від 5 % до 10 % по всьому діапазону) є несуттєвим – важлива абсолютна ширина імпульсу, якою й потрібно керувати програмно.
3.16.2. Підключення¶
Хобі-сервоприводи використовують трипровідний роз’єм:
Живлення (зазвичай червоний): власне джерело живлення сервопривода, як правило 4,8 В до 6 В. Не живіть сервопривід від шини 3,3 В камери – вона не може забезпечити струм заклинювання, і шина просяде.
Земля (зазвичай чорний або коричневий): зворотний шлях для живлення сервопривода, з’єднаний із землею камери, щоб сигнал також мав спільний опорний потенціал.
Сигнал (зазвичай білий, жовтий або помаранчевий): лінія ШІМ від GPIO камери.
3.16.3. Код¶
duty_u16() спрацює, але він встановлює робочий цикл як частку від періоду – незручно для сигналу, де важлива абсолютна ширина імпульсу, а період фіксований. duty_ns() встановлює ширину імпульсу безпосередньо в наносекундах:
from machine import PWM, Pin
servo = PWM(Pin("P7"), freq=50, duty_ns=1_500_000) # centre
Несна частота — 50 Гц (період 20 мс); час високого рівня в кожному циклі становить рівно 1500 мкс. Невеликий допоміжний засіб робить відображення положення в імпульс явним:
def set_position(angle):
# angle: 0..180 degrees mapped to 1.0..2.0 ms
pulse_us = 1000 + (angle * 1000) // 180
servo.duty_ns(pulse_us * 1000)
set_position(0) # full one way
set_position(90) # centre
set_position(180) # full the other way
Повільне проходження по всьому діапазону:
import time
for angle in range(0, 181, 5):
set_position(angle)
time.sleep_ms(20)
for angle in range(180, -1, -5):
set_position(angle)
time.sleep_ms(20)
Діапазон 1,0 – 2,0 мс є стандартним, але багато сервоприводів допускають ширший діапазон (часто від 500 мкс до 2500 мкс) для повного ходу. Технічні умови на сервопривід містять точні межі ширини імпульсу; значення за межами цього діапазону можуть ударити двигун об механічні упори.
Для сервопривода з нестандартним діапазоном перенесіть межі в константи та параметризуйте відображення:
PULSE_MIN_US = 500 # full one way (from the data sheet)
PULSE_MAX_US = 2500 # full the other way
def set_position(angle):
span_us = PULSE_MAX_US - PULSE_MIN_US
pulse_us = PULSE_MIN_US + (angle * span_us) // 180
servo.duty_ns(pulse_us * 1000)