3.16. Řízení serva

Hobby (RC) servo je malý motor s převodovkou v utěsněném pouzdře se zabudovaným řízením polohy s uzavřenou smyčkou. Uvnitř pouzdra je stejnosměrný motor, redukční převodovka, potenciometr připojený k výstupní hřídeli a malá budicí deska, která porovnává hodnotu potenciometru s žádanou hodnotou přicházející zvenčí. Budič roztáčí motor tím směrem, který zmenšuje odchylku, a zastaví se, když poloha odpovídá. Z pohledu kamery z toho nic vidět není – prostě servu řeknete, kam se má nastavit.

3.16.1. Signál PWM

Servo přijímá svou žádanou hodnotu jako PWM signál s pevnou snímkovou frekvencí 50 Hz, kde šířka pulzu volí polohu:

  • Pulz 1,0 ms nastaví hřídel na jeden konec dráhy pohybu.

  • Pulz 1,5 ms zaparkuje hřídel ve středu.

  • Pulz 2,0 ms nastaví hřídel na druhý konec.

Cokoli mezi tím se mapuje na mezilehlou polohu.

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.

PWM rámec serva je dlouhý 20 ms; šířka pulzu (1,0 – 2,0 ms) volí polohu.

Na rozdíl od LED a motorů servo PWM neprůměruje. Samotná šířka pulzu je povelem: vnitřní logika serva změří každý pulz, podle toho nastaví svůj cíl a roztáčí motor, dokud výstup neodpovídá. Střída jako poměr (mezi 5 % a 10 % v celém rozsahu) je vedlejší – záleží na absolutní šířce pulzu, kterou software potřebuje řídit.

3.16.2. Zapojení

Hobby serva používají třívodičový konektor:

  • Napájení (obvykle červený): vlastní napájení serva, typicky 4,8 V až 6 V. Nenapájejte servo z 3,3 V úrovně kamery – nezvládne dodat klidový (stall) proud a úroveň napětí by se propadla.

  • Zem (obvykle černý nebo hnědý): zpětná cesta pro napájení serva, spojená se zemí kamery, aby měl signál také společnou referenci.

  • Signál (obvykle bílý, žlutý nebo oranžový): PWM vodič z GPIO kamery.

3.16.3. Kód

duty_u16() by fungovala, ale nastavuje střídu jako poměr k periodě – nešikovné pro signál, kde záleží na absolutní šířce pulzu a perioda je pevná. duty_ns() nastavuje šířku pulzu přímo v nanosekundách:

from machine import PWM, Pin

servo = PWM(Pin("P7"), freq=50, duty_ns=1_500_000)  # centre

Nosná je 50 Hz (perioda 20 ms); doba vysoké úrovně v každém cyklu je přesně 1500 µs. Malá pomocná funkce zpřehlední mapování polohy na pulz:

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

Pomalý přejezd celým rozsahem:

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)

Rozsah 1,0 – 2,0 ms je standardem, ale mnoho serv přijímá pro plný rozsah pohybu širší rozmezí (často 500 µs až 2500 µs). Katalogový list serva uvádí přesné meze šířky pulzu; hodnoty mimo tento rozsah mohou motor narazit do mechanických dorazů.

U serva s nestandardním rozsahem vyzdvihněte meze do konstant a parametrizujte mapování:

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)