3.16. Sterowanie serwomechanizmem

Hobbystyczne (RC) serwo to mały silnik z przekładnią w szczelnej obudowie z wbudowanym sterowaniem położeniem w pętli zamkniętej. Wewnątrz obudowy znajduje się silnik DC, przekładnia redukcyjna, potencjometr połączony z wałem wyjściowym oraz mała płytka sterownika, która porównuje odczyt potencjometru z wartością zadaną przychodzącą z zewnątrz. Sterownik napędza silnik w kierunku, który zmniejsza błąd, i zatrzymuje go, gdy położenie się zgadza. Z punktu widzenia kamery nic z tego nie jest widoczne – po prostu mówisz serwu, dokąd ma się ustawić.

3.16.1. Sygnał PWM

Serwo przyjmuje wartość zadaną jako sygnał PWM o stałej częstotliwości ramki 50 Hz, gdzie szerokość impulsu wybiera położenie:

  • Impuls 1,0 ms ustawia wał na jednym krańcu jego ruchu.

  • Impuls 1,5 ms ustawia wał w pozycji środkowej.

  • Impuls 2,0 ms ustawia wał na drugim krańcu.

Wszystko pomiędzy odwzorowuje położenie pośrednie.

Trzy rzędy przebiegów prostokątnych ułożone pionowo. Każdy rząd pokazuje jeden okres 20 ms sygnału PWM 50 Hz z wąskim impulsem wysokim na początku: 1,0 ms w górnym rzędzie, 1,5 ms w środkowym, 2,0 ms w dolnym.

Ramka PWM serwa ma długość 20 ms; szerokość impulsu (1,0 – 2,0 ms) wybiera położenie.

W przeciwieństwie do diod LED i silników, serwo nie uśrednia sygnału PWM. Samą komendą jest szerokość impulsu: wewnętrzna logika serwa mierzy każdy impuls, odpowiednio ustawia cel i napędza silnik, aż wyjście się dopasuje. Współczynnik wypełnienia jako ułamek (między 5 % a 10 % w całym zakresie) jest tu uboczny – liczy się bezwzględna szerokość impulsu, którą oprogramowanie ma sterować.

3.16.2. Okablowanie

Hobbystyczne serwa używają trzyprzewodowego złącza:

  • Zasilanie (zwykle czerwony): własne zasilanie serwa, zazwyczaj od 4,8 V do 6 V. Nie zasilaj serwa z szyny 3,3 V kamery – nie jest ona w stanie dostarczyć prądu utyku, a napięcie szyny zapadnie się (brown out).

  • Masa (zwykle czarny lub brązowy): droga powrotna dla zasilania serwa, połączona z masą kamery, dzięki czemu sygnał ma też wspólny punkt odniesienia.

  • Sygnał (zwykle biały, żółty lub pomarańczowy): linia PWM z pinu GPIO kamery.

3.16.3. Kod

Metoda duty_u16() zadziałałaby, ale ustawia ona wypełnienie jako ułamek okresu – co jest niewygodne dla sygnału, w którym liczy się bezwzględna szerokość impulsu, a okres jest stały. Metoda duty_ns() ustawia szerokość impulsu bezpośrednio w nanosekundach:

from machine import PWM, Pin

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

Nośna ma 50 Hz (okres 20 ms); czas stanu wysokiego w każdym cyklu wynosi dokładnie 1500 µs. Mały pomocnik czyni odwzorowanie położenia na impuls jawnym:

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

Powolny przebieg po całym zakresie:

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)

Zakres 1,0 – 2,0 ms jest standardem, ale wiele serw akceptuje szerszy zakres (często od 500 µs do 2500 µs) dla pełnego ruchu. Karta katalogowa serwa podaje dokładne granice szerokości impulsu; wartości spoza tego zakresu mogą uderzać silnikiem w jego mechaniczne ograniczniki.

Dla serwa o niestandardowym zakresie przenieś granice do stałych i sparametryzuj odwzorowanie:

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)