3.16. Servo-Steuerung¶
Ein Hobby-Servo (RC) ist ein kleiner Getriebemotor in einem versiegelten Gehäuse mit eingebauter Positionsregelung im geschlossenen Regelkreis. Im Gehäuse sitzen ein Gleichstrommotor, ein Untersetzungsgetriebe, ein mit der Ausgangswelle verbundenes Potentiometer und eine kleine Treiberplatine, die den Messwert des Potis mit einem von außen kommenden Sollwert vergleicht. Der Treiber lässt den Motor in der Richtung laufen, die den Fehler verringert, und stoppt, wenn die Position übereinstimmt. Von der Kameraseite aus ist nichts davon sichtbar – man sagt dem Servo einfach, wohin er fahren soll.
3.16.1. Das PWM-Signal¶
Ein Servo erhält seinen Sollwert als PWM-Signal mit einer festen Frame-Rate von 50 Hz, wobei die Pulsbreite die Position auswählt:
Ein Puls von 1,0 ms treibt die Welle an ein Ende ihres Verfahrwegs.
Ein Puls von 1,5 ms parkt die Welle in der Mitte.
Ein Puls von 2,0 ms treibt die Welle an das andere Ende.
Alles dazwischen wird auf eine Zwischenposition abgebildet.
Der PWM-Frame des Servos ist 20 ms lang; die Pulsbreite (1,0 – 2,0 ms) wählt die Position.¶
Anders als LEDs und Motoren mittelt der Servo die PWM nicht. Die Pulsbreite selbst ist der Befehl: Die interne Logik des Servos misst jeden Puls, setzt entsprechend ihr Ziel und lässt den Motor laufen, bis der Ausgang übereinstimmt. Das Tastverhältnis als Bruchteil (zwischen 5 % und 10 % über den gesamten Bereich) ist nebensächlich – es kommt auf die absolute Pulsbreite an, und die ist es, die die Software steuern muss.
3.16.2. Verdrahtung¶
Hobby-Servos verwenden einen Stecker mit drei Adern:
Spannungsversorgung (üblicherweise rot): die eigene Versorgung des Servos, typischerweise 4,8 V bis 6 V. Versorgen Sie den Servo nicht aus der 3,3-V-Schiene der Kamera – sie kann den Anlaufstrom nicht liefern, und die Schiene würde einbrechen.
Masse (üblicherweise schwarz oder braun): der Rückleiter für die Versorgung des Servos, mit der Masse der Kamera verbunden, sodass auch das Signal einen gemeinsamen Bezug hat.
Signal (üblicherweise weiß, gelb oder orange): die PWM-Leitung vom GPIO der Kamera.
3.16.3. Code¶
duty_u16() würde funktionieren, setzt das Tastverhältnis aber als Bruchteil der Periode – unhandlich für ein Signal, bei dem die absolute Pulsbreite entscheidend ist und die Periode fest ist. duty_ns() setzt die Pulsbreite direkt in Nanosekunden:
from machine import PWM, Pin
servo = PWM(Pin("P7"), freq=50, duty_ns=1_500_000) # centre
Der Träger beträgt 50 Hz (20-ms-Periode); die High-Zeit jedes Zyklus ist genau 1500 µs. Eine kleine Hilfsfunktion macht die Abbildung von Position auf Puls explizit:
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
Ein langsamer Durchlauf über den Bereich:
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)
Der Bereich von 1,0 – 2,0 ms ist der Standard, aber viele Servos akzeptieren für den vollen Verfahrweg einen größeren Bereich (oft 500 µs bis 2500 µs). Das Datenblatt des Servos nennt die genauen Pulsbreiten-Grenzen; Werte außerhalb dieses Bereichs können den Motor in seine mechanischen Endanschläge schlagen.
Für einen Servo mit nicht standardmäßigem Bereich sollte man die Grenzen in Konstanten herausziehen und die Abbildung parametrisieren:
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)