Avtorja: Mag. Vladimir Mitrović, Robert Sedak
E-pošta: vmitrovic12@gmail.com
V tem nadaljevanju se bomo naučili kako povezati mali servo motor na razvojno ploščico Shield-B in kako jih s programi napisanimiv programskih jezikih Bascom-AVR in Arduino IDE krmiliti.
Servo motorji se precej razlikujejo od “običajnih” enosmernih elektromotorjev, s katerimi smo se ukvarjali do sedaj. Pravzaprav je DC motor samo eden od sestavnih delov vsakega servo motorja. Poleg njega je v ohišje vgrajen zobniški prenos (zaradi česar se os servo motorja vrti počasneje od osi pogonskega DC motorja) in ustrezno krmilno vezje. Sestavni deli tipičnega servo motorja so prikazani na sliki 13.
Ta vsebina je samo za naročnike
Slika hkrati prikazuje tudi kako servo motor vežemo na napajalno napetost. Nazivna napetost večine malih modelarskih servo motorjev znaša 5 V, poraba pa ni prevelika, zato jih lahko direktno povežemo na razvojno ploščo Shield-B in uporabimo isti vir, s katerim napajamo tudi Arduino Uno. No, servo motor ne bo deloval, če ga vežemo zgolj na napajalno napetost: da bi ga zavrteli, mu je potrebno na tretji priključek (rumene ali bele barve) trajno dovajati ustrezne krmilne impulze. Te impulzi se morajo ponavljati vsakih 20 ms (z drugimi besedami, impulzi morajo imeti frekvenco 50 Hz) in trajati med 700 in 2300 µs. Obnašanje motorja je odvisno prav od trajanja krmilnih impulzov.
Opomnimo še, da obstajata dve izvedbi servo motorja:
- servo motorji, katerih os se lahko trajno vrti v eni ali drugi smeri (takšni motorji so primerni za pogon robota) in
- servo motorji, katerih os se lahko zavrti samo za 180° (takšni motorji so primerni za postavljanje delov robota v želeni položaj, pa tudi za krmiljenje smeri njihovega gibanja).
Os prve izvedbe se bo vrtelav eni smeri, ko je trajanje krmilnih impulzov krajše in vnasprotni smeri, če je trajanje krmilnih impulzov daljše od 1500 µs. Motor se bo zaustavil, ko krmilni impulzi trajajo okoli 1500 µs. V ožjem področju okoli 1500 µs je mogoče krmiliti tudi hitrost vrtenja servo motorja, vendar motor hitro doseže maksimalno hitrost vrtenja, ki potem ni več odvisna od krajših ali daljših impulzov.
Mi se bomo ukvarjali z drugo izvedbo, kjer se os od srednjega položaja lahko zavrti za po 90° v obe smeri. Slika 14 zgoraj prikazuje, kako je obrat osi servo motorja Hitec HS-422 odvisen od trajanja krmilnih impulzov. Prikazana sta samo srednji in končni položaj, vendar je te servo motorje možno tudi zelo natančno krmiliti. Tako bodo npr. impulzi trajanja 1450 µs obrnili os samo malo “v levo” od srednjega položaja, impulzi trajanja 1400 µs še malo bolj v levo itd.
Slika 14 spodaj se nanaša na mali servo motor SG90. Opazili bomo, da se njegova osi vrti v nasprotni smeri od osi HS-422 motorja, pa tudi dovoljeni razpon trajanja impulzov je pri njemu nekaj manjši. Vedno je potrebno preveriti dokumentacijo uporabljenega motorja ali pa ga pazljivo pregledati znotraj kakšnega razpona se njegova os svobodno zavrti! Dovajanje prekratkih ali predolgih impulzov in tudi dovajanje impulzov, katerih frekvenca pomembno odstopa od nazivnih 50 Hz bo povzročila poskus postavljanja osi v nedovoljeni položaj preko omejilnika. Servo motor bo “zablokiral”, pri čemer se lahko poškodujejo njegovi zobniki!
Da bi se lahko zagotovila zanesljiva odvisnost položaja osi v odnosu na trajanje impulzov, se v servo motorje vgrajuje potenciometer, ki je povezan z osjo motorja (ta potenciometer ni viden na sliki 13). Drsnik potenciometra elektronskemu vezju v vsakem trenutku “javlja” položaj osi servo motorja, zato lahko naredi potrebne korekcije, takoj ko ugotovi, da položaj osi ne ustreza trajanju krmilnih impulzov.
Slika 15 prikazuje kako povezati dva servo motorja na razvojni sistem Shield-B, verzija v1.2. Povezovanje ne bi smelo predstavljati problem, ker so priključki na konektorjih obarvani z istimi barvami kot tudi priključki servo motorja (slika 16). Prvi servo motor, S1, vežemo na konektor J5, preko katerega motor dobi tudi napajalno napetost in krmilne impulze. Drugi servo motor, S2, vežemo na konektor S8 (ta konektor, kot tudi ostale komponente, ki so na shemi narisane z modro barvo, ne obstaja v osnovni izvedbi razvojnega sistema, v1.1, zato je na tej verziji na ploščico možno vezati samo en servo motor).
Ker je vsa potrebna “elektronika” vgrajena v sam servo motor, so krmilni priključki (SIG) na razvojnem sistemu Shield-B povezani direktno s priključki mikrokontrolerja. Dodali smo samo LED-ice D8 in D10, ki bodo svetile proporcionalno s širino krmilnih impulzov: tako bomo imeli vidno kontrolo impulzov, ki jih mikrokontroler posreduje servo motorjem.
- programska naloga: za vezje po shemi na sliki 15 napišite program, s katerim bomo s pomočjo potenciometrov RV1 in RV2 krmilili položaj servo motorjev S1 in S2.
Bascom-AVR rešitev (program Shield-B_5.bas)
Po uvodnih konfiguracijskih ukazih, ki se nanašajo na uporabljeni mikrokontroler in pogoje v katerih dela bomo dimenzionirali spremenljivki Rv1 in Rv2 in ustrezno konfigurirali A/D pretvornik:
Dim Rv1 As Word , Rv2 As Word
Config Adc = Single , Prescaler = Auto ,
Reference = Avcc
V spremenljivki bomo shranili prebrano napetost drsnika potenciometrov RV1 in RV1. Bascom-AVR ima določene rutine za krmiljenje do 10 servo motorjev. V konfiguracijskih ukazih definiramo koliko servo motorjev imamo in katere priključke mikrokontrolerja bomo uporabili za njihovo krmiljenje. V našem primeru imamo dva serva, ki ju krmilimo preko priključkov PB1 in PB2:
Config Servos = 2 , Servo1 = Portb.1 ,
Servo2 = Portb.2 , Reload = 7
Krmilna priključka PB1 in PB2 še moramo konfigurirati kot izhodna in omogočiti prekinitve (o prekinitvah bomo več povedali ob neki drugi priložnosti):
Config Portb.1 = Output
Config Portb.2 = Output
Enable Interrupts
Bascom-AVR bo definiral dve spremenljivki, Servo(1) in Servo(2), parameter Reload pa določa pogostost preverjanja njunih vsebin, oziroma, finost s katero lahko postavimo os servo motorja, pa tudi frekvenco krmilnih impulzov. Vrednost parametra Reload = 7 je izbrana s poskusom; z njo je frekvenca krmilnih impulzov blizu optimalnih 50 Hz, potreben razpon krmilnih impulzov (700 – 2300 µs) bomo dobili zvpisom vrednosti v razponu 70 – 230 v spremenljivki Servo(1) ali Servo(2).
V glavni programski zanki najprej beremo napetost na drsniku potenciometra RV1:
Do
Rv1 = Getadc(0)
Glede na položaj drsnika bo prebrana vrednostv razponu od 0-1023. Z množenjem s faktorjem 21/134 bomo ta razpon najprej zmanjšali na 0-160 in nato rezultatu dodali 70. Tako smo dobili število v razponu 70-230, ki ga vpišemo v spremenljivko Servo(1):
Rv1 = Rv1 * 21
Rv1 = Rv1 / 134
Servo(1) = 70 + Rv1 ‚70-230
Ostanek bo za nas naredila “nevidna” Bascom-AVR rutina, ki bo nastavila mikrokontroler tako, da bo na osnovi vpisane vrednosti proizvajal krmilne impulze širine 700-2300 µs.
Program za drugi servo motor je identičen; tudi tukaj beremo napetost na drsniku potenciometra RV2 in nato prebrano vrednost zmanjšamo v razpon 0-160:
Rv2 = Getadc(1)
Rv2 = Rv2 * 21
Rv2 = Rv2 / 134
Tukaj smo vpis v spremenljivko Servo(2) prekrojili na način da obrne os v nasprotni smeri:
Servo(2) = 230 – Rv2 ‚230-70
Loop
Arduino rešitev (program Shield-B_5.ino)
Arduino IDE razvojno okolje ima knjižnico pod imenom Servo, ki uporablja Timer1 in lahko sočasno krmili do 12 servo motorjev. Knjižnica Servo omogoča enostavno krmiljenje malih servo motorjev z definiranjem objekta in uporabo pripadajočih funkcij. Uporabili bomo dve funkciji: attach() za definiranje na kateri priključek je vezan servo motor, in funkcijo write()s pomočjo katere definiramo kot obrata servo motorja od 0 do 180 stopinj.
Program bomo začeli z navajanjem knjižnice, ki jo bomo uporabili:
include
Nato za vsak servo motor definiramo lastni objekt:
Servo S1;
Servo S2;
V funkciji setup() bomo za vsak objekt definirali priključek, ki ga uporablja. Ker smo servo motor 1 vezali na priključek 9, bomo objektu S1 pridružili ta priključek s pomočjo funkcije attach(). Za servo motor 2 bomo uporabili priključek 10:
void setup() {
S1.attach(9);
S2.attach(10);
}
V funkciji loop() najprej beremo napetost na drsniku potenciometra RV1:
void loop() {
int Rv1 = analogRead(A0);
Odvisno od položaja drsnika RV1 bo prebrana vrednostv razponu 0-1023. Zato je potrebno ta razpon pretvoriti v razpon 0-180 s pomočjo funkcije map():
Rv1 = map(Rv1, 0, 1023, 0, 180);
Sedaj nam še preostane pretvorjeno vrednost predati funkciji write() objekta S1 intako obrniti os servo motorja S1:
S1.write(Rv1);
Isti postopek ponovimo za drsnik Rv2 in servo motor S2, vendar bomo v tem primeru definirali vrtenje osi v drugi smeri prav tako z uporabo funkcije map():
int Rv2 = analogRead(A1);
Rv2 = map(Rv2, 0, 1023, 180, 0);
S2.write(Rv2);
Ker hitrost vrtenja servo motorja ni zelo velika, bomo na koncu funkcije loop() napravili 15 ms pavzo in tako dali servo motorju dovolj časa, da zaključi z zadanim obratom osi:
delay(15);
} // kraj loop()
Opombe:
Programe Shield-B_5.bas in Shield-B_5.ino lahko brezplačno dobite od uredništva revije Svet elektronike! Programi so bili napisani za dva servo motorja. Koliko močnostnih motorjev bomo lahko vezati na Shield-B je odvisno tudi od njihove porabe. Mikro servo motorji, kot SG90, pod obremenitvijo trošijo okoli 270 mA, neobremenjeni precej manj. Zato bo napajanje preko USB kabla dovoljšnje tudi, ko preverjamo delo programa z dvema takšnima servo motorjema. Delovni tok HS-422 in podobnih servo motorjev je okoli 150 mA, vendar lahko pod obremenitvijo zraste tudi do 800 mA. Če uporabljamo dva servo motorja te vrste, je nujno zagotoviti napajanje preko mrežnega adapterja z napetostjo 7,5-9 V in maksimalnim tokom najmanj 1 A. Adapterja ne povežemo na Shield-B, pač pa na Arduino Uno!
https://svet-el.si