3.16. Керування сервоприводом

Хобі-сервопривід (RC) — це невеликий редукторний двигун у закритому корпусі із вбудованим замкненим контуром керування положенням. Всередині корпусу знаходяться двигун постійного струму, редукторний знижувач, потенціометр, підключений до вихідного валу, і невелика плата драйвера, яка порівнює показання потенціометра із заданим значенням, що надходить ззовні. Драйвер запускає двигун у тому напрямку, який зменшує помилку, і зупиняється, коли положення збігається. З боку камери нічого з цього не видно – ви просто вказуєте сервоприводу, куди рухатись.

3.16.1. Сигнал ШІМ

Сервопривід отримує своє задане значення як сигнал ШІМ із фіксованою частотою кадрів 50 Гц, де ширина імпульсу вибирає положення:

  • Імпульс 1,0 мс переміщує вал на один кінець його ходу.

  • Імпульс 1,5 мс зупиняє вал у центрі.

  • Імпульс 2,0 мс переміщує вал на інший кінець.

Будь-яке значення між ними відповідає проміжному положенню.

Three rows of square-wave traces stacked vertically. Each row shows one 20 ms period of a 50 Hz PWM with a narrow high pulse at the start: 1.0 ms in the top row, 1.5 ms in the middle, 2.0 ms in the bottom.

Кадр ШІМ сервопривода становить 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)