3.16. Servo kontrolü

Bir hobi (RC) servosu, kapalı çevrim konum kontrolü yerleşik olan, mühürlü bir kasa içindeki küçük dişlili bir motordur. Kasanın içinde bir DC motor, bir redüksiyon dişli kutusu, çıkış miline bağlı bir potansiyometre ve potansiyometrenin okumasını dışarıdan gelen bir ayar noktasıyla karşılaştıran küçük bir sürücü kartı bulunur. Sürücü, motoru hatayı azaltan hangi yön ise o yönde çalıştırır ve konum eşleştiğinde durur. Kameranın tarafından bunların hiçbiri görünmez – yalnızca servoya nereye gideceğini söylersiniz.

3.16.1. PWM sinyali

Bir servo, ayar noktasını sabit bir 50 Hz çerçeve hızında bir PWM sinyali olarak alır; burada darbe genişliği konumu seçer:

  • 1.0 ms’lik bir darbe, mili hareket aralığının bir ucuna sürer.

  • 1.5 ms’lik bir darbe, mili merkeze park eder.

  • 2.0 ms’lik bir darbe, mili diğer uca sürer.

Aradaki herhangi bir şey, bir ara konuma eşlenir.

Dikey olarak üst üste dizilmiş üç sıra kare dalga izi. Her sıra, başlangıçta dar bir yüksek darbe bulunan bir 50 Hz PWM'in 20 ms'lik bir periyodunu gösterir: üst sırada 1.0 ms, ortada 1.5 ms, alt sırada 2.0 ms.

Servonun PWM çerçevesi 20 ms uzunluğundadır; darbe genişliği (1.0 – 2.0 ms) konumu seçer.

LED’lerin ve motorların aksine, servo PWM’in ortalamasını almaz. Darbe genişliğinin kendisi komuttur: servonun dahili mantığı her darbeyi ölçer, hedefini buna göre ayarlar ve çıkış eşleşene kadar motoru çalıştırır. Bir kesir olarak görev döngüsü (tüm aralık boyunca %5 ile %10 arasında) ikincildir – önemli olan mutlak darbe genişliğidir, ki bu da yazılımın kontrol etmesi gereken şeydir.

3.16.2. Kablolama

Hobi servoları üç telli bir konnektör kullanır:

  • Güç (genellikle kırmızı): servonun kendi beslemesi, tipik olarak 4.8 V ile 6 V arası. Servoyu kameranın 3.3 V rayından beslemeyin – bu ray durma (stall) akımını sağlayamaz ve ray gerilimi düşer.

  • Toprak (genellikle siyah veya kahverengi): servonun gücünün dönüş yolu, sinyalin de paylaşılan bir referansa sahip olması için kameranın toprağına bağlanır.

  • Sinyal (genellikle beyaz, sarı veya turuncu): kameranın GPIO’sundan gelen PWM hattı.

3.16.3. Kod

duty_u16() işe yarardı, ancak görev döngüsünü periyodun bir kesri olarak ayarlar – önemli olanın mutlak darbe genişliği olduğu ve periyodun sabit olduğu bir sinyal için kullanışsızdır. duty_ns(), darbe genişliğini doğrudan nanosaniye cinsinden ayarlar:

from machine import PWM, Pin

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

Taşıyıcı 50 Hz’dir (20 ms periyot); her çevrimdeki yüksek süre tam olarak 1500 µs’dir. Küçük bir yardımcı, konum-darbe eşlemesini açık hâle getirir:

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

Aralık boyunca yavaş bir tarama:

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)

1.0 – 2.0 ms aralığı standarttır, ancak birçok servo tam hareket için daha geniş bir aralığı (genellikle 500 µs ile 2500 µs) kabul eder. Servonun veri sayfası tam darbe genişliği sınırlarını listeler; bu aralığın dışındaki değerler motoru mekanik durdurucularına çarptırabilir.

Standart olmayan aralığa sahip bir servo için sınırları sabitlere yükseltin ve eşlemeyi parametreleyin:

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)