3.16. Upravljanje servom

Hobi (RC) servo je mali motor s prijenosom u zatvorenom kućištu s ugrađenom regulacijom položaja zatvorenom petljom. Unutar kućišta nalaze se istosmjerni motor, reduktorski prijenos, potenciometar spojen na izlaznu osovinu i mala upravljačka pločica koja uspoređuje očitanje potenciometra sa zadanom vrijednošću koja dolazi izvana. Upravljač pokreće motor u onom smjeru koji smanjuje pogrešku i zaustavlja se kada se položaj podudara. Sa strane kamere ništa od toga nije vidljivo – jednostavno kažete servu kamo da ide.

3.16.1. PWM signal

Servo prima svoju zadanu vrijednost kao PWM signal pri fiksnoj učestalosti sličica od 50 Hz, gdje širina impulsa bira položaj:

  • Impuls od 1,0 ms pomiče osovinu na jedan kraj njezina hoda.

  • Impuls od 1,5 ms parkira osovinu u središtu.

  • Impuls od 2,0 ms pomiče osovinu na drugi kraj.

Bilo što između preslikava se na srednji položaj.

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 sličica serva traje 20 ms; širina impulsa (1,0 – 2,0 ms) bira položaj.

Za razliku od LED dioda i motora, servo ne usrednjava PWM. Sama širina impulsa je naredba: interna logika serva mjeri svaki impuls, postavlja svoj cilj u skladu s tim i pokreće motor dok se izlaz ne podudari. Radni ciklus kao udio (između 5 % i 10 % preko cijelog raspona) je sporedan – bitna je apsolutna širina impulsa, što je ono što softver treba kontrolirati.

3.16.2. Ožičenje

Hobi servi koriste tropolni priključak:

  • Napajanje (obično crveno): vlastito napajanje serva, tipično 4,8 V do 6 V. Ne napajajte servo iz 3,3 V razine kamere – ona ne može isporučiti struju zastoja, a razina će pasti.

  • Uzemljenje (obično crno ili smeđe): povratni put za napajanje serva, vezan na uzemljenje kamere tako da signal također ima zajedničku referencu.

  • Signal (obično bijelo, žuto ili narančasto): PWM linija s GPIO-a kamere.

3.16.3. Kod

duty_u16() bi radilo, ali postavlja radni ciklus kao udio razdoblja – nezgodno za signal kod kojeg je bitna apsolutna širina impulsa, a razdoblje je fiksno. duty_ns() postavlja širinu impulsa izravno u nanosekundama:

from machine import PWM, Pin

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

Nosivi signal je 50 Hz (razdoblje od 20 ms); visoko vrijeme u svakom ciklusu je točno 1500 µs. Mala pomoćna funkcija čini preslikavanje položaja u impuls eksplicitnim:

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

Sporo pomicanje preko raspona:

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)

Raspon 1,0 – 2,0 ms je standard, ali mnogi servi prihvaćaju širi raspon (često 500 µs do 2500 µs) za puni hod. Podatkovni list serva navodi točne granice širine impulsa; brojevi izvan tog raspona mogu udariti motor u njegove mehaničke graničnike.

Za servo s nestandardnim rasponom, podignite granice u konstante i parametrizirajte preslikavanje:

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)