Raspberry Pi

44) Ovládání serva

Servo se používá pro natočení nějaké mechanické části na přesně zadaný úhel.
Na rozdíl od krokového motoru, který se také umí natáčet na přesně zadaný úhel, nepotřebuje servo žádnou paměť aktuální pozice.

Pro pokusy jsem použil levné modelářské servo s označením 9g.

Hlavní částí tohoto serva je stejnosměrný elektromotor s převodovkou a řídící elektronikou. Přímo k ose serva je přidělaný potenciometr, který slouží jako zpětná vazba pro elektroniku. O vlastní řízení se stará obvod s označením AA51880.

Princip řízení je následující:

Po připojení napájecího napětí (hnědý vodič=GND; rudý vodič=+5V) se do zbývajícího vodiče (oranžový) posílají frekvencí 50 až 100Hz obdélníkové impulzy. Podle šířky těchto impulzů se osa serva natočí do patřičné polohy. Pracovní rozsah natočení je 180° (servo ale zvládá i trochu větší úhel na každou stranu). 

Při šířce impulzu 0,5ms se servo natočí do jedné krajní polohy, při šířce impulzu 2,5ms se osa přetočí o 180° - do druhé krajní polohy. Když je šířka impulzů 1,5ms, natočí se servo do střední polohy. 

Na frekvenci impulzů moc nezáleží. Důležitá je hlavně šířka pulzu. Při nízkých frekvencích se ale servo už pohybuje trhaně.


Připojení k RasPi

Modelářské servo pracuje s napětím mezi 3V a 5V.
Změřil jsem, že odběr jednoho serva je krátkodobě (když se pohybuje) až 200mA. 
Pokud máte novější variantu RasPi (s 512MB paměti) a silný napájecí zdroj, můžete připojit napájení serva na +5V na GPIO konektoru. Bezpečnější je ale použít zvláštní zdroj.
Mám vyzkoušeno (viz video níže), že přes 5V pin na GPIO konektoru je možné napájet 2 serva zároveň.
Je to ale opravdu na hranici: 550mA samotné RasPi + (2 x 200mA) serva = 950mA.
Vstupní pojistka v RasPi je 1100mA. Takže je tam rezerva nějakých slabých 150mA.

I když je servo napájené z 5V, je možné ho bez problémů řídit 3,3V impulzy, které jsou generované nějakým GPIO pinem.


Ovládání - varianta 1 (GPIO - PWM)

První způsob řízení, na který jsem pomyslel, bylo využití zabudované PWM funkce GPIO výstupů. 

Schéma:

 (Pro pokusy jsem používal 2 serva na sobě, která byla otočená o 90° - jedno jako horizontální a druhé jako vertikální ):

(Laser je tam jen kvůli tomu, aby bylo vidět na vzdálené zdi, kam serva míří.)

Popis:

Na GPIO výstupu se nastaví frekvence 50Hz a střída se přepočte tak, aby při krajních polohách byla délka trvání impulzu 0,5 a 2,5ms.

Pomocí trojčlenky jsem došel k následujícímu:

Při 50Hz trvá celá perioda signálu 20ms.
Abych získal impulz široký 0,5ms, musím nastavit střídu 2,5%.
Pro impulz široký 2,5ms je ta střída 12,5%.

Vzhledem k tomu, že je možné zadávat střídu jen v celých procentech, Bylo by pro výběr polohy možné využít jen celá čísla od 3 do 13 To je jen 11 pozic. Na ovládání stylem "Zavřeno" / "Otevřeno" to stačí, ale pokud by bylo třeba najíždět do mezipoloh, tak je to dost málo.

Zkusil jsem tedy změnit výpočet pro vyšší frekvenci (100Hz).
V tom případě trvá celá perioda 10ms.
0,5ms široký impulz se získá nastavením střídy na 5%.
Druhá krajní poloha (2,5ms široký impulz) se dosáhne nastavením střídy na 25%.

To už je trochu lepší přesnost - celý rozsah 180° se tímto rozdělí na 20 pozic.

Problém ale nastal se stabilitou. PWM na GPIO, které je řízené Pythonem je dost nestabilní, a proto i při dojezdu do požadované polohy servo strašně zakmitávalo (nedokázalo se rozhodnout, jestli už je ve správné poloze), takže tento způsob by byl v praxi nepoužitelný.

