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.

Drei Reihen von Rechteckwellen-Verläufen vertikal gestapelt. Jede Reihe zeigt eine 20-ms-Periode einer 50-Hz-PWM mit einem schmalen High-Puls am Anfang: 1,0 ms in der oberen Reihe, 1,5 ms in der mittleren, 2,0 ms in der unteren.

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)