Avtorja: Mag. Vladimir Mitrović, Robert Sedak
E-pošta: vmitrovic12@gmail.com
V tem nadaljevanju bomo spoznali koračne motorje, pokazali bomo, kako jih lahko vežemo na razvojno ploščo Shield-B. Napisali bomo Bascom-AVR in Arduino programe, s katerimi jih bomo zagnali.
Koračni motorji se ne vrtijo stalno, pač pa se premikajo v korakih in se lahko zaustavijo samo v določenih položajih. Če so ti koraki dovolj kratki, bomo koračni motor lahko zelo natančno zavrteli za želeni kot, kar je tudi njegova najvažnejša lastnost.
Slika 21 prikazuje notranjost enostavnega unipolarnega koračnega motorja, ki je sestavljen iz permanentnega magneta (rotorja) in štirih elektromagnetov (statorja). Rotor se vrti proti tistim polom statorja, ki so v določenem trenutku magnetizirani. To je lahko samo en pol ali po dva sosedna, kot smo to na sliki prikazali. V gornji vrsti je prikazan potreben vrstni red vklapljanja statorskih elektromagnetov z namenom, da bi se rotor vrtel v smeri vrtenja kazalca na uri. V spodnji vrsti je prikazan potreben vrstni red vklapljanja statorskih elektromagnetov z namenom, da bi se rotor vrtel v smeri, ki je nasprotna vrtenju kazalca na uri.
Ta vsebina je samo za naročnike
Če primerjate katero koli sosednjo skico v horizontalni vrsti na sliki 21 boste opazili, da se je rotor med njima obrnil za 90°. Za takšen motor rečemo, da ima korak 90°. Isti motor lahko naredimo dvakrat bolj natančen, če ga vrtimo s pol-korakom (slika 22): tukaj rotor izmenično privlači en statorski elektromagnet in dva sosednja, zaradi česar je korak prepolovljen na 45°. V obeh primerih korakov ne smemo preskakovati, ker bomo samo tako zagotovili zanesljivo delo motorja!
Za večino uporab potrebujemo bolj natančno kontrolo pomikov, zato proizvajalci koračnih motorjev le-te proizvajajo z večjim številom statorskih ovojev od prikazanih, njihov korak pa je nekaj deset ali manj stopinj. Dodatno se korak lahko zmanjša z uporabo zobatega ali polžastega prenosa.
Fotografija na sliki 23 prikazuje dva takšna motorja: koračni motor s polžastim prenosom je vzet iz disketnega pogona osebnega računalnika, v katerem je uporabljen za natančno postavljanje glav za branje/pisanje, in 28BYJ-48, katerega bomo mi uporabili. 28BYJ-48 ima 32 statorjev in skladno s tem je potrebnih 32 korakov za polni krog osi motorja, če uporabimo pomik s polnim korakom. Dodatno je v motor vgrajen zobniški prenos s prenosnim razmerjem 64:1, zato se bo izhodna os vrtela 64-krat počasneje. Z drugimi besedami, za en polni obrat je potrebnih 32×64 = 2048 korakov, oziroma dosežemo pomik 0,176° na korak.
Vse kar je potrebno vedeti o krmiljenju unipolarnega servo motorja 28BYJ-48, je prikazano na sliki 24. Motor ima pet priključkov, od katerih je rdeči skupni vsem navitjem in se veže na pozitivni priključek napajalne napetosti. Svobodni priključki statorskih ovojev so povezani na preostale štiri priključke. Z vezavo enega od teh priključkov na negativni priključek napajalne napetosti se bodo magnetizirali tisti deli statorja, skozi katere navitja bo stekel tok. Priključki imajo 5-pin konektor, njegov razpored priključkov ustreza razporedu priključkov na konektorju J6 razvojne plošče Shield-B.
Tabele kažejo vrstni red po katerem moramo prepuščati tok skozi posamezna navitja tako, da bi se koračni motor obrnil v želeni smeri (oznaka “1” pomeni, da skozi ustrezno navitje teče tok). Tabele v gornji vrsti ustrezajo polnemu koraku, tabele v spodnji vrsti pa ustrezajo pol-koraku. Tukaj je smer rotacije potrebno gledati pogojno, ker je odvisna tudi od števila zobnikov v zobniškem prenosu.
Shema na sliki 25 kaže kako unipolarni koračni motor 28BYJ-48 vežemo na razvojno ploščo Shield-B. Upornost posameznega navitja motorja je 27 Ω in skozi aktivirana navitja teče tok okoli 180 mA. Zato priključkov motorja ne smemo direktno vezati na priključke mikrokontrolerja, ampak jih vklapljamo s pomočjo tranzistorskih vezij vgrajenih v integrirano vezje ULN2003 (uporabimo 4 od 7 razpoložljivih stikal). Stikala krmilimo s spremembo logičnih stanj na ustreznih priključkih mikrokontrolerja, pri čemer logična enica vklopi stikalo, ničla pa ga izklopi.
Modre LED-ice D4-D7 svetijo takrat, ko je posamezno stikalo vklopljeno; z njihovo pomočjo lahko preverimo delo programa tudi brez priključenega motorja.
Opombe: namesto navedenih se na Shield-B lahko vežejo tudi drugi unipolarni motorji s podobnimi karakteristikami. Shield-B ni predviden za krmiljenje bipolarnih koračnih motorjev, pri katerih se vrtenje rotorja doseže s spremembo smeri toka skozi statorska navitja!
- programska naloga: Za vezje po shemi na sliki 25 napišite program, s katerim bomo krmilili koračni motor na naslednji način:
dokler je pritisnjeno stikalo SW2 naj se motor vrti z maksimalno možno hitrostjo v eni smeri;
dokler je pritisnjeno stikalo SW3, naj se motor vrti z maksimalno možno hitrostjo v drugi smeri.
Bascom-AVR rešitev (program Shield-B_6.bas)
Po uvodnih konfiguracijskih ukazih, ki se nanašajo na uporabljeni mikrokontroler in pogoje v katerih deluje, bomo dimenzionirali spremenljivke Step-korak in Step-i:
Dim Step_korak As Byte
Dim Step_i As Byte
Prva od njih bo vsebovala binarno kombinacijo trenutnega koraka, druga je indeks v tabeli Step-tabela, ki vsebuje definicije vseh važnih korakov s slike 24. Tabelo definiramo na koncu programa:
Step_tabela:
Data &B1000
Data &B1100
Data &B0100
Data &B0110
Data &B0010
Data &B0011
Data &B0001
Data &B1001
Opazimo, da tabela vsebuje 8 definicij pol-koraka. Odvisno od želene smeri vrtenja jo bomo brali od zgoraj navzdol ali v nasprotni smeri. Isto tabelo uporabimo tudi za vrtenje s polnim korakom, v tem primeru beremo vsak drugi zapis (oziroma, samo zapise, v katerih obstajata po dve enici).
Na začetku programa še moramo konfigurirati vhodne priključke PC2 in PC3:
Config Portc.2 = Input
Portc.2 = 1
Config Portc.3 = Input
Portc.3 = 1
Vse priključke, ki krmilijo koračni motor, konfiguriramo kot izhodne:
Config Portd.2 = Output
Config Portd.4 = Output
Config Portd.7 = Output
Config Portb.0 = Output
Sedaj bomo motor postavili v začetno stanje, ki ustreza zgornji levi risbi na sliki 21. To stanje se nahaja v drugi vrsti tabele, zato bomo v indeks vpisali 1 (prva vrsta tabele ima indeks 0) in poklicali podprogram Step_premakni:
Step_i = 1
Gosub Step_premakni
V njemu najprej zagotovimo, da indeks ne bi bil večji od 7,
Step_premakni:
Step_i = Step_i And &B00000111
beremo indeksirano vrsto iz tabele
Step_korak = Lookup(step_i , Step_tabela)
in nato bit po bit postavljamo izhodne priključke v ustrezna stanja:
Portb.0 = Step_korak.3
Portd.7 = Step_korak.2
Portd.4 = Step_korak.1
Portd.2 = Step_korak.0
Return
V glavni programski zanki preverjamo ali je pritisnjena katera od tipk, in tako povečamo ali zmanjšamo indeks za dva (uporabimo polni korak):
Do
If Pinc.2 = 0 Then
Step_i = Step_i + 2
End If
If Pinc.3 = 0 Then
Step_i = Step_i – 2
End If
Vsako prebrano stanje prenesemo na izhodne priključke, da bi se os motorja zavrtela v želeni smeri za en korak.
Gosub Step_premakni
Waitms 2
Loop
Ukaz Waitms določa časovno razliko med dvema korakoma in tako vpliva na hitrost vrtenja motorja.
Arduino rešitev (program Shield-B_6.ino)
Program bomo začeli z deklariranjem spremenljivk step_korak in step_i, pri čemer jim dodamo začetne vrednosti:
byte step_korak = 0;
byte step_i = 1;
Po njih definiramo zaporedje osmih elementov z imenom step_tabela, ki vsebuje definicije vseh veljavnih korakov:
byte step_tabela[8] = {0b1000,
0b1100,
0b0100,
0b0110,
0b0010,
0b0011,
0b0001,
0b1001};
V funkciji setup() definiramo priključke 2, 4, 7, in 8 kot izhodne,
void setup() {
pinMode(2,OUTPUT);
pinMode(4,OUTPUT);
pinMode(7,OUTPUT);
pinMode(8,OUTPUT);
priključka A2 in A3 definiramo kot vhodna z vklopljenim pull-up uporom:
pinMode(A2, INPUT_PULLUP);
pinMode(A3, INPUT_PULLUP);
Motor bomo postaviti v začetno stanje s klicanjem funkcije step_premakni():
step_premakni();
} // konec setup()
V funkciji step_premakni() najprej zagotovimo, da indeks step_i ni večji od 7 z uporabo logičnega I operatorja &;
void step_premakni() {
step_i = step_i & 0b0000111;
beremo indeksirani element iz vrste step_tabela:
step_korak = step_tabela[step_i];
in nato bit po bit postavljamo izhodne priključke v ustrezna stanja:
digitalWrite(2, bitRead(step_korak, 3));
digitalWrite(4, bitRead(step_korak, 2));
digitalWrite(7, bitRead(step_korak, 1));
digitalWrite(8, bitRead(step_korak, 0));
} // kraj step_pomakni()
V glavni programski zanki loop() preverjamo, ali je pritisnjena katera od tipk in nato povečujemo ali zmanjšujemo indeks za dve (uporabimo polni korak):
void loop() {
if (digitalRead(A2) == 0) {
step_i = step_i + 2;
}
if (digitalRead(A3) == 0) {
step_i = step_i – 2;
}
Vsako prebrano stanje prenesemo na izhodne priključke, da bi se os motorja obrnila v želeni smeri za en korak.
step_premakni();
delay(2);
} // konec loop()
Ukaz delay() določa časovno razliko izmed dveh korakov in tako vpliva na hitrost vrtenja motorja.
Ulaza Waitms v Bascom-AVR in delay() v Arduino programu določata hitrost vrtenja koračnega motorja. Če je zakasnitev krajša, se bo motor vrtel hitreje in obratno. 2 ms zakasnitev je bila določena s poskusom in pri njej se je motor vrtel z največjo možno hitrostjo, pri še manjših zakasnitvah se je ustavil. Ta pojem največje hitrosti lahko razumemo z omejitvijo: zaradi velike stopnje prenosa je izhodna os za en poln obrat potrebovala okoli 4 s.
Seveda koračnih motorjev niti ne uporabimo tam, kjer je potrebna velika hitrost vrtenja, pač pa tam, kjer je potrebna velika natančnost!
Za radovedne: povečajte časovno razliko iz 2 ms na 200 ms, spremljajte kaj se dogaja z LED-icami in to obnašanje LED-ic primerjajte z vrtenjem osi motorja!
Opombe: Programa Shield-B_6.bas in Shield-B_6.ino lahko brezplačno dobite od uredništva revije Svet elektronike!