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.
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)