Program: servo-gpio-pwm.py

Video: servo-gpio-pwm.avi (Odkaz na YouTube)

na videu je vidět to zakmitávání při najíždění do cílové polohy

 


Ovládání - varianta 2 (ServoBlaster)

Druhý způsob řízení využívá modul ServoBlaster.
Připojení serv je stejné jako v předchozí variantě ovládání. Rozdíl je jen v softwéru.

Nejdříve bylo nutné ten modul ServoBlaster nainstalovat.
Postupoval jsem podle tohoto návodu: http://www.novitiate.co.uk/?p=72

Přes terminál jsem nainstaloval "git"

sudo apt-get install git

 

Pak jsem zkopíroval soubory PiBits z GitHubu do adresáře /home/

git clone git://github.com/richardghirst/PiBits.git

 

Další operace jsem pak nechal vykonat vlastním pythonovským skriptem, který je součástí ovládacího programu pro serva:

Jde o to, že se pomocí shellovského příkazu insmod musí nejdřív  nainstalovat modul servoblaster. Po instalaci se mu automaticky přiřadí nějaké pořadové číslo.
To číslo se zjistí ze souboru  /proc/devices - (na jedné z řádek je název zařízení "servoblaster" a před ním je to pořadové číslo)

Pak se pomocí příkazu mknod vytvoří, za použití toho pořadového čísla, v adresáři /dev/ zařízení "servoblaster" 

Tady je část pythonovského programu, která kontroluje, jestli už je servoblaster nainstalovaný.
Pokud není, vykoná výše zmíněné shellovské příkazy insmod a mknod.
Test nainstalování se provádí jako test existence souboru /dev/servoblaster/. Pokud není modul servoblaster nainstalovaný, tak ten soubor neexistuje a test skončí s odchytitelnou I/O chybou.
Když soubor dev/servoblaster/ existuje, je pravděpodobné, že už  je modul nainstalovaný. V tom případě už není třeba instalovat znova.

Při vypnutí RasPi se modul servoblaster automaticky odinstalovává, proto je třeba kontrolovat stav nainstalování při každém spuštění programu.

.
.
.
# instalace ServoBlasteru
try:              # pokus o otevreni souboru /dev/servoblaster
  with open("/dev/servoblaster"): pass

except IOError:   # pokud soubor neexistuje, znamena to, ze pravdepodobne neni nainstalovany modul servoblaster 
  print "Servoblaster je treba nainstalovat"
  print " ... INSTALUJI ..."

  prikaz = "sudo insmod /home/pi/PiBits/ServoBlaster/servoblaster.ko"
  os.system(prikaz)           # vykonani prikazu insmod....

  with open("/proc/devices") as f:       # zjisteni cisla servoblasteru ze souboru /proc/devices
    for radka in f :
      if (radka.find("servoblaster")>0):
        mezera = radka.find(" ")    
        cislo = radka[:mezera]
        print "cislo servoblasteru je :" + str(cislo)

  prikaz = "sudo mknod -m 0666 /dev/servoblaster c " + str(cislo) + " 0"
  os.system(prikaz)          # vykonani prikazu mknod ....



print "Servoblaster je nainstalovany."
.
.
.

Program: servo-blaster.py

Video: servoblaster1.avi (Odkaz na YouTube)

 tady je už vidět stabilní najíždění do cílové polohy

 


Ovládání - varianta 3 (obvod PCA9685 - PWM driver ovládaný přes I2C)

V poslední variantě jsem využil externí obvod PCA9685, který je možné pomocí I2C komunikace nastavit tak, aby generoval na výstupech obdélníkový signál s přesně danou šířkou pulzů. Protože je obvod po nastavení úplně nezávislý na RasPi, je generovaný signál velice stabilní.

Další výhodou tohoto způsobu řízení je možnost velice jemně nastavit šířku pulzů. 
Při 50Hz je pro plný rozsah natočení hřídele možné použít rozsah čísel 103 až 512. - to je 410 kroků.
To je asi dvojnásobná přesnost najíždění v porovnání se servoblasterem.

Řízení serva podobným způsobem je vysvětleno například na těchto stránkách: http://learn.adafruit.com/.....

 

Schéma:

Program: servo-pca.py

Video: servo-pca.avi (Odkaz na YouTube)


 


úvodní strana webu AstroMiK.org

poslední úprava stránky 22.8.2013