3.16. Kontrol servo

Servo hobi (RC) adalah motor bergigi kecil dalam casing tertutup dengan kontrol posisi loop tertutup yang sudah terpasang. Di dalam casing terdapat motor DC, gearbox reduksi, potensiometer yang terhubung ke poros keluaran, dan papan driver kecil yang membandingkan pembacaan pot dengan setpoint yang masuk dari luar. Driver menjalankan motor ke arah mana pun yang mengurangi kesalahan, dan berhenti ketika posisi cocok. Dari sisi kamera, semua itu tidak terlihat -- Anda hanya memberi tahu servo ke mana harus pergi.

3.16.1. Sinyal PWM

Servo mengambil setpoint-nya sebagai sinyal PWM pada laju bingkai tetap 50 Hz, di mana lebar pulsa memilih posisi:

  • Pulsa 1,0 ms menggerakkan poros ke satu ujung perjalanannya.

  • Pulsa 1,5 ms memarkir poros di tengah.

  • Pulsa 2,0 ms menggerakkan poros ke ujung lainnya.

Apa pun di antaranya dipetakan ke posisi perantara.

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.

Bingkai PWM servo adalah 20 ms; lebar pulsa (1,0 -- 2,0 ms) memilih posisi.

Berbeda dengan LED dan motor, servo tidak merata-ratakan PWM. Lebar pulsa itu sendiri adalah perintah: logika internal servo mengukur setiap pulsa, mengatur target sesuai, dan menjalankan motor hingga keluaran cocok. Duty cycle sebagai fraksi (antara 5% dan 10% di seluruh rentang) bersifat insidental -- yang penting adalah lebar pulsa absolut, itulah yang perlu dikontrol oleh perangkat lunak.

3.16.2. Pengkabelan

Servo hobi menggunakan konektor tiga kabel:

  • Daya (umumnya merah): suplai servo sendiri, biasanya 4,8 V hingga 6 V. Jangan memberi daya servo dari rel 3,3 V kamera -- tidak dapat menyuplai arus stall, dan rel akan turun tegangan.

  • Ground (umumnya hitam atau coklat): jalur kembali untuk daya servo, dihubungkan ke ground kamera agar sinyal juga memiliki referensi bersama.

  • Sinyal (umumnya putih, kuning, atau oranye): jalur PWM dari GPIO kamera.

3.16.3. Kode

duty_u16() akan berfungsi, tetapi ia mengatur duty sebagai fraksi dari periode -- tidak praktis untuk sinyal di mana lebar pulsa absolut yang penting dan periode sudah tetap. duty_ns() mengatur lebar pulsa langsung dalam nanodetik:

from machine import PWM, Pin

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

Pembawanya adalah 50 Hz (periode 20 ms); waktu tinggi pada setiap siklus tepat 1500 µs. Helper kecil membuat pemetaan posisi-ke-pulsa menjadi eksplisit:

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

Sapuan lambat di seluruh rentang:

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)

Rentang 1,0 -- 2,0 ms adalah standar, tetapi banyak servo menerima rentang yang lebih lebar (sering 500 µs hingga 2500 µs) untuk perjalanan penuh. Lembar data servo mencantumkan batas lebar pulsa yang tepat; angka di luar rentang tersebut dapat membenturkan motor ke pemberhenti mekanisnya.

Untuk servo dengan rentang non-standar, angkat batas ke dalam konstanta dan parameterisasi pemetaannya:

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)