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