Digitaalsed sisend-väljundid Robootika KodulaborisAutor: Raivo Sell Käesolev õpiobjekt tutvustab lihtsaimat mikrokontrolleri funktsioone - digitaalseid sisend-väljundeid ehk kontrolleri viike.![]() Viigud on mikrokontrolleri metallist kontaktid, kõnekeeles jalad, mille kaudu saab edastada ja vastu võtta signaale. Kui viik seadistada programmis sisendiks, saab selle kaudu mikrokontrollerisse lugeda lülitite või muude lihtsamate andurite olekut. Kui viik seadistada väljundiks, saab selle kaudu süüdata valgusdioode või juhtida elektriseadmeid. Peaaegu kõigi tüüpiliste mikrokontrollerite viigud võimaldavad lihtsaid sisend-väljundfunktsioone täita, kuid tavaliselt on neil viikudel ka alternatiivfunktsioonid. Enne alternatiivfunktsioonidega tegelemist, tuleks aga lihtsamad funktsioonid endale selgeks teha. ![]() Õpiobjekti nimi: Digitaalsed sisend-väljundid Robootika KodulaborisÕpiväljund: Pärast mooduli läbimist õpilane:
Kasutusjuhend:
Õpetatav osa: Lugeda teoreetilist ülevaadet enne riistvara reaalset ühendamist ja pingestamist. Vaadata õpivideosid korrektse riistvara käsitlemise tagamiseks. Tarkvara arenduskeskkonna kasutamiseks vaadata üle ekraanijuhendid. Õpitu kinnistamiseks tuleb praktilised näited reaalselt läbi teha. Seoste loomine: Läbi õppevideo ja sõnalise selgituse järgimise. Kinnistav osa: Iseseisev praktika reaalse riistvarakomplekti baasil. TEOREETILINE OSA![]() RegistridMikrokontrolleri registrit võib tinglikult võrrelda lülitite paneeliga (nt. 8 bit register on nagu kaheksa eraldi lülitiga paneel), kus iga lüliti paneb selle õigel kasutamisel midagi käima või seadistab mingi oleku. Valesid lüliteid vajutades mikrokontroller (enamasti) küll katki ei lähe, kuid ei tööta ka õigesti. Tegelikult registris selliseid füüsilisi lüliteid muidugi pole, on hoopis hulk transistore, mis elektrit sisse ja välja lülitavad. Lihtsamatel mikrokontrolleritel on registris 8 transistoridel põhinevat elektrilist lülitit. Registrit võib aga käsitleda nagu 8-bitist arvu, milles iga bitt tähistab ühe lüliti olekut. Näiteks biti väärtus 1 võib tähendada, et lüliti on sees ja 0, et lüliti on väljas. Kuna registri lülitite olekut saab väga hästi esitada arvuna ja vastupidi, siis võib registrit võrrelda ka mäluga, mis suudab hoida ühe arvu suurust informatsiooni. Selle võrdlusega jõudis jutt selleni, et registrid ongi mälupesad. Vahe mälupesaga seisnebki üldjuhul ainult selles, et mälupesa ei tee muud, kui hoiab informatsiooni, registris see informatsioon aga juhib midagi. Ehk kui pildil kujutatud registrisse kirjutada binaarväärtus 01100001, siis kolm näilist lülitit lükatakse alla ja midagi hakkab toimuma. Kui lülitipaneelil võib igat nuppu eraldi vajutada, siis registrites on ühe „lüliti“ või biti muutmine keerulisem. Üldjuhul tuleb muuta kogu registri sisu korraga. Enne kui bittide muutmisest rääkida, tuleks aga teada veel seda, et registreid on mikrokontrolleris palju. Mõnede mikrokontrolleri osade juhtimiseks võib kasutusel olla ka kümneid registreid. Registrite paljusus tähendab, et registreid peab kuidagi eristama ja seda tehakse nimega. Üks registri nimi on näiteks PORTB. Tõe huvides võib mainida, et tegelikult on nimed vaid inimese välja mõeldud asendused numbrilistele aadressidele. Digitaal sisend-väljund pordi registridJärgnevalt on toodud ülevaade ühe digitaalse sisend-väljund pordiga seotud registrid AVR Atmega kontrolleri näitel. Pordi juhtregistriteks on kolm eraldi registrit, milleks on DDRx, PORTx ja PINx. Väike x tähistab siinkohal pordi indeksit ja on üldjuhul tähestiku täht. Näiteks on tegelikud nimed: DDRA, PORTA, PINA; DDRB, PORTB, PINB; DDRC, PORTC, PINC; jne. DDRx register määrab ära andmete liikumise suuna. Kui bit on kõrge (1), siis viik on seatud väljundiks, kui bit on madal (0), siis töötab viik sisendina. PORTx on andmeregister ja kõik bitid on seal nii loetavad, kui ka kirjutatavad. Määrates mingi bit-i registris kõrgeks (1) lülitatakse vastava bitiga seotud viik ka kõrgeks (toitepinge), kui bit määratakse madalaks (0) siis vastav viik seatakse samuti madalaks (maa). See toimib juhul, kui eelnevalt on vastavad viigud määratud DDRx registri kaudu väljundiks. Kui viigud on määratud sisendiks, siis sel juhul on võimalik PORTx registrist lugeda viigu olek (vastavalt siis ka toitepinge (1) või maa (0). PINx on sisendregister. See on ainult loetav ja võimaldab lugeda viigu olekut (sarnaselt PORTx registrile). ![]() Mikrokontrolleri andmelehes (näites ATMega) on registrid dokumenteeritud järgmise illustratsiooniga:
![]() Eelpool kirjeldatud registritega saab lugeda enamus digitaalseid sisendeid ja juhtida digitaalseid väljundeid. Järgnevalt on toodud näited enamlevinud digitaalsete sisend-väljund seadmete kasutamise kohta. Valgusdiood![]() ![]() Lihtsaim ja levinuim komponent, mida hobirobootikas digitaalse väljundiga juhitakse on tavaline valgusdiood. Valgusdiood on pooljuht, mille päripingestamisel kiirgab see valgust. Valgusdioodi nimetatakse inglise keelse lühendiga LED (light-emitting diode). On olemas erineva värvusega valgusdioode ja valgusdioodide kombinatsioone, millega saab tekitada ka valget valgust. Valgusdioodil on nagu tavalisel dioodilgi kaks kontakti - anood ja katood. Valgusdioodi joonistel on anood tähistatud + ja katood - sümboliga. LED-e kasutatakse tihti indikaatoritena ja neid toidetakse otse mikrokontrolleri viikudelt. Kuna mikrokontrollerite toitepinge on enamasti kõrgem LED-ide päripingest ja ka voolutugevus on suurem, siis tuleb LED-iga järjestikku lisada takisti, mis piirab voolu ja tekitab vajaliku pingelangu. Takisti arvutusvalemid leiab elektroonika peatükist. LED-e toodetakse mitmesugustes kestades. Kõige levinumatel „jalgadega“ LED-idel on 3 mm või 5 mm läbimõõduga ümmargune kest ja 2 pikka metallist viiku. Pikem viik tähistab anoodi, lühem katoodi. Pindliides kestas (SMD) LED-idel on polaarsuse tähistamiseks põhja all T-kujuline tähis, kus T katus tähistab anoodi ja teravik katoodi asukohta. Lüliti![]() ![]() Lihtsaim ja levinuim komponent, mida hobirobootikas digitaalse sisendina kasutatakse on tavaline lüliti. Lüliti on elektromehhaaniline seade elektriahela kokku- ja lahtiühendamiseks. Lüliteid on erinevaid, kuid tüüpiline mehaaniline lüliti koosneb klemmidest, mida saab omavahel mehaaniliselt ühendada. Klemmide ühenduse korral on elektriahel suletud ja lülitit võib läbida elektrivool. Kui klemmid on lahti, on elektriahel avatud ja elektrivool lülitit läbida ei saa. Lülititega saab otseselt elektriahelaid pingestada, kuid neid saab kasutada ka anduritena. Lüliti anduri funktsioonis on ka selle harjutuse teema, seepärast on vaatluse alt välja jäetud spetsiifilised kõrgepinge ja suure voolu lülitid. Lülitid erinevad ka kontaktide arvu ja nende ühendamise meetodilt. On olemas kahe kontaktiga lüliteid, kuid ka duubellüliteid, kus ühendatakse kontaktide paarid. On surunupp-, klahv-, liug- ja pöiallüliteid ning lüliteid, mis vajutades ei ühenda, vaid katkestavad elektriahela. Lüliti kasutamiseks andurina mikrokontrolleri juures ühendatakse lüliti üks kontakt mikrokontrolleri viiguga, mis määratakse programmis sisendiks. Kui toimub kontakti ühendamine maa- või toitepotentsiaaliga, muutub ka mikrokontrolleri viigule vastava siini biti väärtus. Loogiline variant on kasutada pöiallülitit, mis võimaldab üht kontakti ühendada valitud kontaktiga (antud juhul siis maa või toitega), kuid see pole päris nii lihtne. Põhjus on selles, et ümberlülitamise hetkel ei ole kontaktid omavahel ühenduses. See hetk on väga lühike (millisekundites), kuid sellesama hetke jooksul pole mikrokontrolleri sisendviik kuhugi ühendatud ja sel on määramata väärtus. Elektromagnetiliste häirete tõttu (mida leidub kõikjal) võib mitte kuhugi ühendatud sisendviik täiesti suvalistel ajahetkedel omada 0 või 1 väärtust. Häired teevadki lülitite kasutamise keerukamaks. Üks peamine meetod määramata olekute vältimiseks on mikrokontrolleri sisend ühendada läbi takisti kas maa- või toitepotentsiaaliga. Sellises funktsioonis olevat takistit nimetatakse inglise keeles kas pull-down või pull-uptakistiks. Tavaliselt ulatub pull-up või pull-down takistite takistus mõnest kilo-oomist ühe mega-oomini. Kui lüliti on avatud, jääb sisendile, millele on ühendatud takisti, pinge, kui lüliti sulgeda, rakendub sisendile lüliti pinge, sest lüliti takistus on palju väiksem (nullilähedane) kui takisti oma. Sisuliselt on tegu pingejaguriga. ![]() Pull-up või pull-down takistiga võib andurina kasutada ka lihtsat kahekontaktilist lülitit, nii et lüliti ühendab sisendi ühe potentsiaaliga ja takisti teisega. Tavaliselt on mikrokontrolleritel ka sisseehitatud pull-up või pull-downtakisti kasutamise võimalus, mistõttu ei pea skeemi eraldi takistit lisamagi. Näiteks AVR mikrokontrollerites on IO viikudel 20 kuni 50 kilo-oomised pull-up takistid. Olgu öeldud, et mehaaniliste lülititega kaasneb siiski veel üks probleem – kontaktide põrkumine. See põhjustab lülitamise hetkel mitmeid väga lühiajalisi väärlülitusi. Seda teemat on käsitletud järgmises peatükis. Selle peatüki näiteid väärlülituse probleem praktiliselt ei mõjuta. Elektrilised ühendusedKasutajaliidese moodul on Kontrollermooduli plaadiga ühendatud porti PA/PC/PG, mis koondab endas 8-viigulisi porte PA ja PC ning 6-viigulist porti PG. Moodul on varustatud kolme nupuga: S1, S2 ja S3, mis on ühendatud vastavalt PC0, PC1, PC2 viikudega. Nuppude teine ots on läbi kaitsetakistite ühendatud maaga (loogiline 0). Moodulil olevad 5 mm LED-id: LED1, LED2 ja LED3 on ühendatud vastavalt PC3, PC4 ja PC5 viikudega. LED-ide teine ots (anood) on ühendatud toitega (loogiline 1). ![]() Tarkvara teekKodulabori teek moodustub mitmetest C-keele päisefailidest (“.h“ laiendiga) ja ühest staatiliselt C-keele teegi failist (“.a“ laiendiga). Teegi installeerimisel kopeeritakse kõik teegi failid AVR-GCC alamkaustadesse, kust kompilaator nad lihtsalt üles leiab. Kasutaja teeki või selle osasid oma rakenduse kausta kopeerima ei pea. Eranditult tuleb igasse teeki kasutavasse projekti kaasata teegi “.a“ fail mis lingitakse kompilaatori poolt projekti kompileeritud failiga. Päisefaile tuleb kaasata vastavalt vajadusele. AVR-iga seotud teegi osade päisefailid asuvad „homelab“ kaustas, Kodulabori moodulitega seotud teegi osad „homelab/module“ kaustas. Nimetatud kaustad asuvad kompilaatori juurkaustas ja neist failide kaasamiseks peab faili nime kirjutama suurendus- ja vähendusmärkide vahel. Näide AVR-i viikude ja Kodulabori Mootorite mooduli teegi kaasamisest: #include <homelab/pin.h>#include <homelab/module/motors.h> Kui Kodulabori teeki ei kasutata, siis on vajalik AVR-i registrite kasutamiseks kaasata projekti: #include <avr/io.h> Teegi kasutamise korral seda eraldi teha ei ole vaja, kuna on kaasatud juba failis pin.h. Tarkvara paigaldamisel kopeeritakse samuti teegi lähtekood, mida on soovi korral võimalik kohandada vastavalt oma projekti vajadustele. Praktiline kasutamineRobootika Kodulabori Kasutajaliidese plaadil on kolm LED-i, mille anoodid on läbi takisti ühendatud +5 V toitega ja katoodid ATmega viikudega pordis PORTC. Selleks et LED-i põlema süüdata ja kustutada, tuleb vastav viik väljundiks defineerida ning seda vastavalt madalaks ja kõrgeks seada. Ehk siis viigu kõrges olekus LED ei põle ja madalas põleb. Põhimõtteliselt võib LED-e ka teistmoodi ühendada, nii et anood on mikrokontrolleri viiguga ja katood maaga ühendatud (kusagil vahel peab ka takisti olema) – sellisel juhul viigu kõrges olekus LED põleb ja madalas olekus ei põle. Peaaegu kõik Kodulabori praktilised näited, kaasa arvatud LED-i süütamise näide, kasutavad Kodulabori viikude teeki. Viikude teegis on andmetüüp pin, mis sisaldab viiguga seotud registrite aadresse ja viigu bitimaski. Kui programmi tekitada pin-tüüpi muutuja ja see kohe programmi alguses makrofunktsiooniga PIN algväärtustada, saab selle muutuja abil viiku kogu programmi ulatuses vabalt kasutada, ilma et peaks oskama registreid kasutada. Järgnevalt on toodud 2 näiteprogrammi, mis teevad täpselt sama asja, kuid üks neist on kirjutatud Kodulabori teegi baasil, teine mitte. Esimene näide kasutab viikude teeki (pin.h fail). Esmalt luuakse programmis pin-tüüpi debug_led-nimeline muutuja, mis hoiab infot LED viigu kohta. Põhiprogrammis toimub selle viigu väljundiks seadmine läbi funktsiooni pin_setup_output ja seejärel selle viigu madalaks määramine funktsiooniga pin_clear, mille tulemusena LED süttib. Teises näites muutujaid ei kasutata, LED-i väljundiks määramine ja süütamine toimub viigu siini C suuna- ja väljundregistrite väärtuste muutmise teel. Mõlemad variandid (teegiga ja ilma teegita kood) toimib täpselt ühte moodi. Vahe on kasutusmugavuses ja programmi koodi loetavuses ehk programmist aruasaamise lihtsuses. Tegelikult võib programmeerimisel kasutada mõlemat varianti ja seda ka ühes programmi koodis läbisegi. Algajatele on üldjuhul teegi kasutamine oluliselt lihtsam, seda eriti, kui tegemist on juba keerukamate funktsioonidega, kui lihtsad digitaalsed sisend-väljundid. Nuppude kasutamise näidiskood põhineb Kodulabori viikude teegil, mida on tutvustatud valgusdioodi näites. Toodud näites on LED-id ja nupud defineeritud massiivina – see võimaldab neid kasutada for tsüklis. Programmi käivitamisel määratakse LED-ide viigud väljundiks ja nuppude viigud sisendiks. Programmisiseses lõputus tsüklis toimub pidev nuppude oleku pärimine ja neile vastavate LED-ide oleku määramine. Esimene nupp süütab rohelise LED-i, teine kollase ja kolmas punase. LISAMATERJAL
Teoreetilise osa algtekstide autor: Raivo Sell ja Mikk Leini |