A szervomotorokat igen széles körben használják a robotikában, különböző vezérlő és szabályzó rendszerekben, RC modellekben, elsősorban pozicionálási feladatokra. A szervo egy speciális motor, tengelye a hagyományos motorokkal szemben nem folyamatos, állandó vagy változtatható fordulatszámú forgást végez, hanem adott szöggel elfordul, és a tengelyére szerelt kar helyzetét változtatja meg. A kar, illetve a tengely által megtett elfordulást, illetve az elfordulás szögét egy impulzussorozattal határozhatjuk meg. A kar addig marad az adott pozícióban, amíg az impulzussorozat meg nem szűnik.

Ebben a leírásban azt fogom bemutatni, hogy egy kisméretű un. microszervo hogyan programozható és működtethető egy Raspberry Pi 3B+ segítségével.

A választott szervo típus a Tower Pro gyártmányú SG92R. A kis motor a népszerű SG90 9g változat utódja, kedvezőbb paraméterekkel illetve megerősített mechanikai tulajdonságokkal.

A szervo főbb paraméterei (SG92R):

  • Tömeg: 9g
  • Méretek: 23×12.2x27mm
  • Fogaskerekek anyaga: szénszállal erősített műanyag
  • Működési sebesség: 0.1sec/60fok (4.8V)
  • Tartozékok: működtető kar és csavarok

Működtetés:

A szervo működtetését a gyakorlatban úgy valósíthatod meg, hogy vezérlő bemenetére egy un. változtatható kitöltési tényezőjű (dutycycle) impulzussorozatot küldesz a Raspberry Pi megfelelő kimenetéről. Ezt a vezérlési módot PWM-nek, azaz impulzus-szélesség modulációnak hívjuk. A megoldás lényege az, hogy olyan állandó periódusidejű (frekvenciájú) jeleket állítunk elő, ahol a szabályozás a jel kitöltési tényezőjének változtatásával történik. Néhány különböző kitöltési tényezőjű PWM jelet láthatsz a következő ábrán:

 

Impulzussorozatok tulajdonságai

A kitöltési tényező az impulzusszélesség (azaz a bekapcsolt állapot ideje) és a periódusidő hányadosa. Ha százalákosan akarjuk megadni, akkor a hányadost még meg kell szorozni 100-al.

kitöltési tényező = impulzusszélesség/periódusidő

Ha a kitöltési tényezőt százalékosan akarjuk megadni, akkor a hányadost még meg kell szorozni 100-zal:

kitöltési tényező [%] = 100 * impulzusszélesség/periódusidő

Az SG92R szervo karja 90 fokos elfordulást végezhet mindkét irányba, azaz a teljes elfordulás szöge 180 fok. A un. semleges helyzet az a pont, amelyből a tengely az óramutató járásával egyező, illetve ellenkező irányba is elmozdulhat. A szervo minden 20ms-os időközönként új impulzust vár, ami meghatározza az elfordulási szögét. Egy 1,5ms-os impulzus a szervot a 90 fokos pozícióba forgatja, amit semleges pozíciónak hívunk. Az 1ms-os impulzus 0 fokba, a 2ms-os impulzus pedig 180 fokos pozícióba forgatja a szervo tengelyét, illetve a rá szerelt kart. A pozícionáló impulzusoknak ismétlődniük kell, hogy a szervo tengelye stabilan tartsa a felvett pozíciót, akár külső erő ellenében is.

Bekötés:

A legtöbb mikrovezérlőn illetve egykártyás számítógépen találsz PWM kimenetet. A Raspberry Pi 3B+ két hardveres illetve több szoftveres kimenettel rendelkezik. Az alábbi példában a PI első PWM csatornáját használtam (GPIO 18 / 12) a microservo vezérlésére, a további GPIO bemenetek három nyomógomb lekezelését oldják meg, ezek szerepére a második mintaprogram ismertetésénél térek ki. ( A Pi másik „fizikai” PWM kimenete a GPIO 13 / 33)

A szervó bekötése

A bekötésnél két alapvető biztonsági szempontra kell figyelemmel lenned! Ahogy a bekötési ábrán is látszik, a servo tápfeszültség ellátása a Pi 5V-os GPIO tüskéjéről történik, a nyomógombok 3,3V-ot kapnak. Ha erre a pontra 5V-ot kötsz, az a Pi tönkremeneteléhez vezethet!!

A másik szem előtt tartandó szempont a servo teljesítmény igénye. A mintakapcsolásban alkalmazott SG92R szervo csatlakoztatható a Pi 5V-os GPIO tüskéjére, de ebben az esetben biztosítani kell, hogy az alkalmazott tápegység képes legyen a megfelelő áramerősség szolgáltatására, mert alacsony teljesítményű tápegység használata esetén a szervo működésekor a Pi lefagyhat, vagy újraindul.
A teljes biztonságot adó megoldás a szervo független 5V-os tápegységről történő működtetése, ebben az esetben a táp negatív potenciálú pontját a GPIO port tetszőleges GND tüskéjével kell összekötnöd.

Vezérlés

Az előzőekben megbeszéltük, hogy a servo számára az impulzusokat ismételnünk kell, méghozzá 20ms-os gyakorisággal. Ez tudva, valamint, hogy a periódusidő a frekvencia reciproka ez 50Hz-es frekvenciát jelent. Így python programunkban a PWM modul meghívását ezzel az értékkel kell megtennünk.

	p = GPIO:PWM(12,50)
	p.start (dc)

Ezek után be kell állítani a kitöltési tényezőt (dutycycle), amit az impulzus időtartamának és a szükséges impulzus szélességének az aránya határoz meg. 20ms-os periódusidővel a szükséges impulzusok időtartamát 0,5ms, 1,5ms, illetve 2,5ms-nak véve a következőképpen számolhatunk:

  • dc1 = 0,5 / 20 x 100 = 2,5%
  • dc2 = 1,5 / 20 x 100 = 2,5%
  • dc3 = 2,5 / 20 x 100 = 2,5%

A kitöltési tényező beállítását az alábbi paranccsal tehetjük meg:

p.ChangeDutyCycle (dc)

Az impulzus sorozatot az alábbi parancs állítja le:

p.stop ()

Példaprogramok:

Az előzőekben elmondottakhoz két példaprogram, az első ciklikusan 0 – 90 – 180 fok között változtatja a szervo pozícióját, míg a másik három nyomógomb segítségével állítja be a kívánt szögelfordulást.
A programok alapján tetszőleges robot, vagy RC modell-vezérlő alkalmazást készíthetsz.

1. példaprogram:

# micro-servo teszt-1 program
# szükséges library-k importálása
import RPi.GPIO as GPIO
import time
#GPIO számozás beállítása
GPIO.setmode (GPIO.BOARD)
#12-es tüske beállítása kimenetnek 
GPIO.setup (12, GPIO.OUT)
#PWM frekvencia beállít
p = GPIO.PWM(12,50)
#alaphelyzet
p.start(0)
dc1 = 7.5
dc2 = 2.5
dc3 = 12.5
try:
    while True:
        p.ChangeDutyCycle(dc1) #90 fok
        time.sleep(1)
        p.ChangeDutyCycle(dc2) #0 fok
        time.sleep(1)
        p.ChangeDutyCycle(dc3) #180 fok
        time.sleep(1)
except KeyboardInterrupt:
    p.stop()
    GPIO.cleanup()
 

2. példaprogram:

   
# micro-servo teszt-2 program, szervo vezérlése gombokkal
# szükséges library-k importálása
import RPi.GPIO as GPIO
import time
#GPIO számozás beállítása
GPIO.setmode (GPIO.BOARD)
#12-es tüske beállítása kimenetnek
GPIO.setup (12, GPIO.OUT)
# 7,10,11-es tüske beállítása bemenetnek
GPIO.setup (7, GPIO.IN)
GPIO.setup (10, GPIO.IN)
GPIO.setup (11, GPIO.IN)
#PWM frekvencia beállít
p = GPIO.PWM(12,50)
#alaphelyzet
p.start(0)
try:
    while True:
        #gomb 1
        if GPIO.input(10) == 1:
            p.ChangeDutyCycle(7.5)
            print("90 fok")
            time.sleep(1)
        #gomb 2
        if GPIO.input(11) == 1:
            p.ChangeDutyCycle(2.5)
            print("0 fok")
            time.sleep(1)
        #gomb 3
        if GPIO.input(7) == 1:
            p.ChangeDutyCycle(12.5)
            print("180 fok")
            time.sleep(1)
except KeyboardInterrupt:
        pass
p.stop()
GPIO.cleanup()

A két forráskód letölthető:

A cikkben használt szervó megvásárolható a MálnaPC Webshopjában!