3.16. Servon ohjaus¶
Harrastelija- eli RC-servo on pieni hammaspyörävälitteinen moottori suljetussa kotelossa, jossa on sisäänrakennettu suljetun silmukan asennon ohjaus. Kotelon sisällä on tasavirtamoottori, alennusvaihteisto, lähtöakseliin kytketty potentiometri ja pieni ohjainlevy, joka vertaa potentiometrin lukemaa ulkopuolelta tulevaan asetusarvoon. Ohjain ajaa moottoria siihen suuntaan, joka pienentää virhettä, ja pysähtyy kun asento vastaa asetusta. Kameran näkökulmasta mikään tästä ei näy – kerrot vain servolle minne mennä.
3.16.1. PWM-signaali¶
Servo ottaa asetusarvonsa PWM-signaalina kiinteällä 50 Hz:n kehystaajuudella, jossa pulssin leveys valitsee asennon:
1,0 ms:n pulssi ajaa akselin liikealueensa toiseen ääripäähän.
1,5 ms:n pulssi pysäköi akselin keskelle.
2,0 ms:n pulssi ajaa akselin toiseen ääripäähän.
Mikä tahansa siltä väliltä kuvautuu välissä olevaan asentoon.
Servon PWM-kehys on 20 ms pitkä; pulssin leveys (1,0 – 2,0 ms) valitsee asennon.¶
Toisin kuin LEDit ja moottorit, servo ei keskiarvoista PWM:ää. Pulssin leveys itsessään on komento: servon sisäinen logiikka mittaa kunkin pulssin, asettaa kohteensa sen mukaan ja ajaa moottoria kunnes lähtö vastaa asetusta. Pulssisuhde murto-osana (5 %:n ja 10 %:n välillä koko alueella) on satunnaista – merkitystä on absoluuttisella pulssin leveydellä, jota ohjelmiston on ohjattava.
3.16.2. Kytkentä¶
Harrastelijaservot käyttävät kolmijohtimista liitintä:
Käyttöjännite (yleensä punainen): servon oma syöttö, tyypillisesti 4,8 V – 6 V. Älä syötä servoa kameran 3,3 V:n jännitetasosta – se ei pysty syöttämään jumitusvirtaa, ja jännitetaso romahtaa.
Maa (yleensä musta tai ruskea): servon käyttöjännitteen paluureitti, sidottuna kameran maahan, jotta signaalilla on myös yhteinen vertailutaso.
Signaali (yleensä valkoinen, keltainen tai oranssi): PWM-linja kameran GPIO:sta.
3.16.3. Koodi¶
duty_u16() toimisi, mutta se asettaa pulssisuhteen jakson murto-osana – hankalaa signaalille, jossa merkitystä on absoluuttisella pulssin leveydellä ja jakso on kiinteä. duty_ns() asettaa pulssin leveyden suoraan nanosekunteina:
from machine import PWM, Pin
servo = PWM(Pin("P7"), freq=50, duty_ns=1_500_000) # centre
Kantoaalto on 50 Hz (20 ms:n jakso); korkea aika kullakin jaksolla on tarkalleen 1500 µs. Pieni apufunktio tekee asento-pulssi-kuvauksen näkyväksi:
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
Hidas pyyhkäisy koko alueen yli:
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:n alue on vakio, mutta monet servot hyväksyvät leveämmän alueen (usein 500 µs – 2500 µs) täyttä liikealuetta varten. Servon datalehti luettelee tarkat pulssin leveyden rajat; tuon alueen ulkopuoliset arvot voivat lyödä moottorin mekaanisia rajoittimiaan vasten.
Servolle, jolla on epästandardi alue, nosta rajat vakioiksi ja parametroi kuvaus:
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)