Avtorja: mag. Vladimir Mitrović in Robert Sedak
E-pošta: vmitrovic12@gmail.com
V reviji Svet elektronike št. 288-301 smo predstavili razvojni sistem in učilo za programiranje mikrokontrolerjev z imenom Shield-A.
Shield-A je oblika Arduino Uno ploščice in vsebuje različne komponente – nize enobarvnih in tribarvnih (RGB) LED-ic, piskač, tipke, potenciometer, in tudi priključke za alfanumerični displej ter za I2C komunikacijo. Ko jo postavimo na Arduino Uno ali kompatibilno ploščico, se komponente s Shielda-A povežejo z mikrokontrolerjem ATmega328P in nam omogočajo, da vizualiziramo delo programa, ki smo ga napisali. S tem, ko smo si zadali enostavne in vse bolj zahtevne programske naloge, smo postopoma vstopali v svet programiranja mikrokontrolerjev. Programe smo pisali v programskih jezikih Bascom-AVR in Arduino, da bi učilo lahko približali uporabnikom obeh platform.
Sedaj, ko smo se naučili osnove, je prišel čas za korak naprej: pokazali bomo, kako s pomočjo mikrokontrolerja krmiliti različne vrste elektromotorjev! Za začetek vzemimo ”običajen” mali enosmerni (DC) elektromotor, kot tisti, ki ga robotiki uporabljajo v svojih konstrukcijah. Najenostavneje rečeno, vsak, ki se je naučil kako sprogramirati mikrokontroler, da bi z njegovo pomočjo lahko vklopil ali izklopil svetlečo (LE) diodo, bo znal zagnati in zaustaviti elektromotor. No, ali je vse res tako enostavno?
Slika 1a prikazuje običajen način vezave LED-ice in mikrokontrolerja:
- ko priključek Pxy mikrokontrolerja, na katerega je vezana LED-ica (na sliki 1a) postavimo v stanje logične ničle (= 0 V), bo skozi diodo stekel tok in LED-ica bo zasvetila,
- ko isti priključek mikrokontrolerja postavimo v stanje logične enice (= 5 V), bo dioda ugasnila, ker skozi njo več ne teče tok.
Ker LED-ice ”delujejo” na nižjih napetostih od tistih, ki se običajno uporabljajo za napajanje mikrokontrolerja (na Arduino Uno ploščici ta napetost znaša 5 V), potrebujemo tudi upor R, ki bo omejil tok skozi LED-ico na ustrezno vrednost. Predpostavimo, da imamo enosmerni elektromotor predviden za 5V napetost in ga vežemo na mikrokontroler namesto LED-ice, prav tako, kakor je prikazano na sliki 1b. Vezje je še enostavnejše, ker je delovna napetost elektromotorja ravno 5 V, zato upora R več ne potrebujemo… Vendar pa slika sugerira, da s tem vezjem še vedno nekaj ni v redu; pojasnimo zakaj!
Ta vsebina je samo za naročnike
Elektromotorji, tudi tako majhni, potrebujejo za svoje delo precej večji tok od tistega, ki teče skozi LED-ico: tipično gre za tokove večje od 100 mA. Z druge strani, priključke mikrokontrolerja ne smemo obremeniti s tokovi, ki so večji od 40 mA: če bi elektromotor vezali kot na sliki 1b in ga vklopili s postavljanjem priključka Pxy v stanje logične ničle, bi skozi njega stekel tok, ki bi preobremenil ta priključek, mogoče celo uničil celoten mikrokontroler.
Problem rešujemo z uvajanjem ustreznega elektronskega stikala: stikalo mora biti dovolj zmogljivo, da lahko sigurno vklaplja in izklaplja elektromotor, in dovolj ”občutljivo” da ga lahko krmilimo iz mikrokontrolerja. Najenostavnejše elektronsko stikalo je tranzistor v vezju kot na sliki 1c:
- ko je priključek Pxy v stanju logične ničle, tranzistor T ne prevaja toka (”stikalo” je odprto) in elektromotor je izklopljen;
- ko je priključek Pxy v stanju logične enice, preko upora R bo proti bazi tranzistorja T stekel tok in tranzistor bo pričel prevajati (”stikalo” je sklenjeno) in elektromotor se bo zavrtel.
Ker tok elektromotorja teče skozi tranzistor in ne skozi mikrokontroler, lahko na opisani način vklapljamo tudi močnejše elektromotorje – koliko močnejše je odvisno samo od zmožnosti tranzistorskega stikala. Zaradi velikega tokovnega ojačenja tranzistorja so za krmiljenje takega stikala dovoljšnji bazni tokovi velikosti nekaj mA, katere lahko mikrokontroler enostavno ”daje”. Opazili bomo, da v vezju na sliki 1c elektromotor vklapljamo s postavljanjem priključka Pxy v stanje logične enice, medtem, ko smo LED-ico, vezano kot na sliki 1a, vklapljali z logično ničlo; to v bistvu ničesar ne menja, vendar je to potrebno upoštevati pri pisanju programa.
Vezje s tranzistorjem ima še eno veliko prednost: napetost napajanja elektromotorja je lahko različna od napajalne napetosti mikrokontrolerja; npr., na takšen način lahko krmilimo elektromotor z delovno napetostjo 3, 6 ali morda 12 V. Dioda D ščiti vezje od prenapetosti; brez nje bi na kolektorju tranzistorja v trenutku, ko tranzistor izklopi elektromotor, nastala zelo visoka napetost, ki bi lahko uničila sam tranzistor.
Razen ”običajnega” NPN tranzistorja na sliki 1c, lahko kot elektronsko stikalo uporabimo tudi MOSFET tranzistorje, njihove karakteristike so še bližje idealnemu stikalu. Če v nekem projektu potrebujemo več elektronskih stikal, je bolj primerno uporabiti specialno integrirano vezje kot L272M na sliki 2. LM272 vsebuje dva operacijska ojačevalnika, OP1 in OP2, in dve dvo-položajni stikali narejeni z močnimi tranzistorji. Operacijski ojačevalniki primerjajo napetosti na svojih + in – vhodih (delajo kot komparatorji) in odvisno od njihove trenutne vrednosti, preklopijo stikalo tako, da povežejo izhodni priključek proti + ali proti – polu napajalne napetosti. Bolje bomo to pojasnili s pomočjo risbe na sliki 2 desno:
ko je napetost + vhoda operacijskega ojačevalnika višja od napetosti njegovega – vhoda, bo stikalo preklopilo izhodni priključek na + pol napajalne napetosti (zgornje stikalo na izhodu je +U);
ko je napetost + vhoda operacijskega ojačevalnika nižja od napetosti njegovega – vhoda, bo stikalo preklopilo izhodni priključek na – pol napajalne napetosti (spodnje stikalo na izhodu je -U).
Tranzistorska stikala znotraj integriranega vezja L272M lahko preklapljajo tokove do 1 A pri napetostih do 28 V – kar je idealno za delo z malimi enosmernimi elektromotorji. (Tukaj vseeno moramo opomniti, da tranzistorska stikala znotraj integriranega vezja L272M niso idealna, ker na njih v stanju prevajanja obstaja padec napetosti okoli 1 V; to je mora upoštevati med projektiranjem vezja in izbire optimalne delovne napetosti!)
Druge izvedbe elektromotorjev, kot koračni ali servo motorji, zahtevajo drugačna krmilna vezja (drivere). Ugotavljamo, da bi bilo koristno imeti ploščico, na kateri se že nahajajo ustrezna vezja za krmiljenje različnih vrst elektromotorjev, in še kakšno tipko ali potenciometer, s katerima bi jih lahko krmilili. Prav takšna ploščica je naš Shield-B modul, čigar možnosti bomo raziskovali v nekaj naslednjih številkah revije Svet elektronike!
Shield-B z obliko, dimenzijami in razporedom priključkov ustreza ploščici Arduino Uno (slika 3). Ko ga enkrat postavimo na Arduino Uno ali kompatibilno ploščico, se komponente shielda povežejo z mikrokontrolerjem, kar bomo postopno raziskovali. Na Shieldu-B se nahajajo tudi konektorji, na katere lahko vežemo različne vrste elektromotorjev. Ko povežemo motor in izberemo ustrezno napajalno napetost, nam preostane le še to, da napišemo program, s katerim ga bomo krmilili… Čaka nas veliko dela!
Pokažimo najprej, kako lahko na Shield-B povežemo mali enosmerni (DC) elektromotor, in kako ga lahko zaženemo in zaustavimo iz programov napisanih v programskih jezikih Bascom-AVR in Arduino IDE.
Da bi lahko krmili DC elektromotorje, smo na razvojno ploščico Shield-B postavili integrirano vezje L272M, električna shema na sliki 4 kaže, kako je povezan z mikrokontrolerjem ATmega328P. Od vseh prikazanih komponent se samo mikrokontroler nahaja na Arduino Uno ploščici, medtem ko so vse ostale del razvojnega sistema Shield-B. Modro obarvani kvadratki predstavljajo vezi med Arduino Uno in Shield-B ploščico, oznake poleg njih ustrezajo oznakam na Arduino Uno ploščici.
Da bi vezje delalo kot mora, sta potrebna dva vira napajanja:
Mikrokontroler se napaja z napetostjo 5 V, ki pride z osebnega računalnika preko USB kabla, ali preko napetostnega stabilizatorja na Arduino Uno ploščici.
Elektromotorji in L272M se napajajo iz ustreznega vira napajanja, katere napetost UMOT je potrebno prilagoditi delovni napetosti motorjev. Ta vir je lahko akumulator ali omrežni adapter; zaradi padca napetosti na elektronskih stikalih znotraj integriranega vezja L272M, mora biti napetost vira okoli 1 V višja od delovne napetosti elektromotorja.
”Vijolična” dioda D9 dovaja napetost za napajanje motorjev, UMOT, na VIN vhod Arduino Uno ploščice, oziroma na vhodni priključek njenega napetostnega stabilizatorja. Zato lahko enkrat, ko programiramo mikrokontroler, prekinemo USB kabel od računalnika in napajanje celotnega vezja in vseh komponent na Arduino VIN Uno ploščici in ga zagotovimo iz vira UMOT. Da bi izguba napetosti na diodi bila čim manjša, smo uporabili Schottky diodo SB120. Da pa bi vse delalo tako kot mora, mora biti napetost UMOT stabilna in višja od 6,5 V; pri nižjih napetostih napetostni stabilizator na Arduino Uno ploščici ne bo mogel zagotoviti stabilnega napajanja mikrokontrolerja, kar lahko povzroči netočno izvajanje programa.
Dvobarvna svetleča dioda D1 ima dvojno vlogo:
Zeleni segment bo zasvetil takoj, ko Arduino Uno z USB kablom povežemo z osebnim računalnikom, oziroma, ko zagotovimo kateri koli vir napajanja Arduino Uno ploščice (napetost +5V je prisotna v vseh kombinacijah napajanja, zato bo zeleni segment vedno svetil). Padec napetosti na njemu je okoli 2 V, in to napetost uporabimo kot referenčno napetost za – vhode komparatorja znotraj integriranega vezja L272M.
Rdeč segment LED-ice D1 sveti samo, če je prisotna napetost UMOT. Odvisno od višine te napetosti in karakteristike uporabljene LED-ice, bo svetila rumeno ali oranžno. Pri višji napetosti UMOT, je lahko rdeča svetloba toliko dominantna, da popolnoma ”zaduši” zeleno barvo.
Mali signalni LED-ici, D2 in D3, svetita, ko je napetost na ustreznih + vhodih komparatorja 5 V. Vgrajene so zato, da bi lahko videli, kakšne so krmilne napetosti in tako vizualno preverili, kako dela naš program, ne da bi vezali elektromotor in brez priključene napetosti UMOT.
Shema na sliki 5 prikazuje vse ključne komponente in dva različna načina vezanja DC elektromotorja na priključke razvojnega sistema Shield-B.
Motor A je vezan med priključka M1 in M-, zato se bo zavrtel, ko M1 preko integriranega vezja L272M povežemo s priključkom M+, oziroma, s + polom napetosti UMOT. To bomo dosegli, če napetost + vhoda spodnjega komparatorja dvignemo nad napetost njegovega – vhoda, tj. nad 2 V.
Motor B je vezan med priključka M2 in M+, zato se bo zavrtel, ko M2 preko integriranega vezja L272M povežemo s priključkom M-, oziroma, z – polom napetosti UMOT. To bomo dosegli, če napetost + vhoda zgornjega komparatorja spustimo pod napetost njegovega – vhoda, tj. pod 2 V.
Tipki SW2 in SW3 se nahajata na ploščici Shield-B in z njima bomo krmiliti elektromotorja. Sedaj nam je poznano elektronsko vezje in je čas, da postavimo našo prvo programsko nalogo!
- programska naloga: Motor A se mora vrteti dokler držimo pritisnjeno tipko SW3. Motor B se mora vrteti dokler držimo pritisnjeno tipko SW2.
Bascom-AVR rešitev
(program Shield-B_1.bas)
Spomnimo se, da vsak Bascom-AVR program pričnemo z nekaj konfiguracijskimi ukazi, ki se napajajo na uporabljen mikrokontroler in pogoje, v katerih dela:
$regfile = ”m328pdef.dat”
$crystal = 16000000
$hwstack = 64
$swstack = 32
$framesize = 64
Config Clockdiv = 1
Iz teh ukazov bo Bascom-AVR prevajalnik zaznal, da pišemo program za Atmega328P, ki dela s taktom frekvence 16 MHz, in koliko spomina sme porabiti za različne sistemske potrebe. Tako napisani konfiguracijski ukazi bodo ustrezali za vse programe, ki jih bomo analizirati v tej seriji, zato jih bomo samo prekopirali na začetek vsakega novega programa.
Sedaj pristopimo rešitvi naše programske naloge. Najprej moramo konfigurirati priključka PD5 in PD6 kot izhoda
Config PORTD.5 = Output
Config PORTD.6 = Output
medtem ko bomo priključka PC2 in PC3 konfigurirali kot vhodna:
Config PORTC.2 = Input
Config PORTC.3 = Input
Da bi lahko brali stanja tipk, moramo na vhodnih priključkih vključiti pull-up upora:
PORTC.2 = 1
PORTC.3 = 1
Zaradi njiju bo vhodni priključek v stanju ”0” dokler je pridružena tipka pritisnjena, in se bo vrnil v stanje ”1” ko tipko spustimo. Sedaj vstopamo v neskončno Do-Loop zanko, znotraj katere program večkrat preverja logična stanja na vhodnih priključkih PC2 in PC3. Če ugotovi, da je tipka SW3 pritisnjena, bo postavil izhodni priključek PD5 v stanje ”1” in tako zagnal motor A:
Do
If PINC.3 = 0 Then
PORTD.5 = 1 ‚vklopi A
Else
PORTD.5 = 0 ‚izklopi A
End If
Isto proceduro bomo ponovili s tipko SW2 in motorjem B, samo tega vklapljamo s postavljanjem priključka PD6 v stanje ”0”:
If PINC.2 = 0 Then
PORTD.6 = 0 ‚vklopi B
Else
PORTD.6 = 1 ‚izklopi B
End If
Loop
Če ugotovimo, da je pri elektromotorju B logično stanje izhodnega priključka enako, pri elektromotorju A pa nasprotno logičnemu stanju vhodnega priključka, lahko to programsko nalogo rešimo tudi precej enostavneje:
Do
PORTD.5 = Not PINC.3
PORTD.6 = PINC.2
Loop
Arduino rešitev
(program Shield-B_1.ino)
V funkciji setup() konfiguriramo priključka 5 (PD5) in 6 (PD6) kot izhodna, priključka A2 (PC2) in A3 (PC3) kot vhodna z vključenima pull-up uporoma:
void setup() {
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(A2, INPUT_PULLUP);
pinMode(A3, INPUT_PULLUP);
}
V funkciji loop() uporabimo isto programsko logiko, kot v Bascom-AVR primeru. Za branje stanja tipk uporabimo ukaz digitalRead(), za postavljanje stanja priključkov 5 in 6 uporabimo ukaz digitalWrite().
void loop() {
if (digitalRead(A2) == 0) {
digitalWrite(5, HIGH);
} else {
digitalWrite(5, LOW);
}
if (digitalRead(A3) == 0) {
digitalWrite(6, LOW);
} else {
digitalWrite(6, HIGH);
}
}
Funkcijo loop() lahko tako poenostavimo:
void loop() {
digitalWrite(5, !digitalRead(A2));
digitalWrite(6, digitalRead(A3));
}
V trenutku, ko prenesete program v mikrokontroler, boste opazili, da se motor B vrti okoli tri sekunde in se nato zaustavi. Isto se bo dogodilo, če pritisnete tipko RESET na Shield-B ploščici.
To se dogaja zato, ker je pri zagonu mikrokontrolerja potrebnih do tri sekunde za branje bootloaderja in zagon programa vpisanega v flash spominu. Za čas branja bootloaderja in do zagona programa so vsi priključki postavljeni v stanje logične ničle. Ker je motor B vezan na priključke M2 in M+, dokler je priključek 6 v stanju logične ničle (in posledično M2 je vezan z – polom napetosti UMOT), se bo motor vrtel.
Konektorji na razvojnem sistemu Shield-B omogočajo sočasno vezavo dveh DC elektromotorjev. Oba motorja sta lahko vezana kot motorja A ali kot motorja B ali na ”mešan” način prikazan na sliki 5.
Niti en od teh načinov vezave ni boljši ali slabši od drugega in, katero koli kombinacijo bi izbrali, bomo lahko neodvisno krmiliti vsakega od motorjev. Smer vrtenja motorjev je določena z načinom, kako smo njegove priključke povezali na priključke Shielda-B in se lahko spremeni, če tem priključkom zamenjamo mesta. Da bi iz programa spremenili smer vrtenja in kako elektromotor upočasniti ali pohitriti, bomo pokazali v naslednjem nadaljevanju!
Opombe: Shemo razvojnega sistema Shield-B, popis komponent in proizvodne datoteke ploščice si lahko prenesete s povezave https://github.com/rsedak/Shield-B. Programa Shield-B_1.bas in Shield-B_1.ino lahko brezplačno dobite od uredništva revije Svet elektronike!
https://svet-el.si