This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
et:book [2010/02/19 11:36] – external edit 127.0.0.1 | et:book [2023/04/25 12:49] (current) – created - external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Eessõna ====== | ||
- | |||
- | Raamat, mida käes hoiad, on esimene praktiline mikrokontrolleri ja robootika käsiraamat eesti keeles, mis autorite lootuste kohaselt aitab robootikahuvilistel oma teadmisi laiendada ja paremaid lahendusi ehitada ning meelitab uusi huvilisi inseneriteadustega tegelema. Tegemist on just Eesti vajadustest ja situatsioonist lähtuva praktilise abimehega, mida saab kasutada nii koolis, ülikoolis, hobirobootikas kui ka ettevõtetes praktiliste AVR mikrokontrolleritel põhinevate süsteemide õppimisel ja arendamisel. Käsiraamat on suunatud nii õpetajale kui ka õpilasele, aidates mõlemal kiiremini ja tulemuslikumalt soovitud tulemuseni jõuda: õpilastel siis targemaks saada ja õpetajatel oma õppeaine lihtsamalt ja paremini õpilasteni viia :) | ||
- | |||
- | **Platvorm** | ||
- | |||
- | Praktiliste harjutuste konkreetsuse huvides on baasplatvormiks valitud ATmega128 mikrokontrolleril põhinev Mehhatroonika ja Robootika Kodulabori komplekt, mis on paljudes Eesti koolides juba kasutusel. AVR on PIC-i kõrval üks kõige levinumatest mikrokontrolleritest harrastuselektroonikute seas ja see on õppeotstarbeks igati sobilik. | ||
- | |||
- | |||
- | Raamat jaguneb tinglikult viieks osaks: | ||
- | |||
- | **1.** osa teeb kiire sissejuhatuse algajale või meeldetuletuse kogenud elektroonikule lihtsatest, kuid hädavajalikest elektriskeemi arvutusvalemitest. Need valemid ja nende rakendamisoskus tulevad kasuks mitmete praktiliste harjutuste läbimisel. Kiirtutvustus on ka C-keele kohta, mis annab näidete varal ülevaate keele süntaksist. | ||
- | |||
- | **2.** osa annab ülevaate 8-bitilistest AVR seeria mikrokontrolleritest ATmega128 näitel. Peatükk seletab eesti keeles lahti AVR-i andmelehtedes kirjutatu ja on abiks praktiliste harjutuste läbimisel. Algaja võib AVR-i tutvustuse esialgu vahele jätta ja pöörduda selle poole harjutuste käigus, sest tutvustus eeldab üldteadmisi, | ||
- | |||
- | **3.** osa kirjeldab praktiliste tööde aluseks olevat riistvara- ja tarkvaraplatvormi. Viimase juurde kuulub harjutuste jaoks loodud tarkvarateek, | ||
- | |||
- | **4.** osas on praktilised harjutused, mis on konkreetsed näited enam levinud elektroonika- ja elektromehaanikaseadmete kasutamiseks AVR mikrokontrolleriga. Kõik harjutusülesanded on üles ehitatud ja teema järgi grupeeritud nii, et neid oleks õppimisel võimalikult mugav kasutada. Igal harjutuse peatükil on eraldi seadet ja selle tööpõhimõtet selgitav teooriaosa ning praktiline osa, mis õpetab seadet programmi kaudu juhtima. Harjutuste paremaks mõistmiseks on toodud ka lühinimekiri raamatu teistest seotud peatükkidest. Harjutuste gruppide juurde kuuluvad harjutusülesanded, | ||
- | |||
- | **5.** peatükk on samuti hea õppimise abiline, eriti projektitöö puhul. Peatükk näitlikustab, | ||
- | |||
- | Loodame, et raamat on abimeheks nii noorele kui ka vanale robootika- ja mikrokontrollerite huvilisele ning toob mehhatroonika, | ||
- | |||
- | Lumine ja pakasene Tallinn, jaanuar 2010 | ||
- | |||
- | Raivo Sell | ||
- | ====== Mikrokontrollerid ja robootika ====== | ||
- | |||
- | === Mikrokontrollerid === | ||
- | |||
- | [{{ : | ||
- | |||
- | Mikrokontroller on arvuti, mahutatuna ühe kiibi peale (inglise keeles // | ||
- | |||
- | * Kõik funktsioonid on paigutatud ühe kiibi peale väiksemas ja kompaktsemas mahus. | ||
- | * Programmeeritakse kindla ülesande täitmiseks. Funktsionaalsuse muutmiseks tuleb uus tarkvara peale laadida. | ||
- | * Väiksem voolutarve, kuna kõik füüsilised parameetrid on väiksemad ja vähem ressursinõudlikumad kui tavaarvutis. Mikrokontrolleri arendajad rõhuvadki tihti madalale voolutarbele, | ||
- | * Sihtotstarbelised sisendid ja väljundid. Mikrokontrolleritel on välja töötatud perifeeriad, | ||
- | |||
- | Mikrokontrollereid leidub väga palju seadmetes, mida inimesed igapäevaselt kasutavad, näiteks kodutehnika (mikrolaineahi, | ||
- | |||
- | === Robootika === | ||
- | |||
- | Robootika on ala, mis ühendab endas teadmisi ja tehnoloogiat robotite ehitamisest. Tehnoloogia kiire arengu tõttu on aga üha hägustumas mõiste robot kui inimest asendav automaat. Robotina ei saa võtta ainult humanoidrobotit, | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === Mikrokontrollerid robootikas === | ||
- | |||
- | Kuna robootika valdkond on väga lai, siis järgnevalt piiritleme seda kui hobirobootikat, | ||
- | |||
- | * Atmel AVR perekonna mikrokontrollerid (ATmega, ATtiny ja muud) | ||
- | * Microchip Technology PIC perekonna mikrokontrollerid (PIC16, PIC24 ja muud) | ||
- | * ARM tehnoloogial põhinevad mikrokontrollerid | ||
- | |||
- | Väga tihti on kolmandad osapooled loonud arendusplaadid ja -keskkonnad eelnevalt mainitud mikrokontrollerite baasil. Kuna neid on palju, siis tasub välja tuua vaid tuntumad: Arduino (AVR-i baasil), BASIC Stamp (PIC-i baasil) ja Lego NXT (ARM-i baasil). Raamatus lähemalt käsitletavad Kodulabori arendusvahendid on loodud AVR ATmega128 mikrokontrolleri baasil. | ||
- | |||
- | Kuna mikrokontrollereid ja nende baasil loodud arendusplaate on väga palju, siis tekib kindlasti küsimus, et kuidas see kõige sobivam leida. Laias laastus võib vaadeldavad omadused jagada nelja kategooriasse - hind, füüsilised parameetrid, | ||
- | |||
- | * protsessori töösagedus – määrab kiibi töökiiruse | ||
- | * programmimälu maht – kui suure mahuga programmi on võimalik kiibile peale laadida | ||
- | * andmemälu maht – kui suures mahus andmeid on võimalik käsitleda programmis | ||
- | * sisend-väljundviikude arv ja nende funktsioon – erinevatel väljaviikudel on erinevad võimalused | ||
- | * taimerite arv – oluline ajakriteeriumite täitmisel | ||
- | * voolutarve – oluline mobiilsetes lahendustes | ||
- | |||
- | Arenduskeskkonna all mõeldakse PC arvuti tarkvara, mille abil saab kirjutada ja kompileerida programmi, laadida programm mikrokontrollerisse ning siluda programmi töö käigus, et avastada võimalikke vigu. Siinkohal saabki määravaks see, kui mugav ja lihtne on kõiki neid toiminguid teha, kuna programmi väljatöötamise käigus on see põhiline töökeskkond. Siit jõuab ka neljanda kategooria - kasutajatoe - juurde, ehk kui lihtne on saada abi ja toetust võimalike ettetulevate probleemide lahendamiseks. Kõiki neid nelja eespool mainitud kategooriat vaagides peakski sobiva arendusplaadi leidma. | ||
- | ====== Elektroonika ====== | ||
- | |||
- | {{: | ||
- | |||
- | Praktilistes harjutustes on kirjeldatud elektriskeeme, | ||
- | ===== Ohmi seadus ===== | ||
- | |||
- | Ohmi seadust kasutatakse elektrijuhile rakendatud pinge ja juhti läbiva voolutugevuse vahelise sõltuvuse iseloomustamiseks. Iseloomustav tegur on juhi takistus ehk juhi omadus elektrilaengute liikumist takistada. Ohmi seaduse sõnastas Georg Simon Ohm järgmiselt: | ||
- | |||
- | [{{ : | ||
- | |||
- | I = U / R | ||
- | |||
- | kus: | ||
- | |||
- | * I on voolutugevus | ||
- | * U on pinge | ||
- | * R on takistus | ||
- | |||
- | Ohmi seadusest on tuletatud mitmeid teisi valemeid, mida elektroonikas igapäevaselt kasutatakse. | ||
- | ===== Pingejagur ===== | ||
- | |||
- | Pingejagur on elektriahel, | ||
- | |||
- | [{{ : | ||
- | |||
- | U< | ||
- | |||
- | kus: | ||
- | |||
- | * U< | ||
- | * U< | ||
- | * R< | ||
- | |||
- | Valem tuleneb Ohmi seadusest, mille järgi: | ||
- | |||
- | I = U< | ||
- | |||
- | ning: | ||
- | |||
- | U< | ||
- | |||
- | Pingejagurit kasutatakse tihti takistuslike andurite ühendamisel, | ||
- | ===== LED-i takisti arvutamine ===== | ||
- | |||
- | Kui LED-i (valgusdioodi) on vaja toita kõrgema pingega, kui on selle päripinge, ja väiksema vooluga, kui toiteallikas välja annab, tuleb LED-iga järjestikku lisada takisti. Takisti piirab voolu ja tekitab vajaliku pingelangu. Õige takisti väärtuse leidmiseks saab kasutada Ohmi seadust: | ||
- | |||
- | [{{ : | ||
- | |||
- | R = U< | ||
- | |||
- | kus: | ||
- | |||
- | * R on takisti takistus. | ||
- | * U< | ||
- | * U< | ||
- | * U< | ||
- | * I< | ||
- | \\ | ||
- | Kuna takisti valimisel tuleb lähtuda ka selle soojuse eraldamise võimest, siis tuleb leida ka nõutav elektriline võimsus takistil: | ||
- | |||
- | P< | ||
- | |||
- | Kokkuvõtvalt saab öelda, et LED-i voolu piirav takisti peab olema vähemalt sama suure takistusega, | ||
- | |||
- | **Arvutusnäide: | ||
- | |||
- | LED ühendatakse 12 V pingega. Valitud LED-i päripinge on 3 V ja pärivool 20 mA | ||
- | |||
- | I< | ||
- | |||
- | R = (12 - 3) / 0,02 = 450 Ω | ||
- | |||
- | P< | ||
- | |||
- | Lähim standardne takistus on 470 Ω ja võimsus 1/4 W, nii et sellise takisti valimegi. | ||
- | ====== C-keel ====== | ||
- | |||
- | {{: | ||
- | |||
- | Kauaaegne populaarne PC arvutite programmeerimiskeel C on laialt levinud ka mikrokontrollerite programmeerimisel. C on lakooniline riistvaralähedane keel, mis võimaldab kirjutada riistvara võimalusi efektiivselt kasutavat programmikoodi. C-keele süntaksis on võtmesõnu minimaalselt, | ||
- | ===== Kiirkursus ===== | ||
- | |||
- | ==== Programmi ülesehitus ==== | ||
- | |||
- | Põhimõtteliselt võib C-keele programmi kirjutada ükskõik mis kujul, kas või üherealisena, | ||
- | |||
- | <code c> | ||
- | /* Päisefailide kaasamine */ | ||
- | #include < | ||
- | #include < | ||
- | |||
- | /* Makro-deklaratsioonid */ | ||
- | #define PI 3.141 | ||
- | |||
- | /* Andmetüübid */ | ||
- | typedef struct | ||
- | { | ||
- | int a, b; | ||
- | } | ||
- | element; | ||
- | |||
- | /* Globaalsed muutujad */ | ||
- | element e; | ||
- | |||
- | /* Funktsioonid */ | ||
- | int main(void) | ||
- | { | ||
- | // Lokaalsed muutujad | ||
- | int x; | ||
- | |||
- | // Programm | ||
- | printf(" | ||
- | } | ||
- | </ | ||
- | |||
- | ==== Kommentaarid ==== | ||
- | |||
- | Programmi saab kirjutada teksti, mida ei kompileerita ja mis on programmeerijale abiks selgitamisel või märkmete tegemisel. Samuti saab kommentaare kasutada programmilõikude ajutiseks täitmisest kõrvaldamiseks. Näide kahte liiki kommentaaridest: | ||
- | |||
- | <code c> | ||
- | // Üherealine kommentaar. | ||
- | // Kommentaariks loetakse kahe kaldkriipsu järel olevat teksti | ||
- | |||
- | /* | ||
- | Mitmerealine kommentaar | ||
- | Kommentaari algus ja lõpp määratakse kaldkriipsude ja tärnidega | ||
- | */ | ||
- | </ | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | ==== Andmed ==== | ||
- | |||
- | === Andmetüübid === | ||
- | |||
- | C-keele baasandmetüübid: | ||
- | |||
- | ^ Tüüp | ||
- | | (signed) char | -128 | 127 | 8 | 1 | | ||
- | | unsigned char | 0 | 255 | 8 | 1 | | ||
- | | (signed) short | -32768 | ||
- | | unsigned short | 0 | 65535 | 16 | 2 | | ||
- | | (signed) long | -2147483648 | 2147483647 | 32 | 4 | | ||
- | | unsigned long | 0 | 4294967295 | 32 | 4 | | ||
- | | float | -3.4< | ||
- | | double | ||
- | |||
- | Sulgudes olevat sõna " | ||
- | |||
- | AVR mikrokontrolleril //int// = //short// \\ | ||
- | PC arvutil //int// = //long// \\ | ||
- | |||
- | C-keeles puudub spetsiaalne teksti-andmetüüp. Selle asemel kasutatakse //char// tüüpi massiive (nendest edaspidi) ja ASCII " | ||
- | |||
- | === Muutujad === | ||
- | |||
- | Programmis saab kasutada kindlat andmetüüpi mälupesasid - muutujaid. Muutujate nimed võivad sisaldada ladina tähestiku tähti, numbreid ja alakriipsu. Nimi ei tohi alata numbriga. Muutuja deklareerimisel kirjutatakse selle ette andmetüüp. Väärtuse omistamiseks muutujale kasutatakse võrdusmärki (=). Näide muutujate kasutamisest: | ||
- | |||
- | <code c> | ||
- | // char tüüpi muutuja c deklareerimine | ||
- | char c; | ||
- | |||
- | // Muutujale c väärtuse omistamine. | ||
- | c = 65; | ||
- | c = ' | ||
- | |||
- | // int tüüpi muutuja i20 deklareerimine ja algväärtustamine | ||
- | int i20 = 55; | ||
- | |||
- | // Mitme unsigned short tüüpi muutuja deklareerimine | ||
- | unsigned short x, y, test_variable; | ||
- | </ | ||
- | |||
- | === Konstandid === | ||
- | |||
- | Konstante deklareeritakse samamoodi nagu muutujaid, kuid ette lisatakse //const// võtmesõna. Konstantide väärtust ei saa programmi käigus muuta. Näide kasutamisest: | ||
- | |||
- | <code c> | ||
- | // int tüüpi konstandi määramine | ||
- | const int x_factor = 100; | ||
- | </ | ||
- | |||
- | === Struktuurid === | ||
- | |||
- | Baasandmetüüpidest saab //struct// võtmesõnaga struktuure koostada. Struktuur on justkui kombineeritud andmetüüp. Tüüpi deklareeritakse //typedef// võtmesõnaga. Näide struktuurist andmetüübi loomise ja kasutamise kohta: | ||
- | |||
- | <code c> | ||
- | // Uue punkti andmetüübi deklareerimine | ||
- | typedef struct | ||
- | { | ||
- | // x ja y koordinaat ning värvikood | ||
- | int x, y; | ||
- | char color; | ||
- | } | ||
- | point; | ||
- | |||
- | // Punkti muutuja deklareerimine | ||
- | point p; | ||
- | |||
- | // Punkti koordinaatide määramine | ||
- | p.x = 3; | ||
- | p.y = 14; | ||
- | </ | ||
- | |||
- | === Massiivid === | ||
- | |||
- | Andmetüüpidest võib koostada massiive (jadasid). Massiiv võib olla ka mitmemõõtmeline (tabel, kuup, jne). Näide ühe- ja kahemõõtmelise massiivi kasutamisest: | ||
- | |||
- | <code c> | ||
- | // Ühe- ja kahemõõtmelise massiivi deklareerimine | ||
- | char text[3]; | ||
- | int table[10][10]; | ||
- | |||
- | // Teksti moodustamine tähemassiivist | ||
- | text[0] = ' | ||
- | text[1] = ' | ||
- | text[2] = 0; // Teksti lõpetamise tunnus (null-bait) | ||
- | |||
- | // Tabeli ühe elemendi muutmine | ||
- | table[4][3] = 1; | ||
- | </ | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | ==== Avaldised ==== | ||
- | |||
- | Muutujate, konstantide ja väärtust tagastavate funktsioonidega saab koostada avaldisi (tehteid). Avaldise väärtusi saab omistada muutujatele, | ||
- | |||
- | === Aritmeetilised === | ||
- | |||
- | C-keeles toetatud aritmeetilised tehted on liitmine (+), lahutamine (-), korrutamine (*), jagamine (/) ja mooduli võtmine (%). Näited aritmeetiliste tehete kasutamisest: | ||
- | |||
- | <code c> | ||
- | int x, y; | ||
- | |||
- | // Mooduli võtmine, korrutamine ja väärtuse omistamine | ||
- | // x saab väärtuse 9 | ||
- | x = (13 % 5) * 3; | ||
- | |||
- | // Liitev-omistav operaator | ||
- | // x väärtuseks saab 14 | ||
- | x += 5; | ||
- | |||
- | // Ühe lahutamise kiirmeetod | ||
- | // x väärtuseks saab 13 | ||
- | x--; | ||
- | </ | ||
- | |||
- | === Loogilised === | ||
- | |||
- | Loogilised tehted on eitus (!), loogiline korrutamine (&& | ||
- | |||
- | <code c> | ||
- | bool a, b, c; | ||
- | |||
- | // Algväärtustamine | ||
- | a = true; | ||
- | b = false; | ||
- | |||
- | // Eitus | ||
- | // c väärtus tuleb väär sest tõest eitati | ||
- | c = !a; | ||
- | |||
- | // Loogiline korrutamine | ||
- | // c väärtuseks tuleb väär, sest üks operandidest on väär | ||
- | c = a && b; | ||
- | |||
- | // Loogiline liitmine | ||
- | // c väärtus tuleb tõene, sest üks operandidest on tõene | ||
- | c = a || b; | ||
- | </ | ||
- | |||
- | **NB!** //bool// andmetüüp C-keeles tegelikult puudub, selle asemel on kasutusel täisarvud, kus 0 tähistab väära ja iga muu arv tõest väärtust. Näiteks Kodulabori teegis on defineeritud //bool// kui //unsigned char//. Konstant //true// tähistab seal väärtust 1 ja //false// väärtust 0. | ||
- | |||
- | === Võrdlused === | ||
- | |||
- | Arvude väärtuste võrdlemisel saadakse loogilised väärtused. Võrdlustehted on samaväärsus (=), erinevus (!=), suurem (>), suurem-võrdne (>=), väiksem (<) ja väiksem-võrdne (<=). Näide kasutamisest: | ||
- | |||
- | <code c> | ||
- | int x = 10, y = 1; | ||
- | |||
- | // Suurem-kui võrdlustehe, | ||
- | // Tehte ümber on sulud vaid selguse pärast | ||
- | bool b = (5 > 4); | ||
- | |||
- | // Erinevuse tehe | ||
- | // Tehte tulemus on väär | ||
- | b = (4 != 4); | ||
- | |||
- | // Aritmeetiline, | ||
- | // b tuleb väär, sest esimene loogilise korrutise operand on väär | ||
- | b = (x + 4 > 15) && (y < 4); | ||
- | </ | ||
- | |||
- | === Bititehted === | ||
- | |||
- | Bititehted on andmetega binaarses arvusüsteemis tegelemiseks. Neid saab rakendada kõigi täisarv-tüüpi andmetega. Bititehted sarnanevad loogiliste tehetega, kuid erinevad selle poolest, et tehe teostatakse iga bitiga eraldi, mitte kogu arvuga. C keeles on bititeheteks inversioon (~), konjunktsioon (&), disjunktsioon (|), antivalentsus (^), nihe vasakule (<<) ja nihe paremale (>>). | ||
- | |||
- | <code c> | ||
- | // Märgita 8-bitise char-tüüpi muutuja deklareerimine | ||
- | // Muutuja väärtus on kümnendsüsteemis 5, kahendsüsteemis 101 | ||
- | unsigned char c = 5; | ||
- | |||
- | // Muutuja c disjunktsioon arvuga 2 (kahendsüsteemis 010) | ||
- | // c väätuseks saab 7 (kahendsüsteemis 111) | ||
- | c = c | 2; | ||
- | |||
- | // Bitinihe vasakule 2 võrra | ||
- | // c väärtuseks saab 28 (kahendsüsteemis 11100) | ||
- | c = c << 2; | ||
- | </ | ||
- | |||
- | Bititehted on hädavajalikud mikrokontrollerite registrite kasutamisel. Täpsemalt tutvustab neid AVR registrite peatükk. | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | ==== Funktsioonid ==== | ||
- | |||
- | Funktsioon on programmilõik, | ||
- | |||
- | <code c> | ||
- | // Kahe int tüüpi parameetriga funktsiooni deklareerimine | ||
- | // Funktsioon tagastab int-tüüpi väärtuse | ||
- | int sum(int a, int b) | ||
- | { | ||
- | // Kahe arvu liitmine ja summa tagastamine | ||
- | return a + b; | ||
- | } | ||
- | |||
- | // Ilma parameetrite ja tagastatava väärtuseta funktsioon | ||
- | void power_off(void) | ||
- | { | ||
- | } | ||
- | </ | ||
- | |||
- | Funktsiooni kasutamiseks tuleb see välja kutsuda. Funktsioon peab programmikoodis olema deklareeritud enne välja kutsumise kohta. Näide liitmisfunktsiooni väljakutsumisest. | ||
- | |||
- | <code c> | ||
- | int x; | ||
- | int y = 3; | ||
- | |||
- | // Liitmisfunktsiooni väljakutsumine | ||
- | // Parameetriteks on muutuja ja konstandi väärtus | ||
- | x = sum(y, 5); | ||
- | |||
- | // Väljalülitamise funktsiooni väljakutsumine | ||
- | // Parameetrid puuduvad | ||
- | power_off(); | ||
- | </ | ||
- | |||
- | C-keele programmi täitmist alustatakse //main// nimelisest funktsioonist, | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | ==== Laused ==== | ||
- | |||
- | === Tingimuslause === | ||
- | |||
- | Tingimuslause võimaldab vastavalt sulgudes oleva avaldise tõesusele täita või mitte täita tingimusele järgnevat lauset või programmilõiku. Tingimuslause võtmesõna on //if//. Näide kasutamisest: | ||
- | |||
- | <code c> | ||
- | // Avaldis on tõene ja lause x = 5 täidetakse, | ||
- | // sest 2 + 1 on suurem kui 2 | ||
- | if ((2 + 1) > 2) x = 5; | ||
- | |||
- | // Kui x on 5 ja y on 3, siis täidetakse järgnev programmilõik | ||
- | if ((x = 5) && (y = 3)) | ||
- | { | ||
- | // Suvaline tegevus | ||
- | y = 4; | ||
- | my_function(); | ||
- | } | ||
- | </ | ||
- | |||
- | Tingimuslause võib olla pikem ja sisaldada ka lauset või programmilõiku, | ||
- | |||
- | <code c> | ||
- | // Kas x on 5 ? | ||
- | if (x = 5) | ||
- | { | ||
- | // Suvaline tegevus | ||
- | z = 3; | ||
- | } | ||
- | // Kui x ei olnud 5, kas siis x on 6 ? | ||
- | else if (x = 6) | ||
- | { | ||
- | // Suvaline tegevus | ||
- | q = 3; | ||
- | } | ||
- | // Kui x ei olnud 5 ega 6... | ||
- | else | ||
- | { | ||
- | // Suvaline tegevus | ||
- | y = 0; | ||
- | } | ||
- | </ | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === Valikulause === | ||
- | |||
- | Kui on vaja võrrelda avaldist mitme erineva väärtusega, | ||
- | |||
- | <code c> | ||
- | int y; | ||
- | |||
- | // Tingimuslause y võrdlemiseks | ||
- | switch (y) | ||
- | { | ||
- | // y on 1 ? | ||
- | case 1: | ||
- | // Suvaline tegevus | ||
- | function1(); | ||
- | break; | ||
- | |||
- | // y on 2 ? | ||
- | case 2: | ||
- | // Suvaline tegevus | ||
- | function2(); | ||
- | break; | ||
- | |||
- | // Kõik muud juhtumid | ||
- | default: | ||
- | // Suvaline tegevus | ||
- | functionX(); | ||
- | // break lauset pole vaja, | ||
- | // kuna võrdlemine lõppeb nagunii | ||
- | } | ||
- | </ | ||
- | |||
- | ==== Tsüklid ==== | ||
- | |||
- | Tsüklitega saab programmilõiku täita mitmeid kordi. | ||
- | |||
- | === while === | ||
- | |||
- | //while// võtmesõnaga tähistatud programmilõiku täidetakse seni, kuni sulgudes olev avaldis on tõene. | ||
- | |||
- | <code c> | ||
- | int x = 0; | ||
- | |||
- | // Tsükkel kestab seni, kuni x on väiksem kui 5 | ||
- | while (x < 5) | ||
- | { | ||
- | // x suurendamine ühe võrra | ||
- | x++; | ||
- | } | ||
- | </ | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === for === | ||
- | |||
- | //for// võtmesõnaga tsükkel sarnaneb //while// tsüklile, kuid lisaks on sulgudes ära määratud enne tsüklit täidetav lause ja iga tsükli ajal täidetav lause. | ||
- | |||
- | Näide: | ||
- | <code c> | ||
- | int i, x = 0; | ||
- | |||
- | // Algul määratakse i nulliks. Tsüklit täidetaks seni, kuni | ||
- | // i on vähem kui 5. Iga tsükli lõpus suurendatakse i ühe võrra | ||
- | for (i = 0; i < 5; i++) | ||
- | { | ||
- | // x suurendamine 2 võrra | ||
- | x += 2; | ||
- | } | ||
- | |||
- | // Siinkohal tuleb x väärtuseks 10 | ||
- | </ | ||
- | |||
- | === Tsüklis liikumine === | ||
- | |||
- | //while// ja //for// tsüklitest saab erandkorras väljuda //break// võtmesõnaga. // | ||
- | |||
- | <code c> | ||
- | int x = 0, y = 0; | ||
- | |||
- | // Lõputu tsükkel, kuna 1 on loogiline tõesus | ||
- | while (1) | ||
- | { | ||
- | // Tsüklist väljutakse, | ||
- | if (x >= 100) break; | ||
- | |||
- | // x suurendamine, | ||
- | x++; | ||
- | |||
- | // Kui x on 10 või vähem, siis alustatakse järgmist tsüklit | ||
- | if (x <= 10) continue; | ||
- | |||
- | // y suurendamine | ||
- | y++; | ||
- | } | ||
- | |||
- | // Siinkohal on y väärtus 90 | ||
- | </ | ||
- | |||
- | ====== AVR mikrokontroller ====== | ||
- | |||
- | {{: | ||
- | |||
- | Järgnevad peatükid tutvustavad AVR mikrokontrollerit, | ||
- | ===== Tutvustus ===== | ||
- | |||
- | [{{ : | ||
- | |||
- | AVR on Atmeli poolt toodetav 8-bitiste RISC mikrokontrollerite seeria. Harvardi arhitektuuri kohaselt on AVR-il eraldi programmi- ja andmemälu. Programmi jaoks on süsteemisiseselt ümberkirjutatav välkmälu (inglise keeles //Flash//), andmete jaoks staatiline (SRAM) ja EEPROM mälu. Taktsagedus ulatub enamasti kuni 16 MHz ja jõudlus on peaaegu 1 MIPS megahertsise takti kohta. | ||
- | |||
- | AVR mikrokontrollerite tootmist alustati 1997. aastal ja praeguseks on see vabakutseliste elektroonikute seas üks levinumaid. Esialgse edu tagasid odavad arendusvahendid, | ||
- | |||
- | Vastavalt rakenduste tüübile on ka AVR mikrokontrollereid olemas erineva konfiguratsiooniga. Suurema osa AVR-e moodustab megaAVR seeria, mis on suure programmimälu mahuga. Vastupidiselt megaAVR seeriale on olemas tinyAVR seeria väiksemate kestade ja kärbitud võimalustega. Lisaks on veel mikrokontrollerite seeriad spetsiaalselt USB, CAN, LCD, ZigBee, automaatika, | ||
- | |||
- | Järgnevalt on kirjeldatud peamisi megaAVR seeria mikrokontrollerite võimalusi selle seeria ühe levinuima kontrolleri - ATmega128 näitel, mis on kasutusel ka Kodulabori komplektis. Üldiselt on kõigil AVR seeria mikrokontrolleritel registrite nimed, tähendused ja kasutamise kord reglementeeritud nii, et näiteid saab väikeste muudatustega ka teiste kontrollerite puhul kasutada. Peamised erinevused esinevad perifeeria juures. Tutvustuse koodinäited on toodud assembleris ja C-keeles AVR LibC abil. | ||
- | |||
- | === Füüsiline kuju === | ||
- | |||
- | [{{: | ||
- | |||
- | Nagu kõik teisedki kiibid, on AVR pakendatud mingi standardkesta sisse. Traditsiooniline kest on DIP (nimetatakse ka DIL). DIP on nii-öelda jalgadega kest - kõik kiibi viigud on umbes 5-millimeetriste jalgadena näpuotsasuurusest mustast plastist korpusest välja toodud. DIP kest on mõistlik valik hobirakendustes ja prototüüpide puhul, sest selle jaoks on saada odavad pesad, kust saab mikrokontrolleri läbipõlemise korral lihtsalt kätte ja uuega asendada. Samas on jalad ka DIP kesta miinuseks, sest nende jaoks on vaja trükiplaadile auke puurida. | ||
- | |||
- | Palju kompaktsemad on pindliides ehk SMT (nimetatakse ka SMD) kestad, sest neil on jalad mõeldud mitte plaadi läbistamiseks, | ||
- | |||
- | AVR-e on saada nii DIP kui SMT kestades. Viikusid on püütud loogiliselt ning elektriliselt ühtlaselt paigutada. Näiteks on maa ja toiteviigud suurematel kiipidel toodud mitmesse kiibi külge, välise kvartsi viigud on maa viigu lähedal, siinide viigud on numbrilises järjekorras, | ||
- | |||
- | == ATmega128 == | ||
- | |||
- | Et järgnevatest näidetest ATmega128 kohta paremini aru saada, on välja toodud ATmega128 SMT kesta viikude skeem. Viikude juures on selle number, primaarne funktsioon ja sulgudes alternatiivne funktsioon. Toiteotsad on GND ja VCC. AVCC ja AREF on vastavalt analoog-digitaalmuunduri toite ja võrdluspinge viigud. XTAL1 ja XTAL2 on välise kvartsostsillaatori, | ||
- | |||
- | [{{ : | ||
- | ===== Registrid ===== | ||
- | |||
- | Üks kõige raskemini mõistetavaid asju mikrokontrollerite juures on algajate jaoks tavaliselt " | ||
- | |||
- | === Olemus === | ||
- | |||
- | [{{ : | ||
- | |||
- | Register on nagu mõne kodumasina nuppude paneel. Seal on lülitid, mida saab sisse vajutada või välja lükata. Üks parim näide on kassetimängija. Kes veel mäletab, siis kassetimängijatel on (oli) vasakult paremale 6 nuppu: | ||
- | |||
- | * Salvestamine | ||
- | * Tagasikerimine | ||
- | * Mängimine | ||
- | * Edasikerimine | ||
- | * Stopp | ||
- | * Paus | ||
- | |||
- | Iga nupp teeb midagi, kuid ainult õigel kasutamisel. Näiteks stopp-nupp ei tee midagi enne, kui kassett on mängima pandud - alles siis teeb see midagi arusaadavat ja peatab mängimise. Edasi- või tagasikerimise nuppe võib aga igal ajal vajutada, sest linti hakatakse kerima nii poole mängimise kui seismise ajal. Salvestama hakkab kassetimängija aga ainult siis, kui salvestamise nupp koos mängimise nupuga alla vajutada. Mõni on ehk proovinud mitu nuppu või kõik nupud korraga alla vajutada - sel juhul võis mängija mida iganes teha või üldse katki minna. | ||
- | |||
- | Mikrokontrolleri registriga on sama lugu nagu kassetimängija nuppudega - iga nupuke paneb seal õigel kasutamisel midagi käima. Valesid nuppe vajutades mikrokontroller (enamasti) küll katki ei lähe, kuid ei tööta ka. Tegelikult registris selliseid nuppe nagu kodumasinatel muidugi pole, on hoopis hulk transistore, | ||
- | |||
- | [{{ : | ||
- | |||
- | 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, | ||
- | |||
- | Kui kassetimängijal võib igat nuppu eraldi vajutada, siis registrites on ühe " | ||
- | |||
- | === Kasutamine === | ||
- | |||
- | C-keele programmis registri väärtuse kirjutamiseks või lugemiseks tuleb selle poole pöörduda nagu muutuja poole. Järgnev näide demonstreerib väljamõeldud registrisse REG binaarväärtuse kirjutamist ja selle väärtuse muutujasse //reg// lugemist. Binaarväärtuse ette kirjutatakse 0b (ees on null), et kompilaator arvusüsteemist aru saaks. | ||
- | |||
- | <code c> | ||
- | REG = 0b01100001; | ||
- | unsigned char reg = REG; | ||
- | </ | ||
- | |||
- | Põhimõtteliselt registrite väärtuse kirjutamises ja lugemises midagi keerulist polegi, kuid keerulisemaks läheb lugu siis, kui soovitakse muuta registri üksikute bittide väärtust. Bittide muutmiseks tuleb enne selgeks saada binaartehted ja erinevad arvusüsteemid. Keegi ei keela tegutseda binaararvudega, | ||
- | |||
- | [{{ : | ||
- | |||
- | Heksadetsimaalarvus pole numbrid mitte 0 ja 1, nagu binaarsüsteemis, | ||
- | |||
- | Üksikute bittide muutmiseks arvus (registris, muutujas või kus iganes) tuleb kasutada binaartehteid. Binaartehe on tehe binaararvude vahel, kus nende arvude iga biti vahel toimub omaette loogikatehe. Enamasti on mikrokontrollerites kasutusel neli binaartehet, | ||
- | |||
- | [{{ : | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | * **Eitus / Inversioon** \\ Eitus muudab biti väärtuse vastupidiseks ehk 0 muutub 1 ja 1 muutub 0. C-keeles on eituse märk " | ||
- | * **Loogiline korrutamine / Konjunktsioon** \\ Kahte bitti korrutades on vastus 1, kui mõlemad bitid olid 1, muul juhul on vastus 0. C-keeles on korrutamise märk "&" | ||
- | * **Loogiline liitmine / Disjunktsioon** \\ Kahe biti liitmisel on vastus 1, kui vähemalt ühe biti väärtus oli 1, muul juhul on vastus 0. C-keeles on liitmise märk " | ||
- | * **Mittesamaväärsus / Välistav disjunktsioon** \\ Kahe bitiga mittesamaväärsuse tehte korral on vastus 1, kui bittide väärtused teineteisest erinevad, muul juhul on vastus 0. C-keeles on mittesamaväärsuse märk " | ||
- | |||
- | Nüüd on lühidalt selgitatud kõik, mida läheb vaja üksikute bittide väärtuste muutmiseks. Kuid ilmselt jääb teooriast ikkagi väheks ja seepärast on järgnevalt toodud mõningad tüüpnäited registritega. | ||
- | |||
- | ~~CL~~ | ||
- | |||
- | == Üksiku biti kõrgeks seadmine == | ||
- | |||
- | [{{ : | ||
- | |||
- | Selleks et üks või enam bitte registris kõrgeks ehk üheks seada, tuleb kasutada loogilist liitmise tehet. Liitmistehte üks operand peab olema register, teine binaararv, kus kõrge on ainult see bitt, mida ka registris soovitakse kõrgeks seada. Seda teist binaararvu nimetatakse ka bitimaskiks. Kõrvalnäites toodud tehe näeb C-keeles välja niimoodi: | ||
- | |||
- | ~~CL~~ | ||
- | |||
- | <code c> | ||
- | // Oletame, et REG = 0x0F | ||
- | REG = REG | 0x11; // Üks meetod | ||
- | REG |= 0x11; // Teine meetod | ||
- | // Siinkohal REG = 0x1F | ||
- | </ | ||
- | |||
- | == Üksiku biti madalaks seadmine == | ||
- | |||
- | [{{ : | ||
- | |||
- | Ühe või enama biti registris madalaks ehk nulliks seadmiseks tuleb kasutada loogilise korrutamise tehet. Tehte üks operand peab olema register, teine bitimask, kus madalaks on seatud vaid see bitt, mida ka registris soovitakse madalaks seada. Kõrvalnäites toodud tehe näeb C-keeles välja nii: | ||
- | |||
- | ~~CL~~ | ||
- | |||
- | <code c> | ||
- | // Oletame, et REG = 0x0F | ||
- | REG = REG & 0xFE; // Üks meetod | ||
- | REG &= 0xFE; // Teine meetod | ||
- | // Siinkohal REG = 0x0E | ||
- | </ | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | == Üksiku biti inverteerimine == | ||
- | |||
- | [{{ : | ||
- | |||
- | Ühe või enama biti registris inverteerimiseks tuleb kasutada mittesamaväärsuse tehet. Tehte üks operand peab olema register, teine bitimask, kus kõrgeks on seatud vaid see bitt, mida ka registris soovitakse inverteerida. Kõrvalnäites toodud tehe näeb C-keeles välja järgmiselt: | ||
- | |||
- | ~~CL~~ | ||
- | |||
- | <code c> | ||
- | // Oletame, et REG = 0x0F | ||
- | REG = REG ^ 0x11; // Üks meetod | ||
- | REG ^= 0x11; // Teine meetod (rakendada tohib korraga ainult üht) | ||
- | // Siinkohal REG = 0x1E | ||
- | </ | ||
- | |||
- | == Kogu registri inverteerimine == | ||
- | |||
- | [{{ : | ||
- | |||
- | Kogu registri bittide inverteerimiseks tuleb kasutada eitustehet. See on unaarne tehe ehk tal on ainult üks operand. Kõrvalnäites toodud tehe näeb C-keeles välja niimoodi: | ||
- | |||
- | ~~CL~~ | ||
- | |||
- | <code c> | ||
- | // Oletame, et REG = 0x0F | ||
- | REG = ~REG; | ||
- | // Siinkohal REG = 0xF0 | ||
- | </ | ||
- | |||
- | == Üksiku biti väärtuse lugemine == | ||
- | |||
- | [{{ : | ||
- | |||
- | Ühe või enam biti väärtuse lugemiseks registrist tuleb kasutada sama tehet, mis biti nullimisel - loogilist korrutamist. Tehte üks operand peab olema register, teine bitimask, kus kõrgeks on seatud vaid see bitt, mille väärtust registrist lugeda soovitakse. Kõrvalnäites toodud tehe näeb C-keeles välja järgmiselt: | ||
- | |||
- | ~~CL~~ | ||
- | |||
- | <code c> | ||
- | // Oletame, et REG = 0x0F | ||
- | unsigned char x = REG & 0x01; | ||
- | // Siinkohal x = 0x01 | ||
- | </ | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | == Biti nihutamine == | ||
- | |||
- | Tegelikult on paljudes programmeerimiskeeltes peale binaartehete veel mõned bitioperatsioonid, | ||
- | |||
- | [{{ : | ||
- | |||
- | Kõrvaloleval pildil on toodud näide bitinihutuse operatsioonist vasakule. Bitinihutus pole loogikaoperatsioon ja sel puudub vastav tähis, C-keeles on see aga "<<" | ||
- | |||
- | ~~CL~~ | ||
- | |||
- | <code c> | ||
- | REG = 0x01 << 5; | ||
- | // Siinkohal REG = 0x20 | ||
- | </ | ||
- | |||
- | [{{ : | ||
- | |||
- | Sarnaselt bitinihkega vasakule toimib ka bitinihke operatsioon paremale. Selle operatsiooni tähis C-keeles on ">>" | ||
- | |||
- | ~~CL~~ | ||
- | |||
- | <code c> | ||
- | // Oletame, et REG väärtus on 0x20 | ||
- | unsigned char x = REG >> 5; | ||
- | // Siinkohal on x väärtus 0x01 (ehk lihtsalt 1) | ||
- | </ | ||
- | |||
- | Kui bitinihke operatsioonidega nihkub bitt madalaimast järgust paremale või kõrgeimast järgust vasakule, siis see bitt kaob. Mõnedes programmeerimiskeeltes on olemas ka roteeruvad bitinihke operatsioonid, | ||
- | |||
- | Kõik toodud bitioperatsioonide näited toimivad peale registrite ka muutujatega ja konstantidega. Viimased saavad muidugi ainult operandideks, | ||
- | |||
- | === AVR registrid === | ||
- | |||
- | Selleks et midagi reaalselt mikrokontrolleri registritega teha saaks, tuleb osata selle mikrokontrolleriga läbi saada. Kõigi mikrokontrolleritega käib kaasas üks või mitu andmelehte, kus on dokumenteeritud kogu mikrokontrolleri struktuur ja funktsionaalsus. Andmelehes on kirjeldatud ka registrid. Järgnevalt uurime, kuidas saada aru AVR-i andmelehe registrite kirjeldusest. | ||
- | |||
- | [{{ : | ||
- | |||
- | Pildil on toodud ATmega128 mikrokontrolleri register UCSRnA, mille pikem nimetus on "// | ||
- | |||
- | Registri sisu tähistab paksu piirjoonega 8 lahtriga kast. Iga lahter tähistab üht bitti. Kasti kohal on toodud biti järgud - suurenevad paremalt vasakule. Kuna AVR on 8-bitine mikrokontroller, | ||
- | |||
- | Registri bittide all on toodud kaks rida, kus on kirjas, kas bitt on loetav (R), kirjutatav (W) või mõlemat (R/W). Näiteks olekubitte ei saa üle kirjutada ja isegi siis, kui seda programmis üritada, ei omanda bit lihtsalt talle omistatavat väärtust. Biti puhul, mida saab ainult kirjutada, on öeldud üks kindel väärtus, mis selle lugemisel alati tuleb. Bittide all teises reas on toodud vaikeväärtus, | ||
- | |||
- | Kui AVR-i registrite nimed viitavad tegelikult mälupesade aadressidele, | ||
- | |||
- | <code c> | ||
- | // TXC0 biti kõrgeks seadmine | ||
- | UCSR0A |= (1 << TXC0); | ||
- | |||
- | // U2X0 biti madalaks seadmine | ||
- | UCSR0A &= ~(1 << U2X0); | ||
- | |||
- | // UDRE0 biti(maski) väärtuse lugemine | ||
- | unsigned char u = (UCSR0A & (1 << UDRE0)); | ||
- | |||
- | // Siinkohal on u väärtus kas 0 või 32, | ||
- | // mis võimaldab seda loogilises avaldises kasutada | ||
- | if (u) | ||
- | { | ||
- | // MPCM0 biti inverteerimine | ||
- | | ||
- | } | ||
- | |||
- | // Mõnikord on aga vaja saada konkreetne 0 või 1 väärtus, | ||
- | // selleks tuleb loetud bitti nihutada paremale | ||
- | u >>= UDRE0; | ||
- | |||
- | // Siinkohal on u väärtus kas 0 või 1 | ||
- | </ | ||
- | |||
- | ===== Arhitektuur ===== | ||
- | |||
- | AVR-il on sisemine 8-bitine andmesiin, mille kaudu liiguvad andmed arvutusüksuse (ALU), olekuregistri (SREG), programmiloenduri (PC), muutmälu (SRAM) ja perifeeria vahel. ALU-s täitmisele minev programm ehk instruktsioonide jada tuleb välkmälu aadressilt, mille määrab programmiloendur. ALU juurde kuuluvad 32 üldkasutatavat 8-bitist registrit, mida kasutatakse paljude instruktsioonide täitmisel operandidena. | ||
- | |||
- | [{{ : | ||
- | |||
- | === Käsukonveier === | ||
- | |||
- | AVR-i käsukonveier on kaheastmeline. Samal ajal kui üht instruktsiooni täidetakse, | ||
- | |||
- | === Üldkasutatavad registrid === | ||
- | |||
- | Üldkasutatavad registrid R0-R31 on justkui vahepuhvrid mälu ja perifeeria andmete hoidmiseks ning nendega toimetamiseks. Üldkasutatavad registrid lihtsustavad protsessori arhitektuuri, | ||
- | |||
- | Assemblerkeeles programmeerides võib kiiret töötlust vajavaid andmeid üldkasutatavates registrites hoida. Kui programmeeritakse C-keeles ja on kindel soov muutuja hoidmiseks üldkasutatavat registrit kasutada, defineeritakse muutuja täiendavalt " | ||
- | |||
- | <code c> | ||
- | register char x; | ||
- | </ | ||
- | |||
- | === Käsustik === | ||
- | |||
- | Enamiku AVR-ide käsustik koosneb 90-133 erinevast instruktsioonist. ATmega128-l on 133 instruktsiooni. Instruktsioonid on kas ühe, kahe või üldse ilma operandideta. Enamik instruktsioone täidab mikrokontrolleri protsessor ühe takti jooksul, kuid keerukamad kulutavad kuni 5 takti. AVR-i järeltulija XMega puhul on mitmeid instruktsioone täiendatud nii, et need kulutavad vähem takte. Suurem osa AVR-i instruktsioonidest on siireteks, andmete liigutamiseks, | ||
- | |||
- | <box 100% round # | ||
- | |||
- | Toodud on Assembleris ehk puhtalt instruktsioonidena kirjutatud kood, mis liidab muutmälus aadressil $100 (detsimaalarvuna 256) asuvale baidile juurde arvu 5. Kasutatud käsud on olemas kõigil AVR-idel. | ||
- | |||
- | <code asm> | ||
- | ldi r1, 5 ; Konstandi 5 laadimine üldkasutatavasse registrisse r1 | ||
- | lds r2, $100 ; Baidi laadimine muutmälust registrisse r2 | ||
- | add r2, r1 ; Registrile r2 registri r1 väärtuse liitmine | ||
- | sts $100, r2 ; Registri r2 väärtuse kirjutamine tagasi muutmällu | ||
- | </ | ||
- | |||
- | </ | ||
- | |||
- | === Programmi pinumälu === | ||
- | |||
- | Pinumälu (inglise keeles //stack//) on andmete ülesehitus, | ||
- | |||
- | MegaAVR seeria mikrokontrolleritel on pinumälu füüsiline asukoht muutmälus, kuid mõnel tinyAVR seerial muutmälu üldse puudub ja pinumälu tarbeks on spetsiaalne üsna piiratud mahuga mälu. Sellistele, ilma muutmäluta mikrokontrolleritele kompilaatoreid üldjuhul pole. | ||
- | |||
- | Kõrgtaseme keeles (Pascal, C, C++) programmeerides ei pea otseselt mikrokontrolleri siseeluga kursis olema, sest kompilaator valib ise vastavalt vajadusele üldkasutavaid registreid ja instruktsioone, | ||
- | |||
- | ===== Töötakt ===== | ||
- | |||
- | |||
- | |||
- | Nii nagu enamik digitaalelektroonikat, | ||
- | |||
- | **Sisemine RC ostsillaator** | ||
- | |||
- | [{{ : | ||
- | |||
- | See on kiibisisene taktigeneraator, | ||
- | |||
- | **Väline RC ostsillaator** | ||
- | |||
- | Sama põhimõttega, | ||
- | |||
- | **Kvartsostsillaator** | ||
- | |||
- | [{{ : | ||
- | |||
- | Kvartsostsillaatoris kasutatakse elektriväljas oma resonantssagedusel võnkuvat kristalli ja selle piesoelektrilist omadust mehhaanilisel deformatsioonil (võnkumisel) elektriväli tekitada. Kvartsostsillaatorit võimaldavad ligi 0,001% täpsust taktsagedust ja seda olenemata temperatuurist. | ||
- | |||
- | **Keraamiline resonaator** | ||
- | |||
- | Tegu on kvartsostsillaatorile sarnaneva lahendusega, | ||
- | |||
- | **Väline taktsignaal** | ||
- | |||
- | [{{ : | ||
- | |||
- | Välist taktsignaali võib tekitada ükskõik mis seade, peaasi et taktsagedus ja amplituut (pinge) oleks lubatud piirides. Näiteks võib skeemis kasutada eraldi taktigeneraatorit, | ||
- | |||
- | ===== Katkestused ===== | ||
- | |||
- | Katkestuse (inglise keeles // | ||
- | |||
- | AVR mikrokontrolleris on iga katkestus seotud kindla sündmusega. Igal sündmusel on olekuregistris lipubitt, mis tähistab sündmuse juhtumist. Lisaks on sündmustega seotud katkestuste maskeerimise registrid ja vastavad bitid. Kui sündmuse katkestuse bitt on maskeerimata ja tekib sündmus, jätab protsessor mõne(kümne) töötakti jooksul käimasoleva programmi täitmise pooleli ning alustab katkestuse programmi täitmist. Pärast katkestuse programmi täitmist jätkab protsessor poolelijäänud programmi täitmist. | ||
- | |||
- | <box 100% round # | ||
- | |||
- | Katkestuste kasutamiseks AVR LibC teegiga tuleb kasutusele võtta // | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | |||
- | ISR(XXX_vect) | ||
- | { | ||
- | // Tee midagi | ||
- | } | ||
- | </ | ||
- | |||
- | </ | ||
- | |||
- | Globaalne, kõigi katkestuste toimumise lubamine, määratakse ära juht- ja olekuregistris SREG. Võimaluse kõiki katkestusi keelata või lubada tingib andmete kaitse vajadus. Kuna katkestused katkestavad käimasoleva programmi täitmise, võivad nad segada või rikkuda andmeid, mida põhiprogramm katkestamise hetkel kasutas. Sellist olukorda saab vältida kõikide katkestuste keelamisega enne tundlike andmetega tegelemist. Globaalne katkestuste keelamine on lihtne, kui seda saab teha ühe registri (SREG) muutmisega. Pärast kriitilise programmiosa lõppu saab katkestused uuesti lubada ja kõik katkestused, | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | <box 100% round # | ||
- | |||
- | Oletame, et programmis on kasutusel 16-bitine muutuja, mille väärtust muudab nii põhiprogramm kui ka katkestuse programmilõik, | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | |||
- | // Globaalsed 16-bitised muutujad x ja y | ||
- | unsigned short x, y; | ||
- | |||
- | // Suvaline katkestus, mis muudab x väärtuse | ||
- | ISR(XXX_vect) | ||
- | { | ||
- | x = 0x3333; | ||
- | } | ||
- | |||
- | int main() | ||
- | { | ||
- | // Muutujale x väärtuse omistamine | ||
- | x = 0x1111; | ||
- | |||
- | // Globaalne katkestuste lubamine | ||
- | sei(); | ||
- | |||
- | // x väärtuse muutujasse y laadimine | ||
- | y = x; | ||
- | } | ||
- | </ | ||
- | |||
- | Programm on väga lihtne - algul omistatakse muutujale x väärtus 0x1111 ja hiljem selle väärtus omakorda muutujale y. Kui vahepeal tekib katkestus, saab x-i väärtuseks 0x3333. Loogikareeglite järgi saab muutujal y programmi lõpus olla kaks võimalikku väärtust, kuid 8-bitise AVR peal on ka kolmas võimalus. Nimelt, 8-bitise arhitektuuriga toimub 16-bitiste andmete liigutamine 2 takti jooksul ja vahepeal tekkiv katkestus võib andmete ühtsust rikkuda. Niisiis võib peale 0x1111 ja 0x3333 | ||
- | |||
- | Toodud näites muutujale y muutuja x väärtuse omistamine ohutul meetodil: | ||
- | |||
- | <code c> | ||
- | // Globaalne katkestuste keelamine | ||
- | cli(); | ||
- | |||
- | // Laadimine | ||
- | y = x; | ||
- | |||
- | // Globaalne katkestuste uuesti lubamine | ||
- | sei(); | ||
- | </ | ||
- | |||
- | </ | ||
- | ===== Digitaalsed sisendid-väljundid ===== | ||
- | |||
- | Kõik AVR siinid on loetavad ja kirjutatavad, | ||
- | |||
- | * PORT - siini füüsilise väljundoleku määramiseks. | ||
- | * PIN - siini füüsilise sisendoleku lugemiseks. | ||
- | * DDR - siini füüsilise suuna määramiseks. | ||
- | |||
- | <box 100% round # | ||
- | |||
- | Vaja on siini B viigud 0-3 teha sisenditeks, | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | |||
- | int main() | ||
- | { | ||
- | unsigned char x; | ||
- | |||
- | // Viigud 0-3 sisendiks, 4-7 väljundiks | ||
- | DDRB = 0xF0; | ||
- | |||
- | // Viienda viigu kõrgeks seadmine | ||
- | PORTB |= (1 << PIN5); | ||
- | |||
- | // 0-3 sisendviigu väärtuse lugemine | ||
- | x = PINB & 0x0F; | ||
- | } | ||
- | </ | ||
- | |||
- | </ | ||
- | |||
- | Toodud näites on sisendeid kasutatud Hi-Z ehk kõrge impendatsiga (inglise keeles //high impedance// | ||
- | |||
- | Enamasti on IO siinil olevaid viike peale loogiliste ühenduste kasutatud ka muu perifeeria tarbeks. Kui on soov kasutada viigu alternatiivfunktsiooni, | ||
- | ===== Välised katkestused ===== | ||
- | |||
- | Välised katkestused (inglise keeles //external interrupt// | ||
- | |||
- | Välise katkestuse kasutamiseks tuleks viik seadistada tavalise IO sisendrežiimi (võib ka väljundrežiimis kasutada, aga siis saab katkestust tekitada vaid kontroller ise). Välise katkestuse seadistusregistrites tuleb ära märkida katkestuste tekitamise lubamine ja tingimus, mille peale seda teha. Võimalikke tekitajaid on neli: | ||
- | |||
- | * Loogiline null (pinge on 0V) | ||
- | * Loogilise väärtuse muutus | ||
- | * Langev front - loogiline muutus ühest nulli. | ||
- | * Tõusev front - loogiline muutus nullist ühte. | ||
- | |||
- | Katkestuse tekitamiseks loogilise nulli valimisel tekitatakse katkestust järjest senikaua, kuni viigu väärtus on null. Põhiprogrammi töö on samal ajal peatatud. | ||
- | |||
- | Lähtudes tööpõhimõttelt, | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | <box 100% round # | ||
- | |||
- | Vaja on panna ATmega128 viik number 9 ehk siini E viik 7 tekitama katkestust, kui selle väärtus muutub. Sellele viigule vastab väline katkestus INT7, mis on sünkroonne. | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | |||
- | // Välise katkestuse programm | ||
- | ISR(INT7_vect) | ||
- | { | ||
- | // Tee midagi | ||
- | } | ||
- | |||
- | int main() | ||
- | { | ||
- | // Siini E viigu 7 muutmine sisendiks biti 7 nullimise teel | ||
- | DDRE &= ~(1 << PIN7); | ||
- | |||
- | // Siini E viigule 7 pull-up takisti määramine sisendi ujumise vastu | ||
- | PORTE |= (1 << PIN7); | ||
- | |||
- | // Väliste katkestuste seaderegistris katkestuse 7 | ||
- | // tekitajaks loogilise muutuse määramine | ||
- | EICRB = (1 << ISC70); | ||
- | |||
- | // Välise katkestuse 7 lubamine | ||
- | EIMSK |= (1 << INT7); | ||
- | |||
- | // Globaalne katkestuste lubamine | ||
- | sei(); | ||
- | |||
- | // Lõputu programmitsükkel | ||
- | while (1) continue; | ||
- | } | ||
- | </ | ||
- | |||
- | </ | ||
- | |||
- | Lisaks üksikute viikude tekitatavatele katkestustele on suurematel AVR-idel võimalik kasutada ka tervete gruppide viikude loogiliste väärtuste muutuste katkestusi. Neid katkestusi nimetatakse lihtsalt viigu muutuse katkestusteks (inglise keeles //pin change interrupt// | ||
- | ===== Analoog-digitaalmuundur ===== | ||
- | |||
- | Analoog-digitaalmuundur (inglise keeles //analog to digital converter//, | ||
- | |||
- | AVR ADC töötab võrdlusmeetodil (inglise keeles // | ||
- | |||
- | Mõõtetulemust saab kasutaja lugeda 8- ja 10-bitisena. Kuna AVR on 8-bitine, siis ADC mõõteväärtuste jaoks on sel kaks 8-bitist registrit. Seadistustes saab määrata, kas 10-bitisest väärtusest 2 esimest või 2 viimast bitti lähevad eraldi registrisse. Kui eraldatakse 2 noorimat ehk tulemust vähem iseloomustavat bitti, saab mõõtetulemuse 8-bitisena lugeda - sellist kombinatsiooni nimetatakse vasak-asetusega mõõtetulemuseks (//left align//). Teistpidist kombinatsiooni, | ||
- | |||
- | Mõõdetavaid analoogpinge sisendkanaleid on AVR-idel tavaliselt 8, ATtiny seerial üksikud, mõnel ATmega seeria kiibil 16, kuid muundureid on siiski üks. Erinevate sisendite kasutamiseks on kiibis multiplekser. Multiplekseri sisend on spetsiaalse registriga määratav. ADC üksusel on veel mõned omadused: muundamine protsessori magamisrežiimis müra vähendamiseks ja sisemise fikseeritud võrdluspinge (2,56 V, mõnel ka 1 V) kasutamise võimalus. | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | <box 100% round # | ||
- | |||
- | Vaja on mõõta ATmega128 ADC kanali 3 pinget vahemikus 0-5 V 8-bitise täpsusega. | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | |||
- | int main() | ||
- | { | ||
- | unsigned char result; | ||
- | |||
- | // Võrdluspingeks AREF viigu valimine | ||
- | // | ||
- | // Multiplekseriga kanali 3 valimine | ||
- | // Tulemus on vasak-asetusega | ||
- | ADMUX = (1 << REFS0) | (1 << ADLAR) | (3); | ||
- | |||
- | // ADC üksuse käivitamine, | ||
- | // teisendustakti seadmine 16 korda aeglasemaks töötaktist | ||
- | ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADSC); | ||
- | |||
- | // Mõõtmise lõpetamise ootamine | ||
- | while (ADCSRA & (1 << ADSC)) continue; | ||
- | |||
- | // 8-bitise tulemuse lugemine | ||
- | result = ADCH; | ||
- | } | ||
- | </ | ||
- | |||
- | </ | ||
- | ===== Loendurid/ | ||
- | |||
- | Loendurid (inglise keeles // | ||
- | |||
- | === Loenduri normaalrežiim === | ||
- | |||
- | Normaalrežiimis ei täida loendur muud funktsiooni kui pidevat järestikulist arvude loendamist. Loenduri väärtust saab igal hetkel programmis muidugi ka lugeda ja muuta. Ainuke lisavõimalus normaalrežiimis on katkestuse tekitamine loenduri ületäitumisel. Normaalrežiimi kasutatakse tavaliselt mingi programmilõigu täitmiseks kindlate ajaintervallide järel. | ||
- | |||
- | <box 100% round # | ||
- | |||
- | Vaja on 8 MHz taktsagedusel töötav ATmega128 10 ms (sagedus 100 Hz) ajavahemiku järel katkestust tekitama panna. Ülesandeks sobib 8-bitine loendur 0. | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | |||
- | ISR(TIMER0_OVF_vect) | ||
- | { | ||
- | // Loendurile sellise väärtuse omistamine, | ||
- | // et järgmine ületäitumine tekiks 10 ms pärast. | ||
- | // Valem: 256 - 8 MHz / 1024 / 100 Hz = 177,785 = ~178 | ||
- | TCNT0 = 178; | ||
- | } | ||
- | |||
- | int main() | ||
- | { | ||
- | // Et esimene ületäitumise katkestus tekiks 10 ms pärast, | ||
- | // tuleb ka siinkohal loendur algväärtustada. | ||
- | TCNT0 = 178; | ||
- | |||
- | // Sagedusjaguri teguriks 1024 | ||
- | TCCR0 = 0x07; | ||
- | |||
- | // Loenduri täitumise katkestuse lubamine | ||
- | TIMSK |= (1 << TOIE0); | ||
- | |||
- | // Globaalne katkestuste lubamine | ||
- | sei(); | ||
- | |||
- | // Lõputu programmitsükkel | ||
- | while (1) continue; | ||
- | } | ||
- | </ | ||
- | |||
- | Näites toodud loendurile omistatava väärtusega siiski täpselt 10 ms järel katkestust ei tekitata, sest vaja oleks loendurile omistada komakohaga väärtus, kuid see pole võimalik. Et täpset katkestuse intervalli saada, tuleb nii sagedusjaguri tegur kui ka loendurile täitumisel omistatav väärtus valida nii, et taktsagedus jaguks täpselt. Paraku pole see alati võimalik, ja eriti just 8-bitise loenduri puhul, sest selle väärtuste skaala on üsna väike. Täpsema ja suurema intervalli tekitamiseks saab kasutada 16-bitist loendurit. | ||
- | |||
- | </ | ||
- | |||
- | == Välise taktiga loendur == | ||
- | |||
- | Loenduri taktsignaalina saab kasutada ka mikrokontrollerivälist signaali (inglise keeles //external clock source//). Selleks on AVR mikrokontrolleril Tn viik, kus n tähistab loenduri numbrit. Välist taktsignaali ja polaarsust saab valida sagedusjaguri registriga. | ||
- | |||
- | == Sündmuste mõõtmine == | ||
- | |||
- | Kuna loendurid võimaldavad mõõta aega, on keerukamatel AVR mikrokontrolleritel võimalus riistvaraliselt mõõta ka aega, mil toimus mingi sündmus. Seda loenduri osa nimetatakse sündmuse püüdjaks (inglise keeles //input capture unit//). AVR-is on valida kahe sündmuse vahel: spetsiaalse sisendviigu või analoogkomparaatori võrdlustulemuse loogilise väärtuse muutus. Kui toimub valitud sündmus, kirjutatakse loenduri väärtus spetsiaalsesse registrisse, | ||
- | |||
- | <box 100% round # | ||
- | |||
- | Vaja on 8 MHz taktsagedusel töötava ATmega128-ga mõõta välise 122 Hz - 100 kHz loogilise nelinurksignaali sagedust 1 Hz täpsusega. Programm on tehtud 16-bitise loendur 1 sündmuste püüdjaga. | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | |||
- | unsigned long frequency; | ||
- | |||
- | // Sündmuse toimumise katkestus | ||
- | ISR(TIMER1_CAPT_vect) | ||
- | { | ||
- | // Loenduri nullimine | ||
- | TCNT1 = 0; | ||
- | |||
- | // Tulemus on ainult siis arvestatav, kui | ||
- | // loendur pole vahepeal üle täitunud | ||
- | if (!(TIFR & (1 << TOV1))) | ||
- | { | ||
- | // Sageduse arvutamine perioodi pöördväärtusest. | ||
- | frequency = (unsigned long)8000000 / | ||
- | (unsigned long)ICR1; | ||
- | } | ||
- | else | ||
- | { | ||
- | // Sagedus on vähem kui 122 Hz | ||
- | frequency = 0; | ||
- | |||
- | // Loenduri ületäitumise lipukese nullimine | ||
- | TIFR &= ~(1 << TOV1); | ||
- | } | ||
- | } | ||
- | |||
- | int main() | ||
- | { | ||
- | // Tõusva frondi registreerimine, | ||
- | TCCR1B = (1 << ICES1) | (1 << CS10); | ||
- | |||
- | // Sündmuse toimumise katkestuse lubamine | ||
- | TIMSK = (1 << TICIE1); | ||
- | |||
- | // Globaalne katkestuste lubamine | ||
- | sei(); | ||
- | |||
- | // Lõputu programmitsükkel | ||
- | while (1) continue; | ||
- | } | ||
- | </ | ||
- | |||
- | Programmis tekib välise signaali tõusva frondi ajal sündmuse katkestus. Katkestuse jooksul kontrollitakse, | ||
- | |||
- | </ | ||
- | |||
- | Sündmuste püüdmist ning nende aja registreerimist saab teha ka tarkvaraliselt. Saab kasutada väliseid või muid katkestusi ja nende tekkimise ajal lugeda loenduri väärtus. Riistvaraline sündmuste püüdmine on siiski mõeldud eeskätt programmist sõltumatuks töötamiseks ja suhteliselt lühiajaliste (või tihedate) sündmuste mõõtmiseks. | ||
- | |||
- | === Signaali genereerimine === | ||
- | |||
- | Keerukamate loenduritega saab peale signaali pikkuse mõõtmise ka signaali tekitada. Selleks on loenduril väärtuse võrdlemise üksus (inglise keeles //output compare unit//) ja võrdlustulemuse väljastusüksus (inglise keeles //compare match output unit//). Võrdlusüksusesse kuuluvad registrid sama bitilaiusega kui loendur ise ja nende registrite väärtusi võrreldakse loenduri väärtusega selle töö ajal. Hetkel, mil loenduri väärtus saab võrdseks võrdlusüksuse registri väärtusega, | ||
- | |||
- | Mõnedel signaali genereerimise režiimidel on määratav ka loenduri suurim väärtus - loenduri füüsiline suurus jääb küll samaks, kuid mängus on võrdlusregister, | ||
- | |||
- | Loendurid ja nende abil genereeritavate signaalide režiimid on ühed keerulisemad perifeeriamoodulid AVR-il. Kõigist neist kirjutamine läheks pikaks ja enamasti pole nende kasutamisel kõike detailselt teada. Seetõttu on järgnevalt kirjeldatud vaid üht levinuimat PWM signaali robootikas. Ülejäänut saab juba AVR dokumentatsioonist järgi uurida. | ||
- | |||
- | == Pulsilaius-modulatsioon == | ||
- | |||
- | Pulsilaius-modulatsioon (inglise keeles //pulse width modulation//, | ||
- | |||
- | <box 100% round # | ||
- | |||
- | Vaja on 8 MHz taktsagedusel töötava ATmega128-ga genereerida kaks kiirusreguleeritavat servomootori signaali. Viiguga PB5 (OC1A) tuleb genereerida pulsipikkus 1 ms ja viiguga PB6 (OC1B) pulsipikkus 2 ms. | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | |||
- | int main() | ||
- | { | ||
- | // Viigud väljundiks | ||
- | DDRB |= (1 << PIN5) | (1 << PIN6); | ||
- | |||
- | // Väljundid A ja B võrdusmomendil madalaks, | ||
- | // "Fast PWM" režiim, sagedusjagur 8 | ||
- | TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11); | ||
- | TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11); | ||
- | |||
- | // Suurim loenduri väärtus. Valem: | ||
- | // TOP = 8 MHz / 8 / 50 Hz | ||
- | ICR1 = 20000; | ||
- | |||
- | // Esimese mootori poolperiood 1 ms, teisel 2 ms | ||
- | OCR1A = 1000; | ||
- | OCR1B = 2000; | ||
- | |||
- | // Lõputu programmitsükkel | ||
- | while (1) continue; | ||
- | } | ||
- | </ | ||
- | |||
- | </ | ||
- | ===== USART ===== | ||
- | |||
- | USART on universaalne sünkroonne jadaliides, UART aga selle lihtsustatud variant - universaalne asünkroonne jadaliides. Vahe seisneb selles, et USART kasutab peale andmeliinide ka taktsignaali liini, millega andmeid sünkroniseeritakse, | ||
- | |||
- | Kõikide seadistuste jaoks on olemas vastavad registrid, mida on üsna lihtne andmelehe abil seadistada. Natuke keerulisem on boodikiiruse seadmine. Taktsignaal andmete edastamiseks genereeritakse töötaktist ja kasutaja saab valida teguri 1-st 4096-ni, millega töötakt läbi jagatakse. Täiendavalt jagatakse saadud taktisignaali olenevalt režiimist veel 2, 8 või 16-ga. Probleem on selles, et kõiki taktsagedusi ei saa jagada nii, et tekiks standardne boodikiirus. Mõnede mikrokontrolleri taktsageduste puhul on boodikiiruse erinevus soovitust ligikaudu 10%. AVR andmelehtedes on toodud tabelid tüüpilistest taktsagedustest, | ||
- | |||
- | Kuna andmete edastus toimub protsessorist sõltumata ja oluliselt aeglasemalt, | ||
- | |||
- | Sõna saabumist tähistab samuti spetsiaalne olekubitt. Lisaks on olekubitid vastuvõtmisel tekkiva kaadri vea, paarsuse vea ja vastuvõtja puhvri ületäitumise tähistamiseks. Puhvri ületäitumine tekib näiteks siis, kui eelmist saabunud sõna pole vastuvõtu puhvrist välja loetud - seepärast ongi oluline saabuvad sõnad kiiresti programmi lugeda, kasutades selleks näiteks katkestust. Kokku on kolm võimalikku katkestuse põhjust: saatepuhvri valmisolek, saatmise õnnestumine ja vastuvõtmise õnnestumine. | ||
- | |||
- | Muide, saatepuhver ja vastuvõtupuhver on füüsiliselt küll erinevad registrid, kuid jagavad sama mäluaadressi ja neil on ühine nimi. Ühine andmeregister toimib nii, et sellesse kirjutades jõuab sõna saatepuhvrisse ja sellest lugedes tuleb see vastuvõtupuhvrist. Veel ühe täpsustusena tuleks arvestada, et 9-bitiste andmesõnade puhul edastatakse ja loetakse üheksandat bitti hoopis ühe seaderegistri kaudu. | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | <box 100% round # | ||
- | |||
- | Seadistada 8 MHz taktsagedusel töötav ATmega128 USART0 liides boodikiirusel 9600 bps asünkroonselt edastama 8-bitiseid sõnu 1 stop-bitiga ja ilma paarsuse bitita. Saata märk " | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | |||
- | int main() | ||
- | { | ||
- | // Boodi kiiruseks 9600 bps seadmine. Valem: | ||
- | // | ||
- | // UBRR = 8000000 / 16 / 9600 - 1 = ~51 | ||
- | UBRR0H = 0; | ||
- | UBRR0L = 51; | ||
- | |||
- | // Saatja lubamine | ||
- | UCSR0B = (1 << TXEN0); | ||
- | |||
- | // Asünkroonse režiimi seadistamine, | ||
- | // 1 stop-bitt, keelatud paarsuse bitt. | ||
- | UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); | ||
- | |||
- | // Ootame, kuni andmepuhver on tühi ehk eelmine sõna on saadetud | ||
- | // Selles näites ei oma see küll mõtet, sest saadetakse alles | ||
- | // esimest märki, küll tasub seda teha rohkemate märkide korral. | ||
- | while (!(UCSR0A & (1 << UDRE))) continue; | ||
- | |||
- | // Märgi kirjutamine puhvrisse, kust see ka teele saadetakse | ||
- | UDR0 = ' | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (1) continue; | ||
- | } | ||
- | </ | ||
- | |||
- | </ | ||
- | ====== Robootika Kodulabor ====== | ||
- | |||
- | {{: | ||
- | |||
- | **Mehhatroonika ja Robootika Kodulabor** on ATmega128 mikrokontrolleril põhinev omavahel seotud moodulite komplekt, mis on komplekteeritud kaasaskantavasse kohvrisse. Kodulaboriga saab teha erinevaid mehhatroonika- ja robootikaalaseid eksperimente ning harjutusi alates lihtsast tule vilgutamisest kuni keeruka seadme ehitamiseni. Kodulabor on mõeldud eelkõige koolidele, sisaldades endas lisaks riistvarale ka metoodilist materjali ja harjutusülesandeid koos näidete ja lahendustega. Kodulabor on integreeritud oma veebikeskkonnaga, | ||
- | |||
- | Kodulabor on välja arendatud Tallinna Tehnikaülikooli ja Eesti ettevõtte poolt koostöös Euroopa partnerülikoolidega Leonardo da Vinci programmi toel. Kodulabori moodulid on komplekteeritud erinevatesse komplektidesse. Lihtsaim komplekt, millega saab teha esmaseid digitaalsete sisendite-väljundite eksperimente, | ||
- | ===== Integreeritud robootika õppe kontseptsioon ===== | ||
- | |||
- | Tänapäevane inseneriõpe ei saa enam põhineda ühel konkreetsel õppeviisil, | ||
- | |||
- | Mehhatroonika ja robootika integreeritud õppe kontseptsioon sisaldab endas nii standardseid õppeabimaterjale kui ka uudseid lähenemisi, | ||
- | |||
- | Alljärgnev näide võib olla abiks koolile robootika õppesüsteemi käivitamiseks kui ka ideedeks rakendada erinevaid õppevõimalusi tehnikavaldkonna praktilises õppes. | ||
- | |||
- | Õppe kontseptsioon sisaldab endas järgnevaid õppeabimaterjale: | ||
- | * Tavaline käsiraamat-õpik, | ||
- | * Praktiline harjutusülesannete kogu, näiteks käesolev raamat. | ||
- | * Robootika Kodulabor. | ||
- | * Mehhatroonika Kauglabor. | ||
- | * Robootika õpetajate ja õpilaste võrgustik http:// | ||
- | |||
- | Teoreetilised abimaterjalid koosnevad traditsioonilisest õpik-käsiraamatust ja harjutusülesannete kogust. | ||
- | |||
- | Praktiline osa koosneb Kodulaborist ja üle interneti robotite programmeerimise keskkonnast - Kauglaborist. Kodulaborid moodustavad Kauglaboriga ühtse terviku, mis tähendab, et õppija saab kodus harjutada üksikuid funktsioone, | ||
- | |||
- | Kodulabori veebikeskkond\\ | ||
- | http:// | ||
- | |||
- | Kauglabori veebikeskkond\\ | ||
- | http:// | ||
- | |||
- | |||
- | ~~PB~~ | ||
- | |||
- | Õppeprotsessi ühe teema/ | ||
- | |||
- | {{ : | ||
- | |||
- | Teema algab sissejuhatava loenguga, mis võib toimuda klassikalise kontakttunnina, | ||
- | Teoreetilist osa toetab õpik ja harjutuste kogu teoreetiline osa. | ||
- | |||
- | Teema tutvustusele järgneb iseseisev praktiline töö. Praktiline töö koosneb näitelahenduse katsetamisest, | ||
- | |||
- | Praktilise harjutuse tulemused vormistatakse aruandeks ja saadetakse õpetajale või, kui kasutusel on e-õppe süsteem, laetakse koos töötavate masinkoodis lahendustega vastavasse süsteemi. Aruanne sisaldab tüüpiliselt töö kirjeldust ja lahenduse lähtekoodi, | ||
- | |||
- | ===== Robootika õpetamisest ===== | ||
- | |||
- | Ei ole mingi uudis, et infotehnoloogia tungimine igapäevaellu on muutnud paljude, kui mitte enamuse noorte õppimise stiili ja kommunikatsioonikanaleid. Tõenäoliselt saab õppija juba praegu olulise osa õpitava aine informatsioonist erinevate infotehnoloogia kommunikatsioonikanalite kaudu. Enne mingi probleemi lahendamist tehakse tihti kiire otsing internetist, | ||
- | |||
- | Robootika ja mehhatroonika on tulevikku suunatud alad, mille õpetamisel tuleb samuti järgida tänapäeva trende ja uusi tehnoloogiaid. Samal ajal aga on see valdkond väga praktiline ja nõuab oskuste ning teadmiste omandamiseks praktilist katsetamist ja harjutamist. Kuigi on olemas ka virtuaalseid ülesandeid, | ||
- | Järgnevalt püüame pakkuda ühe võimaliku praktilise juhendi, kuidas viia läbi ühte robootika ainet, kus on kasutusel erinevaid õpetamise vorme integreeriv lähenemine. Metoodika eeldab, et õpetajal on võimalus kasutada modulaarset praktilist robootika õppekomplekti - antud juhul Kodulaborit. | ||
- | |||
- | Mida pidada silmas õppeaine alustamisel.... | ||
- | |||
- | - **Grupi suurus** \\ | ||
- | Optimaalse õpilaste arvu laborikomplektiga tegutsemiseks määrab suuresti ära juba arvutikasutamise võimalus. See tähendab, et ühe arvuti taha mahub enamasti kuni 3 inimest nii, et veel kõik saavad toimuvast aktiivselt osa võtta. Suurema arvu juures ei näe osa õpilasi enam kirjutatavat koodi ja neil hakkab igav ning tunnitööga enam ei tegeleta. | ||
- | - **Praktiline töö ja aruandlus** \\ | ||
- | Praktiline töö on jagatud laboritöödeks, | ||
- | * Laboritöö tutvustus | ||
- | * Õpetaja selgitab kõigepealt uut laboritööd, | ||
- | * Õpetaja jaotab labori materjali etappideks, nii et iga etapp koosneb teooriast ja koodi kirjutamisest. Seega kirjutatav programmikoodi näide valmib koos teooria selgitamisega. | ||
- | * Iseseisev ülesannete lahendamine. See toimub laboritöö juhendi järgi, kus on kirjas ülesanne, nõuded ja aruandluse vorm. Õpilased teevad tööd iseseisvalt, | ||
- | * Tööde esitamine. Õpilased koostavad tehtud tööst aruande, kus nad vastavad lisaks õpetaja poolt määratud kordamisküsimustele. Aruandlus koos kompileeritud lahendusega (hex failina) saadetakse õpetajale kindlaks ajaks elektrooniliselt. | ||
- | * Kontroll | ||
- | * Õpetaja kontrollib, kas lahendus töötab ning paneb hinde saadetud töö ja aruandluse alusel. | ||
- | * Õpetaja kontrollib, kas lahendus töötab ning palub grupil tööd kaitsta suuliselt nii, et üks õpilane peab selgitama teatud osas aruandest, teine õpilane teist osa, jne. | ||
- | - ** Gruppide haldamine ** \\ | ||
- | Ülesannete lahendamisel võib alati tekkida grupp (grupid), kes on teistest aeglasem või alustasid hiljem. Sellisel juhul on tavaliselt probleemiks õpetaja tähelepanu koondumine mahajäänud grupi abistamisele ning teised peavad ootama ja igavlema, kuni mahajääja grupp on järele jõudnud. Analoogselt tekib probleem, kui klassis on üks grupp, kes jõuab töödega valmis teistest kiiremini. Mõlema probleemi lahendamiseks on võimalus kasutada kirjapandud ülesandeid või laborijuhendeid. Kuna kogu töö protsess ja nõutud osad on kirja pandud, siis saavad grupid | ||
- | - **Hindamine** \\ | ||
- | Kui õpetaja peab oluliseks, et kõik oskaksid programmeerida ning saaksid programmikoodist aru, siis võib õpetaja nõuda, et õpilased vahetaksid teatud osaülesande järel kohad, nii et igaüks saaks proovida programmeerimist. Teine võimalus on ülesande hindamisel küsida programmikoodi lahenduse kohta selgitust ükskõik milliselt grupi liikmelt ning viimase vastus määrab kogu grupiliikmete hinde. See sunnib gruppi töötama ühtsena ning hoolitsema, et kõik grupi liikmed saaksid aru, kuidas lahenduse üksikasjad töötavad. Kui selline lähenemine tundub ebaõiglasena, | ||
- | - **Veaotsing** \\ | ||
- | Tihtipeale võivad programmi koodi kompileerimisel või riistvara valesti käsitlemisel tekkida mingid tüüpvead. Nende sümptomid tasub kindlasti kirja panna koos lahendusega, | ||
- | - **Võistlus** \\ | ||
- | Üks võimalus motivatsiooni tõstmiseks ja kogu õppeprotsessi huvitavamaks muutmiseks on tekitada võistlusmoment, | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | Järgnevalt on toodud näiteks tüüpiline laboritöö kirjeldus, mida võib kasutada praktilise töö lähteülesandena. | ||
- | |||
- | <box 100% round # | ||
- | |||
- | **Juhendaja**: | ||
- | |||
- | **Töö eesmärk** | ||
- | |||
- | Tutvuda analoog-digitaalmuunduri tööpõhimõtte ja analoogsignaalide muundamisega, | ||
- | |||
- | **Tööks vajalikud vahendid** | ||
- | |||
- | Kodulabori baasversioon, | ||
- | |||
- | **Töö käik** | ||
- | |||
- | - Teha läbi näiteülesanne potentsiomeetriga. \\ http:// | ||
- | - Teha ühine harjutus " | ||
- | - Teha grupi personaalne harjutusülesanne (mille määrab õppejõud vahetult enne töö alustamist) | ||
- | - Vastata kordamisküsimuste ühele küsimusele (küsimuse määrab õppejõud vahetult enne töö alustamist) | ||
- | |||
- | **Aruanne** | ||
- | |||
- | Tehtud töö kohta tuleb esitada elektrooniline aruanne, mis sisaldab: | ||
- | * Seletuskirja töö käigu kohta | ||
- | * Töö eesmärk | ||
- | * Lühikirjeldus tehtud töödest | ||
- | * Algoritm ja väljatrükk programmi algkoodist sammude 2 ja 3 kohta \\ NB! Lähtekood peab olema kommenteeritud ja värvitud (võib kasutada " | ||
- | * Küsimuse vastus (samm 4) | ||
- | * Järeldused ja kommentaarid | ||
- | * Ülesannete 2 ja 3 töötav lahendus HEX failina. | ||
- | |||
- | Aruanne peab sisaldama nime, labori numbrit, teostamise kuupäeva, kaasosaliste nimesid (kui olid). Aruanne peab olema lühike, kuid sisutihe. Hinnatakse kvaliteeti, mitte kvantiteeti! Olge valmis lahenduse demonstreerimiseks juhendajale ja Teie poolt loodud programmikoodi kommenteerimiseks. Aruanded laadida üles e-õppe keskkonda vastava ülesande juurde. | ||
- | Labori aruande esitamise tähtaeg on 1 nädal pärast töö tegemist. | ||
- | |||
- | **Kirjandus** | ||
- | - Kodulabori tugikeskkond: | ||
- | - ATmega128 andmeleht | ||
- | - Sharp infrapunaanduri andmeleht | ||
- | - http:// | ||
- | </ | ||
- | ===== Kodulabori riistvara ===== | ||
- | |||
- | Robootika Kodulabori moodulid on jagatud erinevatesse komplektidesse, | ||
- | |||
- | === Kodulabori baaskomplekt === | ||
- | |||
- | [{{ : | ||
- | |||
- | * AVR ATmega128 arendusplaat | ||
- | * Digitaal sisend-väljundplaat (nupud, LED-id, 2 x LCD väljund, 7-segment-indikaator) | ||
- | * 2 x 16 tähemärgiga taustavalgustusega LCD ekraan | ||
- | * JTAG programmaator ja silur (USB) + kaabel | ||
- | * Näiteülesanded koos C-lähtekoodiga (näidisharjutus) | ||
- | * Toiteplokk | ||
- | * Multimeeter | ||
- | * Tarkvara assembler- ja C-keeles programmeerimiseks | ||
- | * Kaasaskantav kohver | ||
- | |||
- | === Andurite ja Mootorite lisakomplekt === | ||
- | [{{ : | ||
- | **Mootorite moodul** | ||
- | * Alalisvoolumootor (reduktoriga) | ||
- | * RC servomootor | ||
- | * Samm-mootor (bipolaarne või unipolaarne samm-mootor) | ||
- | * Mootorite ajuriplaat | ||
- | * Toitejagur | ||
- | * Ribakaabel | ||
- | |||
- | **Andurite moodul** | ||
- | * Analooganduri ja madalpääsu filtri kombineeritud plaat koos anduritega (temperatuuri andur, valgustugevuse andur, potentsiomeeter) | ||
- | * Ultraheli kaugusandur SRF05 koos kaabliga | ||
- | * Infrapuna kaugusandur SHARP koos kaabliga | ||
- | * Ribakaabel | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === Kodulabori täiskomplekt === | ||
- | |||
- | Kodulabori täiskomplekt sisaldab kõiki komponente Kodulabori baaskomplektist ja Andurite ja Mootorite lisakomplektist ning lisaks järgmisi mooduleid: | ||
- | |||
- | **RFID moodul** | ||
- | |||
- | * Lugeja | ||
- | * Märk (2 tk) | ||
- | * Kaabel | ||
- | |||
- | **Kommunikatsiooni moodul** | ||
- | |||
- | * Bluetooth | ||
- | * Ethernet | ||
- | * SPI | ||
- | |||
- | **Masinnägemise moodul** | ||
- | |||
- | * Intelligentne kaameramoodul (CMUcam3) | ||
- | |||
- | [{{ : | ||
- | |||
- | Kodulabori baaskomplekti ja täiskomplekti saab edukalt kasutada lisaks eksperimentidele ka robotiehitamise baasplatvormina või muu mehhatroonikasüsteemi keskse juhtsüsteemina. Kodulabori versioonid on pidevas arengus ja aeg-ajalt tasub kontrollida, | ||
- | ==== Kontrollermoodul ==== | ||
- | |||
- | Kodulabori keskseks mooduliks (kontrollermooduliks) on arendusplaadile paigaldatud mikrokontroller ATmega128. Lisaks mikrokontrollerile on plaadil veel mitmesuguseid perifeeriaseadmeid, | ||
- | |||
- | * ATmega128-16AU mikrokontroller | ||
- | * 8-kanaliga analoog-digitaalmuunudr (ADC) | ||
- | * 128 kB // | ||
- | * 6 kanaliga programmeeritav PWM generaator | ||
- | * 4 kB EEPROM mälu (andmemälu) | ||
- | * Standardne 6-viiguga ISP (inglise keeles //in-system programming interface// | ||
- | * 14,7456 MHz taktigeneraator | ||
- | * Reaalaja kell RTC (inglise keeles //real time clock// | ||
- | * Programmeeritav oleku LED (PB7) ja toite indikaator-LED | ||
- | * Standardne RS-232 jadaliidese pistikupesa | ||
- | * Grupeeritud AVR viigud (1: pordid D, B, E; 2: pordid G, C, A; 3: port F) | ||
- | * Taaskäivitamise (inglise keeles //reset//) nupp | ||
- | * JTAG 10-viiguga programmeerimise liides | ||
- | * 2,1 mm toitepistiku pesa | ||
- | * Pingestabilisaator ja valepolaarsuse kaitse | ||
- | |||
- | [{{ : | ||
- | |||
- | Kontrollermooduli plaat on varustatud alaldiga ja pingestabilisaatoriga. Sisendpingeks sobib plaadile 6-15 V. Voolukadude minimeerimiseks on soovitatav kasutada 6-9 V pingeallikat. Toite ühendamisel peab plaadil toite LED põlema hakkama. Kui see ei sütti, võib põhjus olla puudulikus toites, ühendamata jäänud toitesillas (toitepesa kõrval) või hoopis lühises Kontrollermooduli plaadil või temaga ühendatud seadmes. Mikrokontrollerit saab programmeerida nii ISP kui JTAG liidese kaudu. Kodulabori komplektiga kaasasolev JTAG-ICE programmaator toetab lisaks lihtsale programmi pealelaadimisele ka programmikoodi silumist. JTAG-ICE programmaatorit võib kasutada ka ISP režiimis. Programmeerimise viigud on ühendatud läbi multiplekseri, | ||
- | |||
- | Kontrollermooduli plaat on varustatud oleku-LED-iga, | ||
- | |||
- | Plaadile on paigaldatud lisamälu - 4 Mb Atmel AT45DB041B välkmälu. Mälu on ühendatud SPI liidese kaudu mikrokontrolleriga ja seda võib kasutada andmete salvestamiseks, | ||
- | |||
- | [{{: | ||
- | |||
- | === Ühenduspesade viigud ja nende funktsioonid === | ||
- | |||
- | {{: | ||
- | ~~CL~~ | ||
- | ^Nr^Viik^Alternatiivfunktsioon / kirjeldus^^ | ||
- | |1|VCC|- | ||
- | |2|GND|- | ||
- | |3|REF|AREF|ADC võrdluspinge sisend| | ||
- | |4|GND|- | ||
- | |5|PF0|ADC0|ADC sisendkanal 0 | | ||
- | |6|GND|-|Maa | | ||
- | |7|PF1|ADC1|ADC sisendkanal 1 | | ||
- | |8|GND|-|Maa | | ||
- | |9|PF2|ADC2|ADC sisendkanal 2 | | ||
- | |10|GND|-|Maa | | ||
- | |11|PF3|ADC3|ADC sisendkanal 3| | ||
- | |12|GND|-|Maa | | ||
- | |13|PF4|ADC4/ | ||
- | |14|GND|-|Maa | | ||
- | |15|PF5|ADC5/ | ||
- | |16|GND|-|Maa | | ||
- | |17|PF6|ADC6/ | ||
- | |18|GND|-|Maa | | ||
- | |19|PF7|ADC7/ | ||
- | |20|GND|-|Maa | | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | {{: | ||
- | ~~CL~~ | ||
- | ^Nr^Viik^Alternatiivfunktsioon / kirjeldus^^ | ||
- | |1 |PD7|T2 | ||
- | |2 |PD6|T1 | ||
- | |3 |PD5|XCK1 | ||
- | |4 |PD4|IC1 | ||
- | |5 |PD3|INT3/ | ||
- | |6 |PD2|INT2/ | ||
- | |7 |PD1|INT1/ | ||
- | |8 |PD0|INT0/ | ||
- | |9 |VCC|- | ||
- | |10|GND|- | ||
- | |11|PB7|OC2/ | ||
- | |12|PB6|OC1B | ||
- | |13|PB5|OC1A | ||
- | |14|PB4|OC0 | ||
- | |15|PB3|MISO | ||
- | |16|PB2|MOSI | ||
- | |17|PB1|SCK | ||
- | |18|PB0|SS | ||
- | |19|PE7|INT7/ | ||
- | |20|PE6|INT6/ | ||
- | |21|PE5|INT5/ | ||
- | |22|PE4|INT4/ | ||
- | |23|PE3|AIN1/ | ||
- | |24|PE2|AIN0/ | ||
- | |25|PE1|PDO/ | ||
- | |26|PE0|PDI/ | ||
- | |||
- | {{: | ||
- | ~~CL~~ | ||
- | ^Nr^Viik^Alternatiivfunktsioon / kirjeldus^^ | ||
- | |1 |GND|- | ||
- | |2 |VCC|- | ||
- | |3 |PA0|AD0|Välismälu-liidese aadressi- ja andmebitt 0 | | ||
- | |4 |PA1|AD1|Välismälu-liidese aadressi- ja andmebitt 1 | | ||
- | |5 |PA2|AD2|Välismälu-liidese aadressi- ja andmebitt 2 | | ||
- | |6 |PA3|AD3|Välismälu-liidese aadressi- ja andmebitt 3 | | ||
- | |7 |PA4|AD4|Välismälu-liidese aadressi- ja andmebitt 4 | | ||
- | |8 |PA5|AD5|Välismälu-liidese aadressi- ja andmebitt 5 | | ||
- | |9 |PA6|AD6|Välismälu-liidese aadressi- ja andmebitt 6 | | ||
- | |10|PA7|AD7|Välismälu-liidese aadressi- ja andmebitt 7 | | ||
- | |11|- |- |Pole ühendatud | ||
- | |12|- |- |Pole ühendatud | ||
- | |13|PG2|ALE|Välismälu-liidese aadressi lukustussignaal | | ||
- | |14|- |- |Pole ühendatud | ||
- | |15|PC6|A14|Välismälu-liidese aadressi- ja andmebitt 14| | ||
- | |16|PC7|A15|Välismälu-liidese aadressi- ja andmebitt 15| | ||
- | |17|PC4|A12|Välismälu-liidese aadressi- ja andmebitt 12| | ||
- | |18|PC5|A13|Välismälu-liidese aadressi- ja andmebitt 13| | ||
- | |19|PC2|A10|Välismälu-liidese aadressi- ja andmebitt 10| | ||
- | |20|PC3|A11|Välismälu-liidese aadressi- ja andmebitt 11| | ||
- | |21|PC0|A8 |Välismälu-liidese aadressi- ja andmebitt 8 | | ||
- | |22|PC1|A9 |Välismälu-liidese aadressi- ja andmebitt 9 | | ||
- | |23|PG0|WR |Välismälu kirjutussignaal | ||
- | |24|PG1|RD |Välismälu lugemissignaal | ||
- | |25|- |- |Pole ühendatud | ||
- | |26|- |- |Pole ühendatud | ||
- | |||
- | ~~PB~~ | ||
- | === Ühendamine === | ||
- | |||
- | Kontrollermooduli ühendamisel teiste moodulite ning seadmetega on esimeseks ja viimaseks tegevuseks toite eemaldamine ja ühendamine. Ajal kui plaat on pingestatud, | ||
- | |||
- | [{{: | ||
- | |||
- | ==== Digitaalne sisend-väljundmoodul ==== | ||
- | |||
- | Digitaalne sisend-väljundmoodul on mõeldud lihtsamateks harjutusteks ja elementaarseks protsessi juhtimiseks. Moodulil on kolm nupp-lülitit ja kolm valgusdioodi (LED), mida saab kasutada AVR sisend-väljundviikudega. Lisaks lihtsatele valgusdioodidele on moodul varustatud ka LED numberindikaatoriga ja LCD ekraanide väljunditega. Digitaalset moodulit on mugav kasutada koos teiste moodulitega, | ||
- | |||
- | * Rohelise, kollase ja punase valgusdioodiga (LED) | ||
- | * Kolme mikrolülitiga. | ||
- | * 7-segmendilise numberindikaatoriga. | ||
- | * Alfabeetilise LCD ühenduspistikuga. | ||
- | * Graafilise LCD ühenduspistikuga (alates versioonist 3.2). | ||
- | * Ultraheli kaugusanduri ühenduspistikuga (alates versioonist 3.3). | ||
- | |||
- | {{: | ||
- | |||
- | === Elektrilised ühendused === | ||
- | |||
- | [{{ : | ||
- | |||
- | Digitaalne sisend-väljundmoodul on Kontrollermooduli plaadiga ühendatud ühe ribakaabliga porti PA/PC/PG, mis koondab endas 8-viigulisi porte PA ja PC ning 3-viigulist porti PG. Lisaks saab moodul ribakaabli kaudu ka toite (+5 V). Kui moodul on õigesti ühendatud, peab moodulil olev väike roheline LED //+5V_OK// põlema minema. Kui LED ei sütti, võib põhjuseks olla ribakaabli vale ühendamine. | ||
- | |||
- | 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). | ||
- | |||
- | [{{ : | ||
- | |||
- | ~~CL~~ | ||
- | |||
- | Digitaalne sisend-väljundmoodul on varustatud ühe 7-segmendilise numberindikaatoriga, | ||
- | |||
- | [{{ : | ||
- | |||
- | ~~CL~~ | ||
- | |||
- | Digitaalmooduli plaadil on eraldi välja toodud port PA. See on ühendatud samaaegselt kahte erinevasse viikude gruppi, kus esimene grupp on ühendatud läbi nivoomuunduri, | ||
- | Eraldi on välja toodud port PG kaks kasutamata viiku - PG0 ja PG1, kuhu on võimalik ühendada lisaseadmeid, | ||
- | |||
- | [{{ : | ||
- | |||
- | === Mooduli ühendamine === | ||
- | |||
- | Mooduli ühendamine on soovitatav teostada alltoodud järjekorras. Enne ühendamist veenduda, et Kontrollermooduli toide oleks lahti ühendatud. | ||
- | |||
- | - Ühendada Digitaalne sisend-väljundmoodul Kontrollermooduliga, | ||
- | - Ühendada vajadusel JTAG programmaator Kontrollermooduliga. | ||
- | - Ühendada Kontrollermooduli toide. | ||
- | |||
- | [{{: | ||
- | ==== LCD moodul ==== | ||
- | |||
- | LCD moodul on moodul, mis hõlmab endas Digitaalse sisend-väljundmooduli ühendusi ja erinevat tüüpi LCD ekraane. Digitaalse mooduli külge on võimalik ühendada 5 V nivool töötavaid alfabeetilisi LCD ekraane ja 3,3 V nivool töötavaid graafilisi LCD ekraane (alates Digitaalmooduli versioonist 3.2). Alfabeetilise ekraani kontrastsuse reguleerimiseks on Digitaalmooduli plaadil väike potentsiomeeter (LCD_BG). Graafilise LCD ekraani kontrastsust reguleeritakse tarkvaraliselt. LCD ekraanid ühendatakse porti PA. Korraga saab kasutada ainult ühte LCD ekraani. | ||
- | |||
- | === LCD ekraani ühendamine === | ||
- | |||
- | Mooduli ühendamisel on soovitatav järgida allolevat järjekorda ja enne ühendamist veenduda, et Kontrollermooduli toide on lahti ühendatud. | ||
- | |||
- | - Ühendada Digitaalne sisend-väljundmoodul Kontrollermooduliga kasutades ribakaablit. | ||
- | - Ühendada alfabeetiline või graafiline LCD ekraan Digitaalmooduliga (korraga ainult üks). | ||
- | - Ühendada vajadusel JTAG programmaator Kontrollermooduliga. | ||
- | - Ühendada Kontrollermooduli toide. | ||
- | |||
- | [{{: | ||
- | ==== Andurite moodul ==== | ||
- | |||
- | Andurite moodul koosneb integreeritud andurite ja madalpääsu filtri plaadist ning kaugusanduritest. | ||
- | |||
- | Anduri moodul on varustatud: | ||
- | |||
- | * Ultraheli kaugusanduriga Devantech SRF05 koos kaabliga (mõõtepiirkond 1-400 cm) {{: | ||
- | * Infrapuna kaugusandur Sharp GP2Y0A21YK0F (mõõtepiirkond 10-80 cm) {{: | ||
- | * Valgustundlik andur (fototakisti) VT935G (takistus 18,5 kΩ 10 lux juures) {{: | ||
- | * Temperatuuriandur (NTC termistor) (takistus 10 kΩ 25 °C juures) {{: | ||
- | * Potentsiomeeter 5 kΩ | ||
- | |||
- | {{: | ||
- | |||
- | === Elektrilised ühendused === | ||
- | |||
- | [{{: | ||
- | |||
- | ~~CL~~ | ||
- | |||
- | == Andurid == | ||
- | |||
- | [{{ : | ||
- | |||
- | Andurid on ühendatud läbi silla (inglise keeles // | ||
- | |||
- | ~~CL~~ | ||
- | |||
- | == Madalpääsu filter == | ||
- | [{{ : | ||
- | |||
- | Madalpääsu RC filtri saab koostada analoogsisendite 0-3 vahele (viigud PF0-PF3). Madalpääsu filtri koostamiseks paigutatakse vastavatesse pesadesse takisti ja kondensaator. Vaikimisi on madalpääsu filter koostatud kanalile PF0. Takisti väärtuseks on 10 kΩ ja kondensaatori väärtuseks 100 nF. | ||
- | |||
- | ~~CL~~ | ||
- | ~~PB~~ | ||
- | |||
- | === Mooduli ühendamine === | ||
- | |||
- | Mooduli ühendamisel on soovitatav järgida allolevat järjekorda ja enne ühendamist veenduda, et Kontrollermooduli toide on lahti ühendatud. | ||
- | |||
- | - Ühendada moodul Kontrollermooduliga (20 soonega ribakaabel). NB! Kontrollermooduliga ühendatakse pistikupesa, | ||
- | - Ühendada vajadusel infrapuna kaugusandur (must juhe - GND). | ||
- | - Ühendada vajadusel Digitaalmoodul ja LCD ekraan. | ||
- | - Ühendada vajadusel ultraheli kaugusandur (must juhe - GND). | ||
- | - Ühendada Kontrollermooduli toide. | ||
- | |||
- | [{{: | ||
- | |||
- | ==== Mootorite moodul ==== | ||
- | |||
- | Mootorite moodul koosneb mootorite juhtplaadist ja erinevatest mootoritest. Mootoriplaat on projekteeritud AVR ATmega128 kontrolleriplaadiga ühendamiseks, | ||
- | |||
- | Mootoriplaat eraldab mootorite toited juhtsignaalidest ning võimaldab ühe ribakaabliga ühendada kõik juhtsignaalid kontrollerplaadiga. | ||
- | |||
- | {{: | ||
- | |||
- | Moodul võimaldab juhtida erinevaid mootoritüüpe ning kõigil tüüpidel võib olla erinev toitepinge. Mooduli (ühendus)võimalused: | ||
- | |||
- | * 4 x alalisvoolumootor või 3 x alalisvoolumootor ja 2 x kooder. | ||
- | * 2 x unipolaarne samm-mootor. | ||
- | * 1 x bipolaarne samm-mootor. | ||
- | * 2 x RC servomootor. | ||
- | * Eraldi UART pistik. | ||
- | * Juhtkiipide toite valiku sild JP1 (kontrollerplaadilt või väline). | ||
- | * Toite LED. | ||
- | |||
- | Mootorite mooduli toitepistik (PWR): | ||
- | |||
- | ^ Viik ^ Ühenduspunkt | ||
- | | 1 | DC mootorid | ||
- | | 2 | Bipolaarne samm-mootor | ||
- | | 3 | Servomootorid | ||
- | | 4 | Unipolaarsed samm-mootorid | ||
- | | 5 | Loogika toide (valitav JP1 abil) | 5 V | | ||
- | | 6 | Maa (GND) | | | ||
- | |||
- | NB! Pinge ja vool sõltuvad eelkõige kasutatavast mootorist ja ei tohi ületada mootori lubatavaid piirväärtusi. Kodulabori komplektis sisalduvate mootorite toide on üldjuhul 5 - 6 V ja vastavalt sellele on kaasasoleva harukaabli väljundpinged limiteeritud 5 või 6 V. | ||
- | |||
- | === Mootorid === | ||
- | |||
- | Mootori konkreetsed margid ja mudelid võivad Kodulabori komplektides varieeruda, kuid igas komplektis on alati 1 alalisvoolumootor, | ||
- | |||
- | Allpool on toodud võimalikud mootorid, mis esinevad Kodulaborite komplektides. | ||
- | |||
- | * **Alalisvoolumootor** | ||
- | * Micromotors L149.6.10 (reduktor) {{: | ||
- | * Micromotors L149.6.43 (reduktor) {{: | ||
- | * Micromotors LE149.6.10 (reduktor + kooder) {{: | ||
- | * **RC servomootor** | ||
- | * Robbe FS 100 {{: | ||
- | * E Sky EK2-0501 {{: | ||
- | * Futaba XT-S | ||
- | * Hitec HS422 {{: | ||
- | * **Unipolaarne samm-mootor** | ||
- | * Ming Jong ST35 {{: | ||
- | * **Bipolaarne samm-mootor** | ||
- | * Moons 42PM {{: | ||
- | * Ming Jong ST28 {{: | ||
- | * **Pieso heligeneraator** (valikuline) | ||
- | |||
- | [{{ : | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === Elektrilised ühendused === | ||
- | |||
- | Mootoriplaat tuleb Kontrollermooduli plaadiga ühendada ühe ribakaabliga Kontrollerimooduli porti PE-PB-PD. Mootorite toited ühendatakse eraldi PWR pistikuga, kus igale mootori tüübile on võimalik anda erinev toitepinge, sõltuvalt kasutatavast mootori tüübist. Plaadil olevaid kiipe on võimalik toita välise toiteallikaga või otse kontrollerplaadilt. Selle määrab plaadil olev sild JP1. Kui sild ühendab viigud 1 ja 2, siis kiipide toide võetakse otse Kontrollermoodulist. Kiipide korrektse toite olemasolu saab kontrollida plaadil oleva väikese rohelise LED +5V abil. Mootoriplaadil on eraldi välja toodud ka UART ühendus, mis võimaldab läbi mootoriplaadi ühendada UART protokolliga ühilduvaid seadmeid. | ||
- | |||
- | [{{ : | ||
- | |||
- | == Alalisvoolumootor == | ||
- | |||
- | Alalisvoolumootorid ühendatakse pistikute gruppi DC1. Iga paari külge on võimalik ühendada üks mootor - kokku 4 mootorit. Mootori pistikuga 3 on paralleelselt ühendatud koodrite ENC1 ja ENC2 pistikud. Kui soovitakse kasutada mootoreid koos koodritega, siis mootoripistikut 3 samaaegselt kasutada ei saa (tarkvaraliselt muudetakse see sisendiks). Mootoreid juhitakse üldlevinud kahe integreeritud H-silla kiipidega L293D, mis mõlemad on võimelised juhtima samaaegselt kahte mootorit. Mootorid võib asendada ka muude täituritega (näiteks pieso heligeneraator, | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | [{{ : | ||
- | |||
- | ^ AVR viik ^ Juhtsignaal ^ AVR viik ^ Juhtsignaal ^ | ||
- | | PB4 | Mootor 1 1A | PD6 | Mootor 3 1A | | ||
- | | PB7 | Mootor 1 2A | PD7 | Mootor 3 2A | | ||
- | | PD0 | Mootor 2 1A | PD4 | Mootor 4 1A | | ||
- | | PD1 | Mootor 2 2A | PD5 | Mootor 4 2A | | ||
- | |||
- | == Samm-mootorid == | ||
- | |||
- | Mootoriplaat toetab kahe erinevat tüüpi samm-mootori kasutamist. Plaadile on võimalik ühendada 2 unipolaarset samm-mootorit ja 1 bipolaarne samm-mootor. Bipolaarset samm-mootorit juhitakse H-sillaga L293D ja unipolaarset samm-mootorit transistorite jadaga ULN2803. Mootorite juhtsignaalide mustrid genereeritakse tarkvaraliselt. Samm-mootorite ühendamisel on oluline jälgida mähiste järjekorda. Unipolaarse samm-mootori toiteotsad ühendatakse viikudesse 1 ja 2. Kui tegemist on viie juhtmelise unipolaarse samm-mootoriga, | ||
- | |||
- | ^ Pesa viik ^ Mähise ots ^ Unipolaar 1 ^ Unipolaar 2 ^ Bipolaar ^ | ||
- | | 1 | 1 | + toide | + toide | | | ||
- | | 2 | 2 | + toide | + toide | | | ||
- | | 3 | 1a | PE0 | PE4 | PB0 | | ||
- | | 4 | 2a | PE1 | PE5 | PB1 | | ||
- | | 5 | 1b | PE2 | PE6 | PB2 | | ||
- | | 6 | 2b | PE3 | PE7 | PB3 | | ||
- | |||
- | |||
- | [{{: | ||
- | |||
- | [{{: | ||
- | |||
- | == Servomootor == | ||
- | |||
- | RC servomootorid ühendatakse mootoriplaadi pistikutesse PWM1 ja PWM2. Mootorid ühendatakse nii, et signaali juhe (tavaliselt kollane või valge) jääb viiku 1 (plaadi ääre pool). Sama-aegselt on võimalik kasutada kahte servomootorit. Mootorite juhtsignaalid on ühendatud otse kontrolleri taimerite väljundviikudega. | ||
- | |||
- | ^ AVR viik ^ Juhtsignaal ^ | ||
- | | PB5(OC1A) | PWM1 | | ||
- | | PB6(OC1B) | PWM2 | | ||
- | |||
- | == Mootorite ühendused == | ||
- | |||
- | [{{ : | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === Mooduli ühendamine === | ||
- | |||
- | Mooduli ühendamisel on soovitatav järgida allolevat järjekorda ja kontrollerplaadi toitepistik ühendada alati kõige viimasena. | ||
- | |||
- | - Ühendada Mootorite mooduli plaat Kontrollermooduli plaadiga, kasutades ribakaablit. | ||
- | - Ühendada mootor(id). | ||
- | - Ühendada Mootorite mooduli plaat toitekaabliga. | ||
- | - Ühendada Kontrollermooduli toide. | ||
- | |||
- | [{{: | ||
- | ===== Kodulabori teek ===== | ||
- | |||
- | Kodulabori teek moodustub mitmetest C-keele päisefailidest (" | ||
- | |||
- | [{{ : | ||
- | |||
- | Sellest, kuidas Kodulabori teeki reaalselt Windows ja Linux operatsioonisüsteemidega kasutama hakata, räägivad esimesed kaks praktilist harjutust. Erinevaid teegi osasid kasutavad erinevad harjutused. Eranditult tuleb igasse teeki kasutavasse projekti kaasata teegi " | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | #include < | ||
- | </ | ||
- | |||
- | Kui Kodulabori teeki ei kasutata, siis on vajalik AVR-i registrite kasutamiseks kaasata projekti: | ||
- | <code c> | ||
- | #include < | ||
- | </ | ||
- | Teegi kasutamise korral seda eraldi teha ei ole vaja, kuna on kaasatud juba failis //pin.h//. | ||
- | |||
- | Kodulabori veebilehel on vabalt kättesaadav Kodulabori teegi lähtekood, mida on võimalik kohandada vastavalt oma projekti vajadustele. Allalaetavas teegis on ka lisafunktsioone, | ||
- | ==== Bitioperatsioonid ==== | ||
- | |||
- | Bitioperatsioonide teek on üldkasutatav makrofunktsioonide kogum tüüpiliste bititehete teostamiseks. Neid funktsioone võib kasutada ükskõik milliste registrite või andmetüüpide puhul, sest makrofunktsioonidel pole kindlat andmetüüpi. Funktsioonid sobivad nii 8-, 16- kui ka 32-bitiste muutujate ning registrite jaoks. Neid bitioperatsioone kasutavad kõik teised teegi osad, seepärast on lähtekoodi alampeatükis funktsioonid ka välja kirjutatud. | ||
- | |||
- | Bitiindeksiks loetakse biti järjekorranumbrit, | ||
- | |||
- | === Funktsioonid === | ||
- | |||
- | * **// | ||
- | Bitiindeksi teisendamine bitimaskiks. Parameetrid: | ||
- | * //bit// - Bitiindeks. | ||
- | * Tagastab bitimaski. | ||
- | |||
- | * **// | ||
- | Muutujas kindla biti kõrgeks seadmine. Parameetrid: | ||
- | * //value// - Muutuja. | ||
- | * //bit// - Bitiindeks. | ||
- | |||
- | * **// | ||
- | Muutujas kindla biti madalaks seadmine. Parameetrid: | ||
- | * //value// - Muutuja. | ||
- | * //bit// - Bitiindeks. | ||
- | |||
- | * **// | ||
- | Muutujas kindla biti soovitud olekusse seadmine. Parameetrid: | ||
- | * //value// - Muutuja. | ||
- | * //bit// - Bitiindeks. | ||
- | * //state// - Tõeväärtus (//true// või //false//). | ||
- | |||
- | * **// | ||
- | Muutujas kindla biti oleku ümberpööramine (madal kõrgeks ja vastupidi). Parameetrid: | ||
- | * //value// - Muutuja. | ||
- | * //bit// - Bitiindeks. | ||
- | |||
- | * **// | ||
- | Väärtuse kindla biti kõrgeloleku kontroll. Parameetrid: | ||
- | * //value// - Muutuja. | ||
- | * //bit// - Bitiindeks. | ||
- | * Tagastab tõeväärtuse //true//, kui bitt on kõrge ja //false//, kui bitt on madal. | ||
- | |||
- | * **// | ||
- | Väärtuse kindla biti madaloleku kontroll. Parameetrid: | ||
- | * //value// - Muutuja. | ||
- | * //bit// - Bitiindeks. | ||
- | * Tagastab tõeväärtuse //true//, kui bitt on madal ja //false//, kui bitt on kõrge. | ||
- | |||
- | === Näide === | ||
- | |||
- | Muutujas //b// kolmanda biti kõrgeks seadmine ja viimase ümberpööramine. | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | |||
- | int main(void) | ||
- | { | ||
- | unsigned char b = 0x00; | ||
- | |||
- | bit_set(b, 2); | ||
- | bit_invert(b, | ||
- | } | ||
- | </ | ||
- | |||
- | === Lähtekood === | ||
- | |||
- | Järgnevalt on lühendatud kujul toodud teegi lähtekood, kust on näha, mis iga makrofunktsiooni taga peitub: | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Funktsioonid bittidega tegelemiseks | ||
- | // | ||
- | #define bit_mask(bit) | ||
- | #define bit_set(value, | ||
- | #define bit_clear(value, | ||
- | #define bit_invert(value, | ||
- | #define bit_is_set(value, | ||
- | #define bit_is_clear(value, | ||
- | #define bit_set_to(v, | ||
- | |||
- | // | ||
- | // Funktsioonid bitimaskidega tegelemiseks | ||
- | // | ||
- | #define bitmask_set(value, | ||
- | #define bitmask_clear(value, | ||
- | #define bitmask_invert(value, | ||
- | #define bitmask_set_to(v, | ||
- | #define bitmask_is_set(value, | ||
- | </ | ||
- | |||
- | ==== Sisend-väljundviigud ==== | ||
- | |||
- | Viikude teek on ette nähtud AVR digitaalsete sisend- ja väljundviikudega opereerimiseks. Teegi eesmärk on lihtsustada AVR viikude kasutamist. Kasutaja saab programmis luua soovitud viigu kohta käiva muutuja, millele ta omistab spetsiaalse makrofunktsiooniga füüsilise viigu aadressi. Seejärel saab muutuja abil välja kutsuda erinevaid funktsioone viigu suuna ja olekute muutmiseks ning nende lugemiseks. | ||
- | |||
- | Määrates viigu füüsilise siini (pordi) ja indeksi ära ainult ühe korra ja ühes kohas, on füüsiliste muudatuste korral lihtne programmi muuta. Näiteks, kui algul kasutatakse indikaatorina ühte LED-i, võib lihtsa tarkvara muudatusega teist LED kasutama hakata. Viigu muutujatest võib luua ka massiive, näiteks siinide koostamiseks. | ||
- | |||
- | === Andmetüübid === | ||
- | |||
- | * **//pin//** \\ Viigu registrite ja bitimaski hoidmise struktuurne andmetüüp. // | ||
- | |||
- | === Funktsioonid === | ||
- | |||
- | * **//void pin_setup_output(pin pin)//** \\ Viigu väljundiks määramine. Parameetrid: | ||
- | * //pin// - Viigu muutuja. | ||
- | * **//void pin_setup_input(pin pin)//** \\ Viigu sisendiks määramine ilma //pull-up// takistita. Parameetrid: | ||
- | * //pin// - Viigu muutuja. | ||
- | * **//void pin_setup_input_with_pullup(pin pin)//** \\ Viigu sisendiks määramine koos // | ||
- | * //pin// - Viigu muutuja. | ||
- | * **//void pin_set(pin pin)//** \\ Viigu väljundi kõrgeks määramine. Parameetrid: | ||
- | * //pin// - Viigu muutuja. | ||
- | * **//void pin_clear(pin pin)//** \\ Viigu väljundi madalaks määramine. Parameetrid: | ||
- | * //pin// - Viigu muutuja. | ||
- | * **//void pin_toggle(pin pin)//** \\ Viigu väljundi oleku pööramine. Madal olek muutub kõrgeks ja vastupidi. Parameetrid: | ||
- | * //pin// - Viigu muutuja. | ||
- | * **//void pin_set_to(pin pin, bool value)//** \\ Viigu väljundi parameetriga määratud olekusse viimine. Parameetrid: | ||
- | * //pin// - Viigu muutuja. | ||
- | * //value// - Tõeväärtuse muutuja. | ||
- | * **//bool pin_get_value(pin pin)//** \\ Viigu sisendi oleku lugemine ja funktsiooniga tagastamine. Parameetrid: | ||
- | * //pin// - Viigu muutuja. | ||
- | * Tagastab tõeväärtuse. | ||
- | * **//bool pin_get_debounced_value(pin pin)//** \\ Viigu sisendi oleku lugemine läbi lüliti väreluse filtri ja selle tagastamine. Filtreerimine toimub minimaalselt 8 ms ja maksimaalselt 100 ms jooksul - olenevalt sellest, kui kiiresti lüliti värelemine lõppeb. Kui värelemine 100 ms jooksul ei lõpe, siis funktsioon tagastab //false//. Funktsioon kasutab tarkvaralist pausi funktsiooni viite teegist. Parameetrid: | ||
- | * //pin// - Viigu muutuja. | ||
- | * Tagastab tõeväärtuse. | ||
- | |||
- | === Näide === | ||
- | |||
- | Näide sellest, kuidas ühe viigu väärtus teha sõltuvaks teisest. Programmis omandab viik PC3 viigule PC0 vastupidise väärtuse: | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | |||
- | pin output_pin = PIN(C, 3); | ||
- | pin input_pin = PIN(C, 0); | ||
- | |||
- | int main(void) | ||
- | { | ||
- | bool value; | ||
- | |||
- | // Viigu väljundiks seadistamine | ||
- | pin_setup_output(output_pin); | ||
- | |||
- | // Viigu pull-up takistiga sisendiks seadistamine | ||
- | pin_setup_input_with_pullup(input_pin); | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // Sisendviigu väärtuse lugemine | ||
- | value = pin_get_value(input_pin); | ||
- | |||
- | // Väljundviigule vastupidise väärtuse omistamine | ||
- | pin_set_to(output_pin, | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | ==== Analoog-digitaalmuundur ==== | ||
- | |||
- | Analoog-digitaalmuunduri teek on AVR ADC mooduli kasutamise lihtsustamiseks. Teegi muundamise funktsioonid on blokeeruvad ehk nende väljakutsumisel jääb protsessor muundamise lõppu ootama. Muundamise aeg sõltub ADC taktijagurist. | ||
- | |||
- | === Andmetüübid === | ||
- | |||
- | * **// | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | |||
- | * **// | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | |||
- | === Funktsioonid === | ||
- | |||
- | * **//void adc_init(adc_reference reference, adc_prescale prescale)// | ||
- | * // | ||
- | * // | ||
- | |||
- | * **// | ||
- | * //channel// - ADC kanali number (0 kuni 7). | ||
- | * Tagastab 10-bitise väärtuse. | ||
- | |||
- | * **// | ||
- | * //channel// - ADC kanali number (0 kuni 7). | ||
- | * // | ||
- | * Tagastab 10-bitise keskmistatud väärtuse. | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === Näide === | ||
- | |||
- | Näites seatakse analoog-digitaalmuundur töövalmis ja loetakse kahelt sisendkanalilt pinge. Kanali 0 pingemuundamise väärtus loetakse muutujasse //x// ja kanali 1 väärtus kümnekordse ümardamise tulemusena muutujasse //y//. | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | |||
- | int main(void) | ||
- | { | ||
- | unsigned short x, y; | ||
- | |||
- | // Analoog-digitaalmuunduri seadistamine | ||
- | // Võrdluspinge tuleb AVCC viigult. Muunduri töötakt | ||
- | // on 8 korda madalam kontrolleri taktist. | ||
- | adc_init(ADC_REF_AVCC, | ||
- | |||
- | // Kanali 0 muundatud väärtuse lugemine muutujasse x | ||
- | x = adc_get_value(0); | ||
- | |||
- | // Kanali 1 muundatud ja keskmistatud väärtuse lugemine muutujasse y | ||
- | y = adc_get_average_value(1, | ||
- | } | ||
- | </ | ||
- | |||
- | |||
- | ==== Jadaliides ==== | ||
- | |||
- | Tegu on AVR universaalse jadaliidese kasutamise teegiga. Võimaldab asünkroonset andmete kirjutamist ja lugemist. | ||
- | |||
- | === Andmetüübid === | ||
- | |||
- | * **// | ||
- | * **// | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * **// | ||
- | * // | ||
- | * // | ||
- | * **// | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | |||
- | === Funktsioonid === | ||
- | |||
- | * **// | ||
- | Makrofunktsiooni USART mooduli asünkroonse režiimi boodikiiruse registri väärtuse arvutamiseks. Parameetrid: | ||
- | * //baud// - Boodikiirus. | ||
- | * Tagastab boodikiiruse registri väärtuse. | ||
- | |||
- | * **//void usart_init_async(usart port, usart_databits data_bits, usart_stopbits stop_bits, usart_parity parity, usart_baudrate baudrate)// | ||
- | Jadaliidese asünkroonseks seadistamine. Parameetrid: | ||
- | * //port// - USART liidese muutuja. | ||
- | * // | ||
- | * // | ||
- | * //parity// - Paarsuse tüüp. | ||
- | * // | ||
- | ~~PB~~ | ||
- | * **//void usart_send_char(usart port, char symbol)//** \\ | ||
- | Blokeeruv sümboli saatmise funktsioon. Funktsioon ootab, kuni saatmise puhver tühjeneb ja kirjutab sinna saatmiseks uue sümboli. Parameetrid: | ||
- | * //port// - USART liidese muutuja. | ||
- | * //symbol// - Saadetav sümbol. | ||
- | |||
- | * **//void usart_send_string(usart port, char *text)//** \\ | ||
- | Blokeeruv teksti saatmise funktsioon. Parameetrid: | ||
- | * //port// - USART liidese muutuja. | ||
- | * //text// - Viit tekstile. Tekst peab lõppema binaarse 0 sümboliga. | ||
- | |||
- | * **//bool usart_has_data(usart port)//** \\ | ||
- | Sisendpuhvris andmete olemasolu kontroll. Parameetrid: | ||
- | * //port// - USART liidese muutuja. | ||
- | * Tagastab //true//, kui sisendpuhvris on sümbol ja //false// kui mitte. | ||
- | |||
- | * **//char usart_read_char(usart port)//** \\ | ||
- | Sisendpuhvrist sümboli lugemine. Enne lugemist peab veenduma, et puhvris on sümbol. Parameetrid: | ||
- | * //port// - USART liidese muutuja. | ||
- | * Tagastab sümboli. | ||
- | |||
- | * **//bool usart_try_read_char(usart port, char *symbol)// | ||
- | Sisendpuhvri sümboli olemasolu kontroll ja selle lugemise ühisfunktsioon. Parameetrid: | ||
- | * //port// - USART liidese muutuja. | ||
- | * //symbol// - Viit sümbolile. Kui sisendpuhvris on sümbol, siis see kirjutatakse siia. | ||
- | * Tagastab //true//, kui sisendpuhvris oli sümbol ja //false// kui mitte. | ||
- | |||
- | === Näide === | ||
- | |||
- | Jadaliidese seadmistamine töötab asünkroonselt 8 andmebiti, ühe stoppbiti ja ilma paarsuse kontrollita boodikiirusel 9600. Programm saadab teksti ja loeb sissetuleva sümboli. | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | |||
- | usart port = USART(0); | ||
- | |||
- | int main(void) | ||
- | { | ||
- | char c; | ||
- | |||
- | // Jadaliidese seadistamine | ||
- | usart_init_async(port, | ||
- | USART_PARITY_NONE, | ||
- | |||
- | // Teksti saatmine | ||
- | usart_send_string(port, | ||
- | |||
- | // Sissetuleva sümboli ootamine | ||
- | while (!usart_has_data(port)) {} | ||
- | |||
- | // Sümboli lugemine | ||
- | c = usart_read_char(port); | ||
- | } | ||
- | </ | ||
- | |||
- | ==== Taimerid ==== | ||
- | |||
- | Käesolev taimerite teek katab suure osa ATmega128 taimerite funktsionaalsusest. Kuna AVR taimerid on erinevate kiipide vahel päris erinevad, siis ei saa nende kasutamiseks kirjutada universaalseid funktsioone. Ka kirjeldatavad ATmega128 funktsioonid on suures osas lihtsalt primitiivsed registri muutmise või lugemise funktsioonid, | ||
- | |||
- | === Andmetüübid === | ||
- | |||
- | * **// | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | |||
- | * **// | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | |||
- | * **// | ||
- | * **// | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | ~~PB~~ | ||
- | * **// | ||
- | * **// | ||
- | * // | ||
- | * // | ||
- | |||
- | * **// | ||
- | * **// | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | |||
- | * **// | ||
- | * **// | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | |||
- | === Funktsioonid === | ||
- | |||
- | * **//void timer0_init_normal(timer0_prescale prescale)// | ||
- | * // | ||
- | |||
- | * **//void timer2_init_normal(timer2_prescale prescale)// | ||
- | * // | ||
- | |||
- | * **//void timer0_stop()// | ||
- | * **//void timer2_stop()// | ||
- | |||
- | * **// | ||
- | * **// | ||
- | * Tagastab 8-bitise loenduri hetkeväärtuse. | ||
- | |||
- | * **//void timer0_set_value(unsigned char value)//** | ||
- | * **//void timer2_set_value(unsigned char value)//** \\ Taimer 0/2 loenduri uue väärtuse määramine. Parameetrid: | ||
- | * //value// - Uus 8-bitine loenduri väärtus. | ||
- | |||
- | * **//void timer0_overflow_interrupt_enable(bool enable)//** | ||
- | * **//void timer2_overflow_interrupt_enable(bool enable)//** \\ Taimer 0/2 ületäitumise katkestuse lubamine või keelamine. Katkestuse vektor on TIMERn_OVF_vect kus " | ||
- | * //enable// - Tõeväärtus katkestuse lubamiseks või keelamiseks. //true// lubab, //false// keelab. | ||
- | |||
- | * **//bool timer0_overflow_flag_is_set(void)// | ||
- | * **//bool timer2_overflow_flag_is_set(void)// | ||
- | * Tagastab tõeväärtuse //true//, kui ületäitumine on toimunud, ja //false//, kui pole. | ||
- | |||
- | * **//void timer0_overflow_flag_clear(void)// | ||
- | * **//void timer2_overflow_flag_clear(void)// | ||
- | |||
- | * **//void timer1_init_normal(timer1_prescale prescale)// | ||
- | * **//void timer3_init_normal(timer3_prescale prescale)// | ||
- | * // | ||
- | |||
- | * **//void timer1_init_ctc(timer1_prescale prescale, timer1_ctc_top top)//** | ||
- | * **//void timer3_init_ctc(timer3_prescale prescale, timer3_ctc_top top)//** \\ Taimer 1/3 CTC (inglise keeles //Clear Timer on Compare Match//) režiimi seadistamine. Selles režiimis taimer ei loenda mitte 65535-ni, vaid valitud registri väärtuseni ja tekitab soovi korral sinnani jõudes katkestuse. Parameetrid: | ||
- | * // | ||
- | * //top// - Taimeri maksimaalse väärtuse registri valik. Valida saab kahe registri vahel, mille mõlema muutmiseks on omaette funktsioonid. Mõlemad registrid võib loenduri tippu jõudes katkestust tekitama seadistada. | ||
- | |||
- | * **//void timer1_init_fast_pwm(timer1_prescale prescale, timer1_fast_pwm_top top, timer1_fast_pwm_output_mode output_a, timer1_fast_pwm_output_mode output_b, timer1_fast_pwm_output_mode output_c)// | ||
- | * **//void timer3_init_fast_pwm(timer3_prescale prescale, timer3_fast_pwm_top top, timer3_fast_pwm_output_mode output_a, timer3_fast_pwm_output_mode output_b, timer3_fast_pwm_output_mode output_c)// | ||
- | * // | ||
- | * //top// - Taimeri maksimaalse väärtuse valik. Valida saab konstantide ja kahe registri vahel. Mõlemad registrid võib loenduri tippu jõudes katkestust tekitama seadistada. | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | |||
- | * **//void timer1_stop()// | ||
- | * **//void timer3_stop()// | ||
- | |||
- | * **// | ||
- | * **// | ||
- | * Tagastab 16-bitise loenduri hetkeväärtuse. | ||
- | |||
- | * **//void timer1_set_value(unsigned char value)//** | ||
- | * **//void timer3_set_value(unsigned char value)//** \\ Taimeri 1/3 loenduri uue väärtuse määramine. Parameetrid: | ||
- | * //value// - Uus 16-bitine loenduri väärtus. | ||
- | |||
- | * **// | ||
- | * **// | ||
- | * **// | ||
- | * **// | ||
- | * **// | ||
- | * **// | ||
- | * Tagastab 16-bitise üksuse võrdlusregistri väärtuse. | ||
- | |||
- | * **//void timer1_set_compare_match_unitA_value(unsigned short value)//** | ||
- | * **//void timer1_set_compare_match_unitB_value(unsigned short value)//** | ||
- | * **//void timer1_set_compare_match_unitC_value(unsigned short value)//** | ||
- | * **//void timer3_set_compare_match_unitA_value(unsigned short value)//** | ||
- | * **//void timer3_set_compare_match_unitB_value(unsigned short value)//** | ||
- | * **//void timer3_set_compare_match_unitC_value(unsigned short value)//** \\ Taimeri 1/3 signaali genereerimise üksuse A/B/C võrdlusväärtuse määramine. Parameetrid: | ||
- | * //value// - Uus 16-bitine võrdlusväärtus. | ||
- | |||
- | * **// | ||
- | * **// | ||
- | * Tagastab 16-bitise sündmuste loenduri registri väärtuse. | ||
- | |||
- | * **//void timer1_set_input_capture_value(unsigned short value)//** | ||
- | * **//void timer3_set_input_capture_value(unsigned short value)//** \\ Taimer 1/3 sündmuste loenduri registri väärtuse määramine. Parameetrid: | ||
- | * //value// - Uus 16-bitine sündmuste loenduri väärtus. | ||
- | |||
- | * **//void timer1_overflow_interrupt_enable(bool enable)//** | ||
- | * **//void timer3_overflow_interrupt_enable(bool enable)//** \\ Taimer 1/3 ületäitumise katkestuse lubamine või keelamine. Katkestuse vektor on TIMERn_OVF_vect, | ||
- | * //enable// - Tõeväärtus katkestuse lubamiseks või keelamiseks. //true// lubab, //false// keelab. | ||
- | |||
- | * **//void timer1_compare_match_unitA_interrupt_enable(bool enable)//** | ||
- | * **//void timer1_compare_match_unitB_interrupt_enable(bool enable)//** | ||
- | * **//void timer1_compare_match_unitC_interrupt_enable(bool enable)//** | ||
- | * **//void timer3_compare_match_unitA_interrupt_enable(bool enable)//** | ||
- | * **//void timer3_compare_match_unitB_interrupt_enable(bool enable)//** | ||
- | * **//void timer3_compare_match_unitC_interrupt_enable(bool enable)//** \\ Taimer 1/3 signaali genereerimise üksuse A/B/C võrdluse sündmuse katkestuse lubamine või keelamine. Katkestuse vektor on TIMERn_COMPx_vect, | ||
- | * //enable// - Tõeväärtus katkestuse lubamiseks või keelamiseks. //true// lubab, //false// keelab. | ||
- | |||
- | * **//void timer1_input_capture_interrupt_enable(bool enable)//** | ||
- | * **//void timer3_input_capture_interrupt_enable(bool enable)//** \\ Taimer 1/3 sündmuste loenduri katkestuse lubamine või keelamine. Katkestuse vektor on // | ||
- | * //enable// - Tõeväärtus katkestuse lubamiseks või keelamiseks. //true// lubab, //false// keelab. | ||
- | |||
- | * **//bool timer1_overflow_flag_is_set(void)// | ||
- | * **//bool timer3_overflow_flag_is_set(void)// | ||
- | * Tagastab tõeväärtuse //true//, kui ületäitumine on toimunud, ja //false//, kui pole. | ||
- | |||
- | * **//bool timer1_input_capture_flag_is_set(void)// | ||
- | * **//bool timer3_input_capture_flag_is_set(void)// | ||
- | * Tagastab tõeväärtuse //true//, kui sündmus on toimunud, ja //false//, kui pole. | ||
- | |||
- | * **//void timer1_overflow_flag_clear(void)// | ||
- | * **//void timer3_overflow_flag_clear(void)// | ||
- | |||
- | * **//void timer1_input_capture_flag_clear(void)// | ||
- | * **//void timer3_input_capture_flag_clear(void)// | ||
- | |||
- | === Näide === | ||
- | |||
- | Näites seadistatakse taimer 0 tavalisse loendamise režiimi ja lubatakse ületäitumise katkestus. | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | #include < | ||
- | |||
- | // Katkestuse programmilõik | ||
- | ISR(TIMER0_OVF_vect) | ||
- | { | ||
- | } | ||
- | |||
- | int main(void) | ||
- | { | ||
- | // Taimer 0 normaalrežiimi, | ||
- | timer0_init_normal(TIMER0_PRESCALE_32); | ||
- | |||
- | // Taimer 0 ületäitumise katkestuse lubamine | ||
- | timer0_overflow_interrupt_enable(true); | ||
- | |||
- | // Globaalne katkestuste lubamine | ||
- | sei(); | ||
- | } | ||
- | </ | ||
- | |||
- | ==== Viide ==== | ||
- | |||
- | Tegu on tarkvaraliste ja riistvaraliste viite tekitamise funktsioonide teegi osaga. Viite funktsioone välja kutsudes jääb programm neid ettenähtud ajaks täitma ja muu programmi, välja arvatud katkestuste, | ||
- | |||
- | Viitefunktsioonid pole eelnevalt kompileeritud, | ||
- | |||
- | === Funktsioonid === | ||
- | |||
- | * **//void sw_delay_ms(unsigned short count)//** \\ Tarkvaraline viide millisekundites. Funktsiooni kasutamine eeldab kompilaatorilt optimeerimise kasutust. Parameetrid: | ||
- | * //count// - Viite aeg millisekundites. 0 kuni 65535 millisekundit. | ||
- | * **//void sw_delay_us(unsigned short count)//** \\ Tarkvaraline viide mikrosekundites. Funktsiooni kasutamine eeldab kompilaatorilt optimeerimise kasutust. Parameetrid: | ||
- | * //count// - Viite aeg mikrosekundites. 0 kuni 65535 mikrosekundit. | ||
- | * **//void hw_delay_ms(unsigned short count)//** \\ Riistvaraline taimeril põhinev viide millisekundites. Funktsioon kasutab ATmega128 8-bitist taimerit 0. Olenevalt taktsagedusest võib tekkida kuni mõne millisekundi suurune viga. Täpsema viite saaks teha 16-bitiste taimeritega, | ||
- | * //count// - Viite aeg millisekundites. 0 kuni 65535 millisekundit. | ||
- | |||
- | === Näide === | ||
- | |||
- | Mõlemat liiki viitefunktsioonide kasutamise näide: | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | |||
- | int main(void) | ||
- | { | ||
- | // Tarkvaraline viide 100 ms | ||
- | sw_delay_ms(100); | ||
- | |||
- | // Riistvaraline viide 100 ms | ||
- | hw_delay_ms(100); | ||
- | } | ||
- | </ | ||
- | |||
- | ==== 7-segmendiline LED indikaator ==== | ||
- | |||
- | //Seotud mooduliga: [HW] [[et: | ||
- | |||
- | See teek on spetsiaalselt loodud Kodulabori Digitaalse sisend-väljundmooduli plaadil asuva indikaatori kasutamiseks. 7-segmendilise indikaatoriga saab kuvada numbreid 0 kuni 9 ja mõningaid tähti. | ||
- | |||
- | === Funktsioonid === | ||
- | |||
- | * **//void segment_display_init(void)// | ||
- | Indikaatori juhtviikude seadmistamine väljundiks. | ||
- | |||
- | * **//void segment_display_write(unsigned char digit)//** \\ | ||
- | Soovitud numbri kuvamine indikaatoriga. Parameetrid: | ||
- | * //digit// - Number 0 kuni 9. Muude väärtuste puhul kuvatakse E nagu //error// (viga). | ||
- | |||
- | === Näide === | ||
- | |||
- | Näites on number 5 kuvamise protseduur. | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | |||
- | int main(void) | ||
- | { | ||
- | // 7-segmendilise indikaatori seadistamine | ||
- | segment_display_init(); | ||
- | |||
- | // Indikaatoril numbri 5 kuvamine | ||
- | segment_display_write(5); | ||
- | } | ||
- | </ | ||
- | |||
- | |||
- | |||
- | |||
- | ==== Alfabeetiline LCD ==== | ||
- | |||
- | //Seotud mooduliga: [HW] [[et: | ||
- | |||
- | See teegi osa sisaldab Kodulabori alfabeetilise LCD kasutamise funktsioone. | ||
- | |||
- | === Andmetüübid === | ||
- | |||
- | * **// | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | |||
- | === Funktsioonid === | ||
- | |||
- | * **//void lcd_alpha_init(lcd_alpha_mode disp_attr)// | ||
- | * // | ||
- | |||
- | * **//void lcd_alpha_clear(void)// | ||
- | |||
- | * **//void lcd_alpha_clear_line(unsigned char line)//** \\ Ekraani ühe rea tühjendamine. Kursor viiakse pärast tühjendamist tühjendatud rea algusesse. Parameetrid: | ||
- | * //line// - Rea number. Väärtus 0 või 1. | ||
- | |||
- | * **//void lcd_alpha_home(void)// | ||
- | * **//void lcd_alpha_goto_xy(unsigned char x, unsigned char y)//** - Kursori soovitud positsioonile viimine. Parameetrid: | ||
- | * //x// - X koordinaat (veeru number). Väärtus 0 kuni 15. | ||
- | * //y// - Y koordinaat (rea number). Väärtus 0 või 1. | ||
- | |||
- | * **//void lcd_alpha_write_char(char c)//** \\ Sümboli kuvamine ekraani kursori positsioonil. Parameetrid: | ||
- | * //c// - ASCII sümbol. | ||
- | |||
- | * **//void lcd_alpha_write_string(const char *s)//** \\ Teksti kuvamine ekraanil kursori positsioonist alates. Parameetrid: | ||
- | * //s// - Teksti viit. | ||
- | |||
- | * **//void lcd_alpha_write_string_p(const char *progmem_s)// | ||
- | * // | ||
- | |||
- | === Näide === | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | |||
- | int main(void) | ||
- | { | ||
- | // Ekraani seadistamine | ||
- | lcd_alpha_init(LCD_ALPHA_DISP_ON); | ||
- | |||
- | // LCD ekraani puhastamine | ||
- | lcd_alpha_clear(); | ||
- | |||
- | // Kursori (nähtamatu) teise rea algusesse viimine | ||
- | lcd_alpha_goto_xy(0, | ||
- | |||
- | // Teksti kuvamine | ||
- | lcd_alpha_write_string(" | ||
- | } | ||
- | </ | ||
- | |||
- | ==== Graafiline LCD ==== | ||
- | |||
- | //Seotud mooduliga: [HW] [[et: | ||
- | |||
- | See teegi osa sisaldab Kodulabori graafilise LCD kasutamise funktsioone. Kuigi LCD on graafiline, puuduvad teegist hetkel siiski kujundite joonistamise funktsioonid. | ||
- | |||
- | === Funktsioonid === | ||
- | |||
- | * **//void lcd_gfx_init(void)// | ||
- | |||
- | * **//void lcd_gfx_backlight(bool set)//** \\ Ekraani taustvalgustuse lülitamine. Parameetrid: | ||
- | * //set// - Tõeväärtus taustvalgustuse töötamisest. //true// puhul taustvalgustus on sees, //false// puhul väljas. | ||
- | |||
- | * **//void lcd_gfx_clear(void)// | ||
- | |||
- | * **//void lcd_gfx_clear_line(unsigned char line)//** \\ Ekraani ühe tekstirea kustutamine. Parameetrid: | ||
- | * //line// - Rea number 0 kuni 5. | ||
- | |||
- | * **//void lcd_gfx_goto_char_xy(unsigned char x, unsigned char y)//** - Märgi positsiooni valik teksti väljastamiseks. Parameetrid: | ||
- | * //x// - X koordinaat. Väärtus 0 kuni 13. | ||
- | * //y// - Y koordinaat. Väärtus 0 kuni 5. | ||
- | |||
- | * **//void lcd_gfx_write_char(char c)//** \\ Sümboli kuvamine ekraanil eelnevalt määratud positsioonil. Parameetrid: | ||
- | * //c// - ASCII sümbol. | ||
- | |||
- | * **//void lcd_gfx_write_string(char *s)//** \\ Teksti kuvamine ekraanil eelnevalt määratud positsioonist alates. Parameetrid: | ||
- | * //s// - Teksti viit. | ||
- | |||
- | === Näide === | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | |||
- | int main(void) | ||
- | { | ||
- | // Ekraani seadistamine | ||
- | lcd_gfx_init(); | ||
- | |||
- | // LCD ekraani puhastamine | ||
- | lcd_gfx_clear(); | ||
- | |||
- | // Kursori (nähtamatu) ekraani keskele viimine | ||
- | lcd_gfx_goto_char_xy(5, | ||
- | |||
- | // Teksti kuvamine | ||
- | lcd_gfx_write_string(" | ||
- | } | ||
- | </ | ||
- | ==== Mootorid ==== | ||
- | |||
- | //Seotud mooduliga: [HW] [[et: | ||
- | |||
- | Mootorite teek võimaldab juhtida Kodulabori mootorite moodulit ja mootoreid, mis sinna ühenduvad. Olemas on alalisvoolu-, | ||
- | |||
- | === Funktsioonid === | ||
- | |||
- | * **//void dcmotor_init(unsigned char index)//** \\ | ||
- | Ühe alalisvoolu mootorikontrolleri juhtviikude seadistamine väljundiks. Parameetrid: | ||
- | * //index// - Mootorikontrolleri number. Väärtus 0 kuni 3. | ||
- | |||
- | * **//void dcmotor_drive(unsigned char index, signed char direction)// | ||
- | Alalisvoolu mootorikontrolleri juhtkäsk. Parameetrid: | ||
- | * //index// - Mootorikontrolleri number. Väärtus 0 kuni 3. | ||
- | * // | ||
- | |||
- | * **//void bipolar_init(void)// | ||
- | Bipolaarse mootorikontrolleri juhtviikude seadistamine väljundiks. | ||
- | |||
- | * **//void bipolar_halfstep(signed char direction, unsigned short num_steps, unsigned char speed)//** \\ | ||
- | Bipolaarse samm-mootori mootorikontrolleri poolsammumise juhtkäsk. Funktsioon on blokeeruv ehk seda täidetakse seni, kuni soovitud arv samme on tehtud. Parameetrid: | ||
- | * // | ||
- | * // | ||
- | * //speed// - Ühe sammu tegemise aeg millisekundites. | ||
- | |||
- | * **//void servomotor_init(unsigned char index)//** \\ | ||
- | Ühe servomootori juhtviikude väljundiks seadistamine ja taimer 1 seadistamine PWM režiimi. Parameetrid: | ||
- | * //index// - Servomootori number. Väärtus 0 või 1. | ||
- | |||
- | * **//void servomotor_position(unsigned char index, signed short position)// | ||
- | Servomootori juhtkäsk. Kui juhitakse positsioneerivat servomootorit, | ||
- | * //index// - Servomootori number. Väärtus 0 või 1. | ||
- | * // | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === Näide === | ||
- | |||
- | Järgnev näide demonstreerib kõiki teegi funktsioone. Järjest seadistatakse mootorikontrollerid ja liigutatakse mootoreid. | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | |||
- | int main(void) | ||
- | { | ||
- | // Alalisvoolu mootorikontrollerite 0 ja 1 seadistamine | ||
- | dcmotor_init(0); | ||
- | dcmotor_init(1); | ||
- | |||
- | // Bipolaarse samm-mootori kontrolleri seadistamine | ||
- | bipolar_init(); | ||
- | |||
- | // Servomootorite 0 ja 1 juhtsignaalide seadistamine | ||
- | servomotor_init(0); | ||
- | servomotor_init(1); | ||
- | |||
- | // Üks alalisvoolu mootor pöörlema ühtpidi, teine teistpidi | ||
- | dcmotor_drive(0, | ||
- | dcmotor_drive(1, | ||
- | |||
- | // Samm-mootori pööramine 100 kraadi ühele poole ja seejärel | ||
- | // 2 korda kiiremini teisele poole | ||
- | bipolar_halfstep(1, | ||
- | bipolar_halfstep(-1, | ||
- | |||
- | // Servomootorite vastassuunda keeramine | ||
- | servomotor_position(0, | ||
- | servomotor_position(1, | ||
- | } | ||
- | </ | ||
- | |||
- | |||
- | |||
- | |||
- | ==== Andurid ==== | ||
- | |||
- | //Seotud mooduliga: [HW] [[et: | ||
- | |||
- | See teegi osa sisaldab Kodulabori andurite kasutamise funktsioone. | ||
- | |||
- | === Andmetüübid === | ||
- | |||
- | * **// | ||
- | * //a// - jagatav. | ||
- | * //b// - vabaliige. | ||
- | * //k// - korrigeerimiskonstant. | ||
- | |||
- | === Konstandid === | ||
- | |||
- | * **// | ||
- | |||
- | === Funktsioonid === | ||
- | |||
- | * **//signed short thermistor_calculate_celsius(unsigned short adc_value)// | ||
- | Termistori temperatuuri arvutamine Celsiuse kraadides ADC muunduri väärtusest. Funktsioon põhineb teisendustabelil. Parameetrid: | ||
- | * // | ||
- | * Tagastab temperatuuri Celsiuse kraadides -20 kuni 100 kraadi piires. | ||
- | |||
- | * **//signed short ir_distance_calculate_cm(ir_distance_sensor sensor, unsigned short adc_value)// | ||
- | IR kaugusanduri väljundpinge ADC väärtuse sentimeetriteks ümberarvutamise funktsioon. Parameetrid: | ||
- | * //sensor// - Kaugusanduri parameetrite struktuuri objekt. | ||
- | * // | ||
- | * Tagastab kauguse sentimeetrites või -1, kui seda ei saanud arvutada. | ||
- | |||
- | * **// | ||
- | Ultraheli-kaugusanduri mõõtmise teostamise funktsioon. Funktsioon tekitab SRF04 kaugusmõõdiku päästikuimpulsi ja mõõdab kajaimpulsi saabumise aega. Aja põhjal arvutatakse objekti kaugus. Mõõtmine võtab aega kuni 36 ms. Funktsioon eeldab 14.7456 MHz mikrokontrolleri taktsagedust. Parameetrid: | ||
- | * //trigger// - päästiku viigu muutuja. | ||
- | * //echo// - kaja viigu muutuja. | ||
- | * Tagastab kauguse sentimeetrites või 0, kui mõõtmine ebaõnnestus. | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === Näide === | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | |||
- | // Ultraheli kaugusmõõdiku juhtviigud | ||
- | pin pin_trigger = PIN(G, 1); | ||
- | pin pin_echo | ||
- | |||
- | int main(void) | ||
- | { | ||
- | unsigned short adc_value = 400; // näidisväärtus | ||
- | signed short distance; | ||
- | |||
- | // IR kaugusanduri ADC väärtuse sentimeetriteks teisendamine | ||
- | distance = ir_distance_calculate_cm(GP2Y0A21YK, | ||
- | |||
- | // Ultraheli-kaugusanduriga mõõtmine | ||
- | distance = ultrasonic_measure(pin_trigger, | ||
- | } | ||
- | </ | ||
- | |||
- | ====== Praktilised näited ====== | ||
- | {{ : | ||
- | |||
- | Praktilised näited on üles ehitatud | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | **Ülesehitus** | ||
- | |||
- | Praktiliste näidete peatükkide juures on toodud loetelu näite läbimiseks vajalikest eelteadmistest. Loetelus on viited raamatu teistele peatükkidele, | ||
- | |||
- | * [HW] Näites kasutatud riistvara moodul | ||
- | * [LIB] Näites kasutatud tarkvara teegi osa | ||
- | * [ELC] Viide elektroonika baasteadmiste peatükile | ||
- | * [AVR] Viide AVR mikrokontrolleri mooduli peatükile | ||
- | * [PRT] Viide teisele harjutusele | ||
- | |||
- | **Näidete baastarkvara** | ||
- | |||
- | Nagu eespool öeldud, on praktilised koodinäited koostatud Kodulabori teegi baasil. Teeki on kirjutatud enimkasutatavad AVR spetsiifilised operatsioonid ja Kodulabori moodulitega seotud protseduurid. Teegi kasutamine tähendab, et kasutaja ei pea moodulite töölepanekuks kirjutama riistvaralähedast, | ||
- | |||
- | **Näidete koodistiil** | ||
- | |||
- | Näidisprogrammid on kirjutatud ühtses stiilis, et programmikood oleks ülevaatlikum. Ühtne stiil teeb programmi loetavaks ja välistab kergemate süntaksivigade tekkimise. Kindlat stiili on soovitatav järgida ka harjutusülesannete tegemisel. Stiili peamised iseloomustajad: | ||
- | |||
- | * Programm, selle funktsioonid ja muutujad on ingliskeelsed ning väiketähtedega, | ||
- | * Funktsioonid on kujul // | ||
- | * Olulisemad kohad programmis on kommenteeritud eesti keeles. | ||
- | * Iga C-keele plokk (tähistatud loogeliste sulgudega { ja } ) algab ja lõpeb eraldi real. | ||
- | * Plokid on tabuleeritud tabulaatorklahviga. Reasiseselt tabulaatorit ei kasutata. | ||
- | ===== Alustamine ===== | ||
- | |||
- | {{: | ||
- | |||
- | AVR mikrokontrolleri programmeerimiseks on vaja koodi kirjutamise keskkonda, vastava keele kompilaatorit ja kompileeritud programmi kontrollerisse laadimise tarkvara. Mugavaim on kasutada kõigeks selleks spetsiaalset integreeritud arenduskeskkonda (IDE). AVR mikrokontrollerit on võimalik programmeerida paljudes erinevates programmeerimiskeeltes: | ||
- | |||
- | Kogu vajaliku installeeritava tarkvara harjutuste läbimiseks leiab Kodulabori veebilehelt. | ||
- | ==== Tarkvara Windowsi keskkonnas ==== | ||
- | |||
- | Järgnev juhend kirjeldab AVR arenduskeskkonna installeerimist ja kasutamist Windowsi operatsioonisüsteemis. | ||
- | |||
- | === Tarkvara paigaldamine === | ||
- | |||
- | Enne paigaldamist tuleks hankida alljärgnev tarkvara, kas tootja või Kodulabori kodulehelt või Kodulabori kohvriga kaasas olevalt plaadilt. | ||
- | |||
- | **1. AVR Studio** | ||
- | |||
- | AVR Studio 4 on IDE (inglise keeles // | ||
- | |||
- | **2. WinAVR** | ||
- | |||
- | WinAVR on GNU-GCC kompilaator AVR mikrokontrolleritele. See on vabavara, mille leiab Sourceforge veebilehelt. WinAVR pakub installeerimisel välja kataloogi nime, mis sisaldab lisaks nimele versiooni numbrit, kuid kataloog tuleks käsitsi muuta lihtsalt: | ||
- | |||
- | C:\WinAVR | ||
- | |||
- | **3. Kodulabori teek** | ||
- | |||
- | Kodulabori teek sisaldab programmi lihtsustavaid funktsioone AVR ja Kodulabori komplekti osade kasutamiseks. Teegi viimase versiooni leiab Kodulabori veebilehelt. Teek tuleb kindlasti installeerida samasse kataloogi, kus on WinAVR. | ||
- | |||
- | **4.. Virtuaalne COM pordi ajur** | ||
- | |||
- | Ajur võimaldab arvutiga ühendada JTAG ICE programmaatori. Ajur tuleb installeerida enne programmaatori ühendamist arvutiga. Paigaldusprogrammi nimi on "CDM x.xx.xx.exe", | ||
- | |||
- | {{ : | ||
- | |||
- | Sõltuvalt sellest, kui palju virtuaalseid jadaporte on arvutisse eelnevalt paigaldatud ja kasutusele võetud, paigaldab Windows automaatselt järgmise järjekorranumbriga virtuaalpordi. Uus järjekorranumber genereeritakse ka USB pordi vahetamisel. AVR Studio mõned versioonid tunnevad JTAG ICE programmaatori ära ainult jadaportides COM1...COM9 ja silumise funktsiooni lubavad kasutada ainult jadaportides COM1...COM4. Kasutajal on võimalus pordi järjekorranumbrit muuta, kasutades //Device manager// töövahendit. [[et: | ||
- | |||
- | === Projekti loomine === | ||
- | |||
- | AVR programmi kirjutamiseks tuleb luua uus projekt, mis tüüpiliselt sisaldab endas palju erinevaid faile: programmikoodi(e), | ||
- | |||
- | Uue projekti loomiseks tuleb läbida järgmised sammud: | ||
- | |||
- | **1.** Avada AVR Studio ja vajutada nupule uus projekt (//New Project//). Juhul kui vastav aken automaatselt ei avane, valida menüüst //Project - New project//. Pärast sobivat sisestust vajutada nupule //Next//. | ||
- | |||
- | {{ : | ||
- | |||
- | **2.** Avaneb aken, kus tuleb märkida kompilaatori ja failide algseaded. Kompilaatoriks valida AVR GCC ja paremas akna osas sisestada projekti nimi ning algkoodi faili nimi. Algkoodi faili nimi peaks kindlasti lõppema laiendiga " | ||
- | |||
- | NB! Kui kompilaatori valikus puudub AVR GCC, siis ei ole WinAVR korrektselt paigaldatud ja seda tuleks enne C-keele programmi kirjutamist kindlasti teha. | ||
- | |||
- | {{ : | ||
- | |||
- | **3.** Järgnevalt avaneb aken, kus tuleb märkida kasutatav silumise platvorm ja mikrokontrolleri tüüp. Kodulaboris on silumise platvormina kasutusel //JTAG ICE// programmaator ja mikrokontrolleriks on // | ||
- | |||
- | {{ : | ||
- | |||
- | **4.** Nüüd avaneb juba programmeerimise kasutajaliides, | ||
- | |||
- | {{ : | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | **5.** Enne koodi kompileerimist tuleb määrata projekti seaded. Olulisemad seaded on kontrolleri taktsagedus ja kompilaatori optimeerimismeetod. Kodulabori kontrolleri taktsagedus on 14,7456 MHz ehk 14745600 Hz. See sagedus tuleb hertsides määrata //Project -> Configuration Options -> General// aknas. Optimeerimise meetodiks jätta -Os, kui ei ole konkreetset vajadust teiste meetodite järgi. | ||
- | |||
- | {{ : | ||
- | |||
- | **6.** Kodulabori teegi kasutamine AVR Studio-ga eeldab, et see on tarkvara paigaldamise juhendi kohaselt süsteemi paigaldatud. Iga projekti korral tuleb teek projekti seadetest //Project -> Configuration Options -> Libraries// lisada lingitavate objektide nimekirja. | ||
- | |||
- | {{ : | ||
- | |||
- | Kui objekt // | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === Seadistuste testimine === | ||
- | |||
- | Kui arenduskeskkond on esimest korda paigaldatud ja seadistatud, | ||
- | |||
- | **1.** Ühendada programmaator ATmega128 plaadiga. Ühendamisel kontrollida, | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | #include < | ||
- | |||
- | int main(void) | ||
- | { | ||
- | // Viigu PB7 seadmine väljundiks | ||
- | DDRB = 0x80; | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // Viigu PB7 inverteerimine | ||
- | PORTB ^= 0x80; | ||
- | hw_delay_ms(500); | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | [{{ : | ||
- | |||
- | Kompileerida programm käsuga //Build// (kiirklahv F7) ja kontrollida, | ||
- | |||
- | Build succeeded with 0 Warnings... | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | **2.** Avada koodi laadimise aken nupust //Tools -> Program AVR -> Auto Connect//. Tulemuseks peaks avanema kompileeritud faili mikrokontrollerisse laadimise aken. Kontrollige, | ||
- | |||
- | {{ : | ||
- | |||
- | Kui eespool toodud aken ei avane ja avaneb aken // | ||
- | |||
- | {{ : | ||
- | |||
- | **3.** Programmaatori aknas sisestada // | ||
- | |||
- | OK | ||
- | Reading FLASH input file.. OK | ||
- | Setting device parameters for jtag programming ..OK | ||
- | Entering programming mode.. OK | ||
- | Erasing device.. OK | ||
- | Programming FLASH .. OK | ||
- | Reading FLASH .. OK | ||
- | FLASH contents is equal to file.. OK | ||
- | Leaving programming mode.. OK | ||
- | |||
- | Programmi mõjul peaks kontrolleri plaadil olev oleku-LED PB7 perioodiliselt süttima ja kustuma. Kui programm töötab, on tarkvara paigaldatud edukalt ja esimene projekt tehtud. Palju õnne! | ||
- | |||
- | {{: | ||
- | |||
- | === Siluri kasutamine === | ||
- | |||
- | [{{ : | ||
- | |||
- | Programmi silumiseks (inglise keeles // | ||
- | |||
- | Programmi käivitamiseks siluri režiimis AVR Studio-ga tuleks see esmalt kompileerida nupuga //Build// (kiirklahv F7) ja käivitada kompileeritud programm käsuga //Run// (kiirklahv F5). Programmi lähtekoodi võib enne seda soovitud kohtadele lisada katkestuspunkte (inglise keeles //break point//) (kiirklahv F9). Kui programmi täitmine jõuab katkestuspunktini, | ||
- | |||
- | === Ujukoma-arvude kasutamine === | ||
- | |||
- | Mõnikord tekib vajadus AVR programmis kasutada ujukoma-arve. Nendega arvutamiseks ja nende esitamiseks // | ||
- | |||
- | **1.** Avada projekti seaded menüüst //Project -> Configuration Options//. Seadete kaardil // | ||
- | |||
- | **2.** Seejärel tuleb avada //Custom Options// kaart ja valida //[All files]// sektsioon. Parempoolsesse kasti lisada read " | ||
- | |||
- | **3.** Vajutada OK ja sulgeda seadete aken. | ||
- | ==== Tarkvara Linuxi keskkonnas ==== | ||
- | |||
- | Järgnev juhend kirjeldab AVR arenduskeskkonna installeerimist ja kasutamist Ubuntu 9.10 operatsioonisüsteemis. | ||
- | |||
- | === Tarkvara paigaldamine === | ||
- | |||
- | Installeerida järgnev tarkvara: | ||
- | |||
- | **1. Linuxi tarkvarapaketid** | ||
- | |||
- | * gcc-avr – GNU C-keele kompilaator AVR platvormile | ||
- | * avrdude – programm hex-faili laadimiseks mikrokontrollerisse | ||
- | * avr-libc – C-keele teegid koodi kirjutamiseks AVR platvormile | ||
- | |||
- | Installeerimiseks kasutada terminali käsurida: | ||
- | |||
- | sudo apt-get install gcc-avr avrdude avr-libc | ||
- | |||
- | või graafilist paketihaldustarkvara (näiteks Ubuntu tarkvarakeskus või Synaptic pakihaldur). | ||
- | |||
- | **2. Kodulabori teek** | ||
- | |||
- | Teek lihtsustab programmikoodi kirjutamist, | ||
- | |||
- | sudo sh homelab_library_vX.X.run | ||
- | |||
- | Veendu, et Kodulabori teegi allalaadimine ja paigaldamine õnnestus. | ||
- | |||
- | **3. KontrollerLab** | ||
- | |||
- | KontrollerLab on IDE (inglise keeles // | ||
- | |||
- | sudo dpkg -i kontrollerlab*.deb | ||
- | |||
- | Kui tekib probleeme paketisõltuvuses, | ||
- | |||
- | sudo apt-get install –f | ||
- | |||
- | {{ : | ||
- | |||
- | === Programmaatori ühendamine === | ||
- | |||
- | Ühendada programmaator arvutiga ning kontrollida, | ||
- | |||
- | {{ : | ||
- | |||
- | Saamaks teada, millise pordi taha on programmaator ühendatud, kontrollida ///dev// kataloogi, kasutades käske //cd /dev// (määrab ///dev// kui aktiivse kataloogi) ja //dir// (kuvab kataloogi sisu). Kuna tegu on USB-Serial liidesega, siis on ta märgitud // | ||
- | |||
- | {{ : | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === Projekti loomine === | ||
- | |||
- | AVR programmi kirjutamiseks tuleb luua uus projekt, mis tüüpiliselt sisaldab endas mitmeid erinevaid faile: programmikoodi(e), | ||
- | |||
- | Uue projekti loomiseks järgi järgmisi samme: | ||
- | |||
- | **1.** Avada KontrollerLab (// | ||
- | |||
- | {{ : | ||
- | |||
- | **2.** Kuna projekt on esialgu tühi, siis tuleb sellele juurde lisada C-fail, kuhu koodi saaks kirjutada. Valida menüü //File -> New -> New//. Avaneb faili lisamise aken, kus valida //C source// ja määrata faili nimi. | ||
- | |||
- | {{ : | ||
- | |||
- | **3.** Seadistada KontrollerLabi projekt vastavalt Kodulabori riistvarale. Valida menüü //Project -> Configure Project//, mispeale kuvatakse projekti seadistamise aken avatuna // | ||
- | |||
- | NB! Kuna KontrollerLab programmis ei saa korrektselt teeki lisada // Linker // kaardil, siis tuleb Kodulabori teegi lisamine seadistada siin, kirjutades map faili nime taha // -lhomelab //. | ||
- | |||
- | {{ : | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | // | ||
- | |||
- | {{ : | ||
- | |||
- | **4.** Määrata programmaatori seaded, valides menüü //Project -> Configure Programmer// | ||
- | |||
- | {{ : | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | **5.** Määrata tekstiredaktori seaded nii, et tabulaatorit tõlgendataks 4 tühikuna. See on vajalik, kui juhtutakse lähtefaili avama mõne muu tekstiredaktoriga, | ||
- | |||
- | {{ : | ||
- | |||
- | **6.** Seadista avanenud alamaknad KontrollerLabis oma käe järgi ning kirjuta mingi lihtne programm keskkonna testimiseks. Järgnevas alampeatükis on näitena toodud vilkuva LED programm. | ||
- | |||
- | {{ : | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === Seadistuste testimine === | ||
- | |||
- | Kui arenduskeskkond on esimest korda paigaldatud ja seadistatud, | ||
- | |||
- | **1.** Ühendada programmaator ATmega128 Kontrollerimooduli plaadiga. Kontrollida, | ||
- | |||
- | {{ : | ||
- | |||
- | **2.** Sisestada lihtne C-kood ja kompileerida see (// | ||
- | |||
- | <code c> | ||
- | #include < | ||
- | #include < | ||
- | |||
- | int main(void) | ||
- | { | ||
- | // Viigu PB7 seadmine väljundiks | ||
- | DDRB = 0x80; | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // Viigu PB7 inverteerimine | ||
- | PORTB ^= 0x80; | ||
- | hw_delay_ms(500); | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | [{{ : | ||
- | |||
- | Veendu, et väljundaknasse tuleb teade "File compiled successfully" | ||
- | |||
- | **3.** Koodi pealelaadimiseks valida //ignite// käsk. Kui kõik õnnestub, siis väljundaknas viimase reana annab KontrollerLab teate " | ||
- | |||
- | Kui LED vilgub, nii nagu eespool kirjeldatud, | ||
- | Palju õnne! | ||
- | |||
- | === Ujukoma-arvude kasutamine === | ||
- | |||
- | Mõnikord tekib vajadus AVR programmis kasutada ujukoma-arve. Nendega arvutamiseks ja nende esitamiseks // | ||
- | |||
- | **1.** Avada projekti seaded menüüst //Project -> Configure Project// ning valida //Linker// kaart. Märgistada //Linker flags// sektsioonis esimene linnuke (vaata ka juuresolevat pilti). | ||
- | |||
- | {{ : | ||
- | |||
- | **2.** Vajutada //OK// ja sulgeda seadete aken. | ||
- | |||
- | ===== Digitaalsed sisend-väljundviigud ===== | ||
- | |||
- | {{ : | ||
- | |||
- | Järgnevad peatükid tutvustavad lihtsaimat mikrokontrolleri funktsiooni - digitaalseid sisend-väljundviike. Viigud on mikrokontrolleri metallist kontaktid, kõnekeeles jalad, mille kaudu saab edastada ja vastu võtta digitaalseid signaale. Kui viik seadistada programmis sisendiks, saab selle kaudu mikrokontrollerisse lugeda lülitite või muude lihtsamate andurite olekut. Kui viik seadistada väljundiks, | ||
- | |||
- | 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. | ||
- | ==== Valgusdiood ==== | ||
- | |||
- | //Vajalikud teadmised: [HW] [[et: | ||
- | |||
- | === Teooria === | ||
- | |||
- | [{{ : | ||
- | |||
- | Valgusdiood on pooljuht, mille päripingestamisel kiirgab see valgust. Valgusdioodi nimetatakse inglise keelse lühendiga LED (// | ||
- | |||
- | [{{ : | ||
- | |||
- | Päripingestamisel rakendatakse LED-i anoodile positiivne ja katoodile negatiivne pinge. LED-i päripinge sõltub selle värvusest – pikema lainepikkusega LED-ide (punased) puhul on see ~2V, lühema lainepikkusega (sinised) on see ~3V. Tavaliselt on LED-ide võimsus mõnikümmend millivatti, sellest tulenevalt peab ka vool samas suurusjärgus olema. Suurema pinge või voolu rakendamisel LED-ile on oht see lihtsalt läbi põletada. | ||
- | |||
- | Kui LED-e kasutatakse spetsiaalselt valgustamiseks, | ||
- | |||
- | [{{ : | ||
- | |||
- | 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. | ||
- | |||
- | === Praktika 1 === | ||
- | |||
- | Kodulabori Kontrollermooduli plaadil on üksik punane LED, mille anood on läbi takisti ühendatud +5 V toitega ja katood ATmega128 viiguga PB7. Selleks et Kontrollermooduli LED-i põlema süüdata ja kustutada, tuleb PB7 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 // | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Kodulabori Kontrollermooduli LED-i testimise programm. | ||
- | // Põhineb Kodulabori teegil. | ||
- | // | ||
- | #include < | ||
- | |||
- | // | ||
- | // LED-i viiguga seotud parameetrite määramine muutujale | ||
- | // | ||
- | pin debug_led = PIN(B, 7); | ||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | // LED-i viigu väljundiks seadmine | ||
- | pin_setup_output(debug_led); | ||
- | |||
- | // LED-i süütamine | ||
- | pin_clear(debug_led); | ||
- | } | ||
- | </ | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Kodulabori Kontrollermooduli LED-i testimise programm. | ||
- | // Põhineb otsesel registrite muutmisel. | ||
- | // | ||
- | #include < | ||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | // LED-i viigu väljundiks seadmine | ||
- | DDRB |= (1 << 7); | ||
- | |||
- | // LED-i süütamine | ||
- | PORTB &= ~(1 << 7); | ||
- | } | ||
- | </ | ||
- | |||
- | Esimene näide kasutab viikude teeki (//pin.h// fail). Esmalt luuakse programmis // | ||
- | |||
- | Mis siis on viikude teegi ja registrite kasutamise vahe? Vahe on kasutusmugavuses - teegiga on see lihtsam, sest ei pea registrite nimesid ja nende toimet teadma. Kõige olulisem teegi eelis on aga kohandatavus. Registreid kasutades tuleb viigu muutmiseks kogu programmis registrite nimed ja bitimaskid ümber muuta, teegi puhul tuleb seda teha vaid programmi alguses, kus viigu muutuja algväärtustatakse. Otsesel registrite kasutamisel on üks näiline eelis - viigu kasutamine on vahetu ja see ei toimu läbi programmimälu ja aeganõudvate funktsioonide. Tegelikult on aga uuemad AVR-GCC kompilaatori versioonid niivõrd taibukad, et teisendavad teegi funktsioonid täpselt sama vahetuks registrite manipuleerimise käskudeks, nagu oleks seda otse programmis tehtud. Täpsustuseks tuleb öelda, et kompilaatori teisendusoskus kehtib ainult konstantsete // | ||
- | |||
- | Järgnevalt on osaliselt toodud viikude teegi lähtekood, mille eesmärk on selgitada teegis toimuvat. Paraku ei pruugi see algajale päris arusaadav olla kuna kasutusel on C-keele viidad (inglise keeles // | ||
- | |||
- | <code c> | ||
- | // Makro-konstant millega määratakse ära registri viit | ||
- | #define _REG_PTR_ volatile uint8_t * | ||
- | |||
- | // | ||
- | // Viigu andmetüüp | ||
- | // | ||
- | typedef struct pin | ||
- | { | ||
- | _REG_PTR_ ddr; | ||
- | _REG_PTR_ port; | ||
- | _REG_PTR_ pin; | ||
- | uint8_t mask; | ||
- | } | ||
- | pin; | ||
- | |||
- | // | ||
- | // Viigu andmetüüpi muutuja algväärtustamise makrofunktsioon | ||
- | // | ||
- | #define PIN(port_char, | ||
- | { \ | ||
- | (_REG_PTR_)& | ||
- | (_REG_PTR_)& | ||
- | (_REG_PTR_)& | ||
- | bit_mask(bit_index) \ | ||
- | } | ||
- | |||
- | // | ||
- | // Viigu seadmine väljundiks | ||
- | // | ||
- | inline void pin_setup_output(pin pin) | ||
- | { | ||
- | bitmask_set(*pin.ddr, | ||
- | } | ||
- | |||
- | // | ||
- | // Viigu seadmine kõrgeks | ||
- | // | ||
- | inline void pin_set(pin pin) | ||
- | { | ||
- | bitmask_set(*pin.port, | ||
- | } | ||
- | |||
- | // | ||
- | // Viigu seadmine madalaks | ||
- | // | ||
- | inline void pin_clear(pin pin) | ||
- | { | ||
- | bitmask_clear(*pin.port, | ||
- | } | ||
- | </ | ||
- | |||
- | === Praktika 2 === | ||
- | |||
- | Peale Kontrollermooduli asuvad LED-id ka Digitaalsel sisend-väljundmooduli plaadil. Need on elektriliselt ühendatud samamoodi nagu Kontrollermooduli LED ehk katood on ühenduses AVR viiguga. Punane LED on ühenduses viiguga PC5, kollane viiguga PC4 ja roheline viiguga PC3. Nende Kodulabori teegi põhine näidisprogramm näeb välja järgmine: | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Kodulabori Digitaalse sisend-väljundmooduli | ||
- | // LED-ide testimise programm. | ||
- | // | ||
- | #include < | ||
- | |||
- | // | ||
- | // LED-ide viikude määramine | ||
- | // | ||
- | pin led_red | ||
- | pin led_yellow = PIN(C, 4); | ||
- | pin led_green | ||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | // LED-ide viikude väljundiks seadmine | ||
- | pin_setup_output(led_red); | ||
- | pin_setup_output(led_yellow); | ||
- | pin_setup_output(led_green); | ||
- | |||
- | // Punase ja rohelise LED-i põlema panek | ||
- | pin_clear(led_red); | ||
- | pin_clear(led_green); | ||
- | |||
- | // Kollase LED-i kustutamine | ||
- | pin_set(led_yellow); | ||
- | } | ||
- | </ | ||
- | ==== Lüliti ==== | ||
- | |||
- | //Vajalikud teadmised: [HW] [[et: | ||
- | |||
- | === Teooria === | ||
- | |||
- | Lüliti on elektromehhaaniline seade elektriahela kokku- ja lahtiühendamiseks. Lüliteid on erinevaid, kuid tüüpiline mehhaaniline lüliti koosneb klemmidest, mida saab omavahel mehhaaniliselt ühendada. | ||
- | |||
- | 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. | ||
- | |||
- | Erinevat liiki lülititel on erinev skemaatiline tähis. Järgnevalt on toodud tüüpilisemad elektroonikaskeemides kasutatavad lülitid ja nende elektrilised tähised: | ||
- | |||
- | ^ Surunupp-lüliti ^ Tumbler-lüliti ^ Klahvlüliti ^ Mikrolüliti ^ DIL-lüliti ^ | ||
- | |{{: | ||
- | | {{: | ||
- | |||
- | 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, | ||
- | |||
- | 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-up// või // | ||
- | |||
- | Olgu öeldud, et mehhaaniliste 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. | ||
- | |||
- | === Praktika === | ||
- | |||
- | Kodulabori Digitaalse sisend-väljundmooduli plaadil on kolm surunupp-lülitit. Lülitid ühendavad mikrkontrolleri viike maaga, kuid mitte otse, vaid läbi takisti – seda põhjusel, et juhuslikul mikrokontrolleri viikude väljundiks määramisel neid nupuvajutusel ei lühistataks. Lülititel on ka //pull-up// takistid, kuid need on palju suurema takistusega kui kaitsetakistid, | ||
- | |||
- | Lülitid asuvad viikudel PC0, PC1 ja PC2. Lülitite oleku lugemiseks tuleb mikrokontrolleri vastavad viigud määrata sisendiks. AVR siseseid //pull-up// takisteid ei pea tööle rakendama, sest, nagu öeldud, viikudel juba on välised takistid. Kui nupp alla vajutada, on viigule vastaval siinil biti väärtus 0, kui nupp lahti lasta, siis väärtus 1. Selleks et näha, kas mikrokontroller sai nupuvajutusest aru, võib kasutada plaadil olevaid LED indikaatoreid. | ||
- | |||
- | Nuppude kasutamise näidiskood põhineb Kodulabori viikude teegil, mida on tutvustatud valgusdioodi näites. | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Kodulabori Digitaalse sisend-väljundmooduli | ||
- | // nuppude testimise programm. | ||
- | // | ||
- | #include < | ||
- | |||
- | // | ||
- | // LED-ide ja nuppude viikude määramine | ||
- | // | ||
- | pin leds[3] | ||
- | pin buttons[3] = { PIN(C, 2), PIN(C, 1), PIN(C, 0) }; | ||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | unsigned char i; | ||
- | |||
- | // LED-ide viikude väljundiks ja nuppude | ||
- | // viikude sisendiks seadmine | ||
- | for (i = 0; i < 3; i++) | ||
- | { | ||
- | pin_setup_output(leds[i]); | ||
- | pin_setup_input(buttons[i]); | ||
- | } | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // Igale nupule vastab üks LED, | ||
- | // mis süttib nuppu alla vajutades | ||
- | for (i = 0; i < 3; i++) | ||
- | { | ||
- | pin_set_to(leds[i], | ||
- | } | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | 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. | ||
- | |||
- | /* | ||
- | Selle näite puhul võib tähelepanelikum õppur märgata, et kompileeritud programm on oma lihtsusest hoolimata natuke suurem kui arvata võiks. Põhjus on selles, et LED-ide ja nuppude viigud on defineeritud massiivina, kuid nagu valgusdioodi harjutuses öeldud, kompilaator viikude massiive ei optimeeri (lihtsusta). Kompileeritud programm oleks kompaktsem, kui kõigi LED-ide ja nuppude kasutamine käiks individuaalselt, | ||
- | */ | ||
- | ==== Lüliti põrkumise filtreerimine ==== | ||
- | |||
- | //Vajalikud teadmised: [HW] [[et: | ||
- | |||
- | === Teooria === | ||
- | |||
- | [{{ : | ||
- | |||
- | Nii nagu lüliteid tutvustavas peatükis öeldud, eksisteerib mehhaaniliste lülititega kontaktide põrkumise probleem. Kuna kontaktid on tehtud metallist, millel on teatav elastsus, siis kontaktide ühendamise või lahti-ühendamise hetkel need põrkuvad ning tulemusena tekib hulga väärlülitusi. Lülituste arv ja kestus sõltub lülitist, kuid enamasti jääb see mõne millisekundi piiresse. Kui lülitit kasutatakse mõne elektriseadme käivitamiseks, | ||
- | |||
- | [{{ : | ||
- | |||
- | Põhiline kontaktide põrkumisest tekkinud väärlülitusi välistav meetod on filtreerimine. Filtreerida saab nii elektriliselt kui ka tarkvaraliselt. Elektriliseks filtreerimiseks tuleb lüliti ühendada läbi madalpääsu filtri – näiteks RC filter - mis silub pingemuutusi ja sellest tulenevalt ei omanda mikrokontrolleri viik hetkelisi väärtusi. Tarkvaraline filtreerimine toimub põhimõttel, | ||
- | |||
- | === Praktika === | ||
- | |||
- | Kodulabori lülititel ei kasutada elektrilist filtreerimist, | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Kodulabori digitaalse sisend-väljundmooduli | ||
- | // nuppude kontaktide põrkumise demonstreerimise programm. | ||
- | // | ||
- | #include < | ||
- | |||
- | // | ||
- | // LED-ide ja nupu viikude määramine | ||
- | // | ||
- | pin leds[3] = { PIN(C, 5), PIN(C, 4), PIN(C, 3) }; | ||
- | pin button | ||
- | |||
- | |||
- | |||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | unsigned char new_value, old_value = 0; | ||
- | unsigned char index, counter = 0; | ||
- | |||
- | // LED-ide viikude väljundiks seadmine | ||
- | for (index = 0; index < 3; index++) | ||
- | { | ||
- | pin_setup_output(leds[index]); | ||
- | } | ||
- | |||
- | // Nupu viigu sisendiks määramine | ||
- | pin_setup_input(button); | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // Nupu oleku lugemine | ||
- | new_value = pin_get_value(button); | ||
- | |||
- | // Kontroll, kas nupp vajutati alla, | ||
- | // ehk kas uus olek on 1 ja vana 0 | ||
- | if ((new_value) && (!old_value)) | ||
- | { | ||
- | // Loenduri suurendamine ja mooduli 3 võtmine | ||
- | counter = (counter + 1) % 3; | ||
- | |||
- | // Loenduri väärtusele vastava LED-i süütamine | ||
- | for (index = 0; index < 3; index++) | ||
- | { | ||
- | pin_set_to(leds[index], | ||
- | } | ||
- | } | ||
- | |||
- | // Peame vana olekut meeles | ||
- | old_value = new_value; | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | Tarkvaraliseks filtreerimiseks on mitmeid meetodeid. Seda võib teha lihtsalt ja keeruliselt, | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | Töökindlam on programm, mis kontrollib nupu olekut teatud aja jooksul mitu korda (mida rohkem ja mida pikema aja jooksul, seda kindlam). Järgnevalt on toodud Digitaalse sisend-väljundmooduli nupu filtreeritud väärtuse lugemise funktsioon: | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Funktsioon mõne IO laiendusplaadi lüliti filtreeritud väärtuse lugemiseks | ||
- | // | ||
- | unsigned char pin_get_debounced_value(pin button) | ||
- | { | ||
- | unsigned char buffer = 0xAA; | ||
- | unsigned char timeout = 100; | ||
- | |||
- | // Ootame, kuni nupu olek on selgunud või oleku selgitamine aegunud | ||
- | while (timeout-- > 0) | ||
- | { | ||
- | // 8-kohalise (bitise) olekupuhvri pidamine | ||
- | // Kõik eelmised olekud (bitid) nihutatakse vasakule | ||
- | // ja paremale lisatakse uus olek (bitt). | ||
- | buffer <<= 1; | ||
- | buffer |= (pin_get_value(button) ? 0x01 : 0x00); | ||
- | |||
- | // Kui kõik 8 bitti on kõrged, siis | ||
- | // nupp on kindlasti alla vajutatud | ||
- | if (buffer = 0xFF) | ||
- | { | ||
- | return 1; | ||
- | } | ||
- | |||
- | // Kui kõik 8 bitti on madalad, siis | ||
- | // nupp on kindlasti üleval | ||
- | if (buffer = 0x00) | ||
- | { | ||
- | return 0; | ||
- | } | ||
- | |||
- | // Paus 1 millisekund | ||
- | // See funktsioon sisaldub Kodulabori teegis | ||
- | sw_delay_ms(1); | ||
- | } | ||
- | |||
- | // Kui olekut ei õnnestunud välja selgitada, siis oletame, | ||
- | // et nuppu ei vajutatud | ||
- | return 0; | ||
- | } | ||
- | </ | ||
- | |||
- | See funktsioon kasutab viite tekitamise funktsiooni, | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Kodulabori digitaalse sisend-väljundmooduli | ||
- | // nuppude kontaktide põrkumise filtreerimise programm. | ||
- | // | ||
- | #include < | ||
- | #include < | ||
- | |||
- | // | ||
- | // LED-ide ja nupu viikude määramine | ||
- | // | ||
- | pin leds[3] = { PIN(C, 5), PIN(C, 4), PIN(C, 3) }; | ||
- | pin button | ||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | unsigned char new_value, old_value = 0; | ||
- | unsigned char index, counter = 0; | ||
- | |||
- | // LED-ide viikude väljundiks seadmine | ||
- | for (index = 0; index < 3; index++) | ||
- | { | ||
- | pin_setup_output(leds[index]); | ||
- | } | ||
- | |||
- | // Nupu viigu sisendiks määramine | ||
- | pin_setup_input(button); | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // Nupu oleku lugemine | ||
- | new_value = pin_get_debounced_value(button); | ||
- | |||
- | // Kontroll, kas nupp vajutati alla, | ||
- | // ehk kas uus olek on 1 ja vana 0 | ||
- | if ((!new_value) && (old_value)) | ||
- | { | ||
- | // Loenduri suurendamine ja mooduli 3 võtmine | ||
- | counter = (counter + 1) % 3; | ||
- | |||
- | // Loenduri väärtusele vastava LED süütamine | ||
- | for (index = 0; index < 3; index++) | ||
- | { | ||
- | pin_set_to(leds[index], | ||
- | } | ||
- | } | ||
- | |||
- | // Peame vana olekut meeles | ||
- | old_value = new_value; | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | Kui nüüd programmi proovida, siis LED-id süttivad täpselt sellises järjekorras nagu kasutaja nupplülitit vajutab. | ||
- | ==== Harjutusülesanded ==== | ||
- | |||
- | Eesmärgiks on koostada programm, mis täidab kirjeldatud ülesannet. | ||
- | |||
- | === Soojendusülesanne === | ||
- | |||
- | * Süütab nupu S1 vajutamisel ühe LED-i, S2 vajutamisel kaks LED-i, S3 vajutamisel kolm LED-i. | ||
- | |||
- | === Algajale === | ||
- | |||
- | - Imiteerib ülekäiguraja autode valgusfoori tööd. Kuni pole vajutatud ühelegi nupule, põleb autodele roheline LED. Pärast suvalisele nupule vajutamist hakkab roheline kolmeks sekundiks vilkuma, seejärel süttib kolmeks sekundiks kollane ning kümneks sekundiks punane ja lõpuks jääb uuesti pidevalt põlema roheline LED. | ||
- | - Loendab nupuvajutusi. Vajutus loetakse lõppenuks alles siis, kui nupp vabastatakse. Tulemus kuvatakse kahendkoodis LED-idel. Maksimaalne tulemus kolmel LED-il on 2< | ||
- | - Vajutades nupule S1, süttib korraga LED1 ja LED3, vajutades nupule S2, süttib LED2, vajutades nupule S3, kustuvad kõik LED-id. Operatsioonid tuleb teostada otse vastavate registrite väärtusi muutes (ilma Kodulabori teegita). | ||
- | - Loendab nupuvajutusi. Tulemus kuvatakse LED-i vilkumistega. Pärast igat nupule vajutamist suureneb vilgutamiste arv ühe võrra. Valida võib suvalise nupu. LED-i vilgutamiseks kasutada alamfunktsiooni, | ||
- | - Vajutades nupule S1, vilgutab punane LED morsekoodis " | ||
- | |||
- | === Edasijõudnule === | ||
- | |||
- | - Igale nupule kolmest vastab üks LED, mis süttib nuppu all hoides. Süütamiseks või kustutamiseks tuleb kasutada registreid ja teha võib seda ainult ühe omistamistehtega (vihje: kasutada bitinihutust). | ||
- | - Vajutades nuppe järjekorras S3 – S2 - S1, süttib roheline LED. Kõigi teiste kombinatsioonide korral süttib punane LED. Iga nupuvajutuse korral vilgatab kollane LED, mis kinnitab nupule vajutust. | ||
- | - Igale LED-ile vastab üks nupp. Kontroller vilgutab LED-e suvaliselt ja kasutaja peab nuppe vajutades sama jada kordama. Vilkumiste jada läheb iga korraga järjest pikemaks, lisades eelnevale jadale uue suvalise LED-i. Pärast iga kasutaja sisestuskorda kontrollitakse, | ||
- | - Programm mõõdab reaktsiooniaega. Suvalise LED-i süttides peab kasutaja võimalikult kiiresti vajutama nuppu LED-i all. Aeg, mil LED süttib, on juhuslik, kuid vähemalt 100 ms. Reaktsiooniaega näidatakse kasutajale millisekundites LCD ekraanil. Nuppude väärtust ei tohi lugeda kontaktide põrkumist filtreeriva funktsiooniga, | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === Kordamisküsimused === | ||
- | |||
- | - Mis on tehete " | ||
- | - Mis on tehete " | ||
- | - Kirjutage avaldis, milles kasutate võrrandit "x = x + 1" kaksteist korda. | ||
- | - Kuidas kirjutate C-keeles lõputu tsükli? Esitage kaks erinevat varianti. | ||
- | - Millist tüüpi muutuja valite C-keeles, et esitada positiivseid arve vahemikus 7 kuni 154? | ||
- | - Milline register määrab ära pordi suuna? Tooge pordi näide sisendi ja väljundi seadistamise kohta. | ||
- | - Milliste meetoditega saab elimineerida lüliti kontaktide põrkumisest tekkivaid väärlülitusi? | ||
- | - Mida tähendab termin bitinihutus? | ||
- | - Miks kasutatakse lülitite juures //pull-up// takistit? Mille järgi määratakse selle takistus? | ||
- | - Arvutage LED voolu piirava takisti väärtus, kui toitepinge on 5 V, LED päripinge 2,7 V ja vool 30 mA. | ||
- | ===== Taimerid ja viited ===== | ||
- | |||
- | {{ : | ||
- | |||
- | Käesolev peatükk tutvustab mikrokontrollerite ajastuse võimalusi - taimereid ja viiteid. Need on abiks rakendustes, | ||
- | |||
- | Mõlemal meetodil on omad head ja vead, millest lähemalt räägivad nende kohta käivad harjutused. Korrektsuse huvides võib öelda, et algselt olid taimerid ikkagi eraldiseisvad integraallülitused elektriskeemis, | ||
- | |||
- | Taimerid on ka lihtsast aja loendamise seadmest arenenud keerukateks signaalide vastuvõtmise või genereerimise süsteemideks. Nad moduleerivad ja demoduleerivad signaale ning nad on võimelised taktsignaali kordistama või jagama. On olemas ka spetsiaalsed aeg-digitaalmuundurid (TDC, inglise keeles // | ||
- | ==== Tarkvaraline viide ==== | ||
- | |||
- | //Vajalikud teadmised: [HW] [[et: | ||
- | |||
- | === Teooria === | ||
- | |||
- | Tihti on mikrokontrollerite programmis vaja tekitada viiteid, et tegevusi ajastada või nende lõppu oodata. Üks idee poolest lihtsamaid meetodeid mikrokontrolleri töös paus tekitada on selle protsessor mingi muu tegevusega üle koormata - näiteks panna see lugema suuri arve. Protsessori taktsagedusest saab välja arvutada, mitmeni see arve loendama peaks, et kindlat ajalist viidet tekitada. Mingi arvu loendamine nullist protsessori taktsageduse väärtuseni hertsides tekitaks teoreetiliselt viite üks sekund. Praktikas see erinevatel põhjustel päris nii lihtne ei ole. | ||
- | |||
- | Kui mikrokontrolleri protsessor arvutab arvudega, mille kahendkuju on sama lai kui selle sisemine siin (AVR puhul 8-bitti), siis protsessoritel võtab üks aritmeetiline tehe, näiteks arvu liitmine ühega, aega 1 protsessori töötakt. Selleks, et arvutada tuhandete või miljonitega, | ||
- | |||
- | Kuna kõrgtaseme keeles (näiteks C-keeles) programmeerides ei kirjutata programmi otse käsustiku baasil, peab tarkvaralise viite tekitamiseks tundma ka kompilaatorit, | ||
- | |||
- | === Praktika ==== | ||
- | |||
- | Järgnevalt on toodud näide tarkvaralise viite tekitamisest AVR mikrokontrolleriga. Kirjutatud on C-keele programmilõik, | ||
- | |||
- | <code c> | ||
- | unsigned char x; | ||
- | |||
- | // Tsükkel seni kuni x on 100 | ||
- | for (x = 0; x < 100; x++) | ||
- | { | ||
- | // Tühiinstruktsiooniga nop | ||
- | asm volatile (" | ||
- | } | ||
- | </ | ||
- | |||
- | Siinkohal on aga toodud sama C-keele programmilõik pärast kompileerimist. Vasakpoolsed 2 heksadetsimaalarvu on masinkood ja paremal on assemblerkeeles käsk koos operandi(de)ga. Masinkood ja assemblerkeel on üks-üheselt seotud, assembler on lihtsalt masinkoodi inimesele loetaval kujul esitamiseks. Kompileerimisel on kasutatud programmi pikkuse optimeerimist (kompilaatori parameeter -Os). | ||
- | |||
- | <code asm> | ||
- | 80 e0 | ||
- | 00 00 | ||
- | 8f 5f subi r24, 0xFF ; r24 registrist 255 lahutamine, ehk +1 liitmine | ||
- | 84 36 | ||
- | e1 f7 brne .-8 ; Kui võrdlus oli väär, siis siire 8 baiti tagasi | ||
- | </ | ||
- | |||
- | Kompileeritud kujul on näha, mis tegelikult C-keele tsüklist saab, ja selle järgi saab arvutada, mitu takti ühe tsükli perioodi täitmiseks kulub. Infot instruktsioonide toime ja tööaja kohta leiab AVR käsustiku andmelehest. Antud näites kulub ühe tsükli perioodis 4 instruktsiooni täitmiseks 4 takti, sest kõik instruktsioonid võtavad ühe töötakti. Lisaks kulub enne tsüklit 1 takt laadimisinstruktsiooni jaoks ja tsüklist väljudes 1 lisatakt. Oletades, et kontrolleri töötakt on 14,7456 MHz, võib välja arvutada kogu programmilõigu tekitatud ajalise viite: | ||
- | |||
- | (1 + 100 ⋅ 4 + 1) / 14745600 = 27,26 μs | ||
- | |||
- | Näites tekitatud viide on mikrosekundites ja kasutatav muutuja on 8-bitine, seega on ka masinkood üsna lihtne. Selleks, et tekitada pausi millisekundites, | ||
- | |||
- | Käesoleva harjutuse eesmärk ei ole siiski masinkoodi tasandil täpset tarkvaralist viidet tekitada, sest see on üsna peen töö ja pealegi on viite tekitamiseks avr-libc ja Kodulabori teegis juba funktsioonid olemas. Need kasutatakse ka järgmistes näidetes. | ||
- | |||
- | Tarkvaralise viite puhul on aga oluline teada, et hoolimata oma põhimõttelisest lihtsusest on see äärmiselt ebaefektiivne meetod energiatarbe seisukohast. Kõigil neil taktidel, mil mikrokontroller tegeleb kasutu loendamisega, | ||
- | |||
- | === Praktika ==== | ||
- | |||
- | Järgnev programmikood käib tarkvaralise viite funktsiooni // | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Tarkvaraline viide millisekundites | ||
- | // | ||
- | void sw_delay_ms(unsigned short count) | ||
- | { | ||
- | // Viite muutuja nullini loendamine | ||
- | while (count-- > 0) | ||
- | { | ||
- | // 1ms viide spetsiaalse funktsiooniga | ||
- | _delay_ms(1); | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | Toodud funktsiooni kasutamiseks on järgnev programm, mis tekitab lõputus tsüklis kaks viidet: 100 ms ja 900 ms. Lühema viite jooksul LED põleb ja pikema ajal on kustunud - tulemusena LED perioodiliselt vilgatab. | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Kodulabori tarkvaralise viite demonstratsioonprogramm. | ||
- | // Programm vilgutab ~1 sekundi järel hetkeks LED-i. | ||
- | // | ||
- | #include < | ||
- | #include < | ||
- | |||
- | // | ||
- | // Test LED-i viigu määramine | ||
- | // | ||
- | pin debug_led = PIN(B, 7); | ||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | // LED-i viigu väljundiks seadmine | ||
- | pin_setup_output(debug_led); | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // LED-i süütamine | ||
- | pin_clear(debug_led); | ||
- | |||
- | // Tarkvaraline paus 100 millisekundit | ||
- | sw_delay_ms(100); | ||
- | |||
- | // LED kustutamine | ||
- | pin_set(debug_led); | ||
- | |||
- | // Tarkvaraline paus 900 millisekundit | ||
- | sw_delay_ms(900); | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | Kuigi näib, et LED vilgatab tõesti 1 sekundi järel, on aeg tegelikult siiski natuke pikem, sest LED-i ja viite funktsioonide väljakutsumised võtavad ka mõned mikrokontrolleri taktid aega. | ||
- | ==== Riistvaraline viide ==== | ||
- | |||
- | //Vajalikud teadmised: [HW] [[et: | ||
- | |||
- | === Teooria === | ||
- | |||
- | Tarkvaraline viide pole ainus meetod pausi tekitamiseks. Sama asja saab teha ka taimeriga. Taimer on riistvaraline kindla sagedusega suurenev või vähenev loendur. Loenduri taktsignaali saab enamasti tekitada mikrokontrolleri töötaktist või mingist välisest taktist. Taktsignaali sagedust saab üldjuhul ka mingi teguriga jagada väiksem taktsageduse saavutamiseks - seda tehakse taktijaguriga, | ||
- | |||
- | [{{ : | ||
- | |||
- | AVR loendurit saab panna teavitama loenduri ületäitumisest (inglise keeles // | ||
- | |||
- | Selleks, et taimeriga viide tekitada, piisabki vaid loenduri seadistamisest ja olekubiti kõrgeks minemise ootamisest. Erinevalt tarkvaralisest viitest ei sõltu taimerite töö kompilaatorist, | ||
- | |||
- | === Praktika === | ||
- | |||
- | Allpool olev programmikood on taimeril põhinev viitefunktsioon, | ||
- | |||
- | Tsüklis toimub loenduri algväärtustamine ja ületäitumise lipukese nullimine (sellesse 1 kirjutades). Seejärel oodatakse, kuni loendur loendab algväärtusest 256-ni, ehk ületäitumiseni. Ületäitumise hetkel läheb ületäitumise lipuke kõrgeks ja 1 ms viide ongi toimunud. Funktsiooni lõpus taimer peatatakse. | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Riistvaraline viide millisekundites | ||
- | // | ||
- | void hw_delay_ms(unsigned short count) | ||
- | { | ||
- | // Taimeri algväärtuse arvutamine | ||
- | register unsigned char timer_start = 256 - F_CPU / 1000 / 64; | ||
- | |||
- | // Taimeri käivitamine | ||
- | timer0_init_normal(TIMER0_PRESCALE_64); | ||
- | |||
- | // Viite muutuja nullini loendamine | ||
- | while (count-- > 0) | ||
- | { | ||
- | // Taimeri algväärtustamine | ||
- | timer0_set_value(timer_start); | ||
- | |||
- | // Ületäitumise lipukese nullimine | ||
- | timer0_overflow_flag_clear(); | ||
- | |||
- | // Ületäitumise ootamine | ||
- | while (!timer0_overflow_flag_is_set()) | ||
- | { | ||
- | asm volatile (" | ||
- | } | ||
- | } | ||
- | |||
- | // Ületäitumise lipukese nullimine | ||
- | timer0_overflow_flag_clear(); | ||
- | |||
- | // Taimeri peatamine | ||
- | timer0_stop(); | ||
- | } | ||
- | </ | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | Esitatud viite funktsioon kasutab aga taimerite teeki, mille lähtekood näeb välja järgmine: | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Taimer 0 taktijaguri valiku tüüp | ||
- | // | ||
- | typedef enum | ||
- | { | ||
- | TIMER0_NO_PRESCALE | ||
- | TIMER0_PRESCALE_8 | ||
- | TIMER0_PRESCALE_32 | ||
- | TIMER0_PRESCALE_64 | ||
- | TIMER0_PRESCALE_128 | ||
- | TIMER0_PRESCALE_256 | ||
- | TIMER0_PRESCALE_1024 | ||
- | } | ||
- | timer0_prescale; | ||
- | |||
- | // | ||
- | // Taimer 0 normaalrežiimi seadistamine | ||
- | // | ||
- | inline void timer0_init_normal(timer0_prescale prescale) | ||
- | { | ||
- | TCCR0 = prescale & 0x07; | ||
- | } | ||
- | |||
- | // | ||
- | // Taimer 0 peatamine | ||
- | // | ||
- | inline void timer0_stop() | ||
- | { | ||
- | TCCR0 = 0x00; | ||
- | } | ||
- | |||
- | // | ||
- | // Taimer 0 loenduri väärtuse määramine | ||
- | // | ||
- | inline void timer0_set_value(unsigned char value) | ||
- | { | ||
- | TCNT0 = value; | ||
- | } | ||
- | |||
- | // | ||
- | // Taimer 0 ületäitumise lipukese nullimine | ||
- | // | ||
- | inline void timer0_overflow_flag_clear(void) | ||
- | { | ||
- | bit_set(TIFR, | ||
- | } | ||
- | |||
- | // | ||
- | // Taimer 0 ületäitumise lipukese oleku lugemine | ||
- | // | ||
- | inline bool timer0_overflow_flag_is_set(void) | ||
- | { | ||
- | return (bit_is_set(TIFR, | ||
- | } | ||
- | </ | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | Järgnevalt on toodud samasugune programm nagu tarkvaralise viite näiteski. Lühemal 100 ms poolperioodil LED süüdatakse, | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Kodulabori riistvaralise viite demonstratsioonprogramm. | ||
- | // Programm vilgutab ~1 sekundi järel hetkeks LED-i. | ||
- | // | ||
- | #include < | ||
- | #include < | ||
- | |||
- | // | ||
- | // Test LED viigu määramine | ||
- | // | ||
- | pin debug_led = PIN(B, 7); | ||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | // LED-i viigu väljundiks seadmine | ||
- | pin_setup_output(debug_led); | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // LED-i põlema panek | ||
- | pin_clear(debug_led); | ||
- | |||
- | // Riistvaraline paus 100 millisekundit | ||
- | hw_delay_ms(100); | ||
- | |||
- | // LED-i kustutamine | ||
- | pin_set(debug_led); | ||
- | |||
- | // Riistvaraline paus 900 millisekundit | ||
- | hw_delay_ms(900); | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | ==== Perioodiline katkestus ==== | ||
- | |||
- | //Vajalikud teadmised: [HW] [[et: | ||
- | |||
- | === Teooria === | ||
- | |||
- | Käesoleva praktilise harjutuse eesmärk on demonstreerida katkestuste kasutamist loendurite näitel. Katkestused on mikrokontrolleris esinevatele sündmustele reageerivad programmilõigud. Katkestusi kasutatakse tavaliselt kiireks sündmusele reageerimiseks, | ||
- | |||
- | === Praktika === | ||
- | |||
- | Järgnev programm näitab, kuidas seadistada loendurit tekitama katkestust. Programmis on kasutusel kaks Digitaalse sisend-väljundmooduli LED-i, millest punase olekut muudetakse perioodiliselt tarkvaralise viitega ja roheline, mille olekut muudetakse katkestuse tekkimisel. Tarkvaralise viitega LED-i vilgutamise kohta on olemas eraldi harjutus ja seda siinkohal selgitatud pole. Põhieesmärk on selgitada loendurite teegi ja katkestuste kasutamist. | ||
- | |||
- | Programmi alguses toimub 16-bitise loendur/ | ||
- | |||
- | f = 14745600 Hz / 1024 / 14400 = 1 | ||
- | |||
- | Pärast loendur 1 maksimaalse väärtuse saavutamise katkestuse lubamist tuleb katkestuse tekkimine lubada ka globaalselt ehk üle kogu mikrokontrolleri. Globaalseks katkestuste lubamiseks on funktsioon //sei// ja keelamiseks //cli//. Nende funktsioonide ja katkestuste programmilõigu defineerimiseks peab programmi kaasama ka // | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Kodulabori loenduri katkestusega vilkuva LED-i näide. | ||
- | // Võrdluseks katkestusega vilkuvale LED-ile | ||
- | // töötab paralleelselt ka tarkvaralise viitega vilkuv LED. | ||
- | // | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | |||
- | |||
- | // | ||
- | // LED-ide viikude määramine | ||
- | // | ||
- | pin led_red | ||
- | pin led_green = PIN(C, 3); | ||
- | |||
- | // | ||
- | // Katkestus | ||
- | // | ||
- | ISR(TIMER1_CAPT_vect) | ||
- | { | ||
- | // Rohelise LED oleku muutmine | ||
- | pin_toggle(led_green); | ||
- | } | ||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | // LED-ide viikude väljundiks seadmine | ||
- | pin_setup_output(led_red); | ||
- | pin_setup_output(led_green); | ||
- | |||
- | // Taimeri seadistamine CTC režiimi | ||
- | timer1_init_ctc( | ||
- | TIMER1_PRESCALE_1024, | ||
- | TIMER1_CTC_TOP_ICR); | ||
- | |||
- | // Taimeri maksimaalne väärtus 14400, mis | ||
- | // teeb perioodi pikkuseks 1s | ||
- | // Valem: 14,7456Mhz / 1024 = 14400 | ||
- | timer1_set_input_capture_value(14400); | ||
- | |||
- | // Väärtuse saavutamise katkestuse lubamine | ||
- | timer1_input_capture_interrupt_enable(true); | ||
- | |||
- | // Globaalne katkestuste lubamine | ||
- | sei(); | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // Tarkvaraline paus 1000 millisekundit | ||
- | sw_delay_ms(1000); | ||
- | |||
- | // Punase LED oleku muutmine | ||
- | pin_toggle(led_red); | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | Programmi käivitades on näha, et hoolimata sellest, mida mikrokontroller põhiprogrammis teeb, toimuvad katkestused ja roheline LED vilgub. | ||
- | |||
- | Kui programmil lasta töötada mõni minut, tuleb välja oluline aspekt, mida tarkvaralise viite harjutuses nii lihtsalt näha polnud. Kuigi punase LEDi vilgutamise viide on 1000 ms, siis tegelik aeg, mis kulub iga tsükli täitmiseks, | ||
- | ==== Harjutusülesanded ==== | ||
- | |||
- | === Ülesanded === | ||
- | |||
- | Eesmärgiks on koostada programm, mis täidab kirjeldatud ülesannet. | ||
- | |||
- | === Soojendusülesanne === | ||
- | |||
- | * Panna punane LED vilkuma 10-sekundilise perioodiga (poolperiood 5 s). Teostamiseks luua tarkvaralise viite funktsioon, mille parameetriks on sekundite arv. | ||
- | |||
- | === Algajale === | ||
- | |||
- | - LCD ekraanil kuvada aega 100 ms täpsusega, mis kulub suvalise kahe nupu allavajutamiste vahel. Aja mõõtmise teostuse võib vabalt valida. | ||
- | - Vajutades nuppu S1, aeglustub kõigi kolme LED-i vilkumine 2 korda, vajutades nuppu S3, sageneb vilkumine 2 korda, ja vajutades nuppu S2, määratakse vilkumise sageduseks 1 Hz. Kasutada viitefunktsioone või katkestusi. (Katkestused on keerukamad, kuid viitefunktsioonidega tekib nuppude filtreerimisfunktsiooni tõttu lisaviide.) | ||
- | - 7-segmendilisel LED indikaatoril kuvada nupu S1 vajutamise sagedus hertsides. Sageduse näit tuleb piirata madalamalt nulli ja kõrgemalt üheksaga. | ||
- | - Nupule S1 vajutades loendab programm sekundeid 60-st nullini ja süütab seejärel punase LED-i. Nupule S2 vajutades on ajaks 30 sekundit, misjärel süüdatakse kollane LED. Nupp S3 aeg on 10 sekundit ja süüdatav LED on roheline. Kõik protsessid peavad toimima paralleelselt. LED-id kustuvad, kui vajutada vastavaid nuppe. | ||
- | - Näidata LCD ekraanil kellaaega kujul " | ||
- | |||
- | === Edasijõudnule === | ||
- | |||
- | - Teha stopper, mis LCD ekraanil kuvab tunde, minuteid, sekundeid ja millisekundeid. Nupp S1 alustab mõõtmist, S2 peatab mõõtmise ja S3 nullib aja. Kasutada tuleb taimeri katkestust. | ||
- | - 2-sekundilise vahega süttib ja kustub sujuvalt järjest punane, kollane ja roheline LED. Sujuv valgustus saadakse LED-i mitmesajahertsise sagedusega moduleerides (seda ülikiiresti süüdates ja kustutades) ja põlemise/ | ||
- | - Kirjutada C-keeles programmilõik, | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === Kordamisküsimused === | ||
- | |||
- | - Millised meetodid on viite tekitamiseks? | ||
- | - Kuidas tekitada tarkvaraline viide? Millistest parameetritest tarkvaralise viite kestus sõltub? | ||
- | - Mis sunnib kasutama riistvaralist taimerit koos katkestusega? | ||
- | - Arvutage 8-bitise taimeri ületäitumise katkestuse periood, kui taktsagedus on 16 MHz ja sagedusjaguri tegur 1024. | ||
- | - Mis asi on arvutites peituv " | ||
- | - Mis juhtub 19. jaanuaril 2038 arvutite maailmas? | ||
- | - Mida saab AVR taimeritega veel teha peale aja loendamise? | ||
- | - Milliste registritega saab seadistada ATmega128 taimer 0. Mida on nende registritega võimalik seadistada? | ||
- | - Milline on suurim katkestuste ajaline täpsus millisekundites, | ||
- | - Kui protsessor on tugevalt koormatud programmi täitmisega (näiteks juhib mitut mootorit ja kontrollib pidevalt paljude andurite väärtusi), | ||
- | ===== Näidikud ja ekraanid ===== | ||
- | |||
- | {{ : | ||
- | |||
- | Üks lihtsamaid meetodeid veendumaks mikrokontrolleri töö korrektsuses on lisada programmi koodilõik, mis vilgutab LED-i või mitut kindla tegevuse korral. Tihtipeale jääb sellest aga väheks, sest vaja oleks edastada rohkem infot kui LED-iga võimalik, ning mõni rakendus eeldab kasutajaliidest, | ||
- | |||
- | Järgnevad peatükid tutvustavad lihtsamat liiki näidikuid ja ekraane - LED segmentidega indikaatorit ja kahte liiki monokromaatilist LCD ekraani. Peale nende kasutatakse mikrokontrolleritega aktiivselt ka LED maatrikseid ja tänapäeval levinud värvilisi orgaanilisi LED (OLED) ekraane. Kunagi olid levinud ka hõõgniidiga numberindikaatorid, | ||
- | ==== 7-segmendiline numberindikaator ==== | ||
- | |||
- | //Vajalikud teadmised: [HW] [[et: | ||
- | |||
- | === Teooria === | ||
- | |||
- | 7-segmendiline LED numberindikaator on seitsmest number 8-kujuliselt paigutatud valgusdioodist koosnev näidik. Vastavaid LED-e (segmente) süüdates või kustutades saab nendega kuvada numbreid nullist üheksani ning mõningaid tähti. | ||
- | |||
- | [{{ : | ||
- | |||
- | Elektriliselt on kõigi LED-ide anoodid ühendatud ühise anoodi viiguga //ca//. LED-e süüdatakse nende katoode (//a, b, c...//) lülitades. Olemas on ka vastupidi ühendusi, kus indikaatoritel on ühine katood //cc//. Tavaliselt kasutatakse mitut numberindikaatorit, | ||
- | |||
- | LED numberindikaatoreid on lihtne kasutada, sest neid võib juhtida kas või otse mikrokontrolleri viikudelt, kuid on ka spetsiaalseid ajureid, mis võimaldavad numberindikaatorit juhtida vähemate mikrokontrollerite viikude arvuga. LED numberindikaatoreid on erinevat värvi, nad võivad olla väga eredad ja väga suured. Kogu ladina tähestiku kuvamiseks on olemas ka lisasegmentidega indikaatoreid. | ||
- | |||
- | === Praktika === | ||
- | |||
- | Digitaalse mooduli plaadil on üks 7-segmendiline LED numberindikaator. Seda juhitakse läbi järjestikliidesega ajuri A6275. Ajuri järjestikliides on sarnane SPI-ga, kus kasutatakse ka taktsignaali ja andmesignaali. Erinevalt SPI-st pole kasutusel kiibi valikut (inglise keeles // | ||
- | |||
- | [{{ : | ||
- | |||
- | * Lukustussignaal (//latch//) - PG2 | ||
- | * Taktsignaal (//clock//) - PC7 | ||
- | * Andmesignaal (//data//) - PC6 | ||
- | |||
- | ~~CL~~ | ||
- | |||
- | Andmed edastatakse bitthaaval andmeviigu kaudu. Iga kord, kui taktsignaal kõrgeks läheb, nihutatakse nihkeregistri sisu paremale ja kõige vasakpoolsemasse pesasse loetakse andmeviigult tulev bitt. Niiviisi laaditakse nihkeregistrisse 8 bitti. Kui lukustussignaal kõrgeks seada, laetakse nihkeregistri väärtus lukustusregistrisse, | ||
- | |||
- | Numbrite kuvamiseks Kodulabori Digitaalse mooduli indikaatoril on Kodulabori teeki kirjutatud järgnev funktsionaalsus: | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Viikude seadistus | ||
- | // | ||
- | static pin segment_display_latch = PIN(G, 2); | ||
- | static pin segment_display_data_out = PIN(C, 6); | ||
- | static pin segment_display_clock = PIN(C, 7); | ||
- | |||
- | // | ||
- | // Märgikaart. | ||
- | // Bitid tähistavad segmente. Madalaim järk A, kõrgeim DP. | ||
- | // | ||
- | static const unsigned char segment_char_map[11] = | ||
- | { | ||
- | 0b00111111, | ||
- | 0b00000110, | ||
- | 0b01011011, | ||
- | 0b01001111, | ||
- | 0b01100110, | ||
- | 0b01101101, | ||
- | 0b01111100, | ||
- | 0b00000111, | ||
- | 0b01111111, | ||
- | 0b01100111, | ||
- | 0b01111001 | ||
- | }; | ||
- | |||
- | // | ||
- | // 7-segmendilise indikaatori käivitamine | ||
- | // | ||
- | void segment_display_init(void) | ||
- | { | ||
- | // Set latch, data out and clock pins as output | ||
- | pin_setup_output(segment_display_latch); | ||
- | pin_setup_output(segment_display_data_out); | ||
- | pin_setup_output(segment_display_clock); | ||
- | } | ||
- | </ | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | <code c> | ||
- | // | ||
- | // 7-segmendilisel indikaatoril numbri kuvamine | ||
- | // | ||
- | void segment_display_write(unsigned char digit) | ||
- | { | ||
- | unsigned char map; | ||
- | signed char i; | ||
- | |||
- | // Numbri kontroll | ||
- | if (digit > 9) | ||
- | { | ||
- | digit = 10; | ||
- | } | ||
- | |||
- | // Number segmentide kaardiks. | ||
- | map = segment_char_map[digit]; | ||
- | |||
- | // Lukustussignaal maha | ||
- | pin_clear(segment_display_latch); | ||
- | |||
- | // Bittide saatmine. Kõrgeim järk esimesena. | ||
- | for (i = 7; i >= 0; i--) | ||
- | { | ||
- | // Viigu seadmine vastavalt kaardi biti väärtusele | ||
- | pin_set_to(segment_display_data_out, | ||
- | |||
- | // Taktsignaal kõrgeks hetkeks | ||
- | pin_set(segment_display_clock); | ||
- | _delay_us(1); | ||
- | |||
- | // Taktsignaal madalaks | ||
- | pin_clear(segment_display_clock); | ||
- | _delay_us(1); | ||
- | } | ||
- | |||
- | // Lukustussignaal peale | ||
- | pin_set(segment_display_latch); | ||
- | } | ||
- | </ | ||
- | |||
- | Numbrite ja " | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | Järgnevalt on toodud konkreetsem numberindikaatori kasutamise näiteprogramm. Programmis kasutatakse teegi eelnevalt kirjeldatud funktsioone. Programm loeb ligikaudu sekundilise intervalliga numbreid nullist üheksani. Selline loendamine on saavutatud suuremast arvust mooduli võtmisega. | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Kodulabori sisend-väljundmooduli 7-segmendilise | ||
- | // LED indikaatori näidisprogramm | ||
- | // | ||
- | #include < | ||
- | #include < | ||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | int counter = 0; | ||
- | |||
- | // 7-segmendilise indikaatori seadistamine | ||
- | segment_display_init(); | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // Loenduri üheliste väärtuse näitamine | ||
- | segment_display_write(counter % 10); | ||
- | |||
- | // Loendamine väga pikalt | ||
- | counter++; | ||
- | |||
- | // Paus 1 sekund | ||
- | sw_delay_ms(1000); | ||
- | } | ||
- | } | ||
- | </ | ||
- | ==== Alfabeetiline LCD==== | ||
- | |||
- | //Vajalikud teadmised: [HW] [[et: | ||
- | |||
- | === Teooria === | ||
- | |||
- | Alfabeetiline LCD on vedelkristall-ekraan (inglise keeles //liquid crystal display//), mis on ette nähtud tähtede ja numbrite kuvamiseks. Inglise keeles nimetatakse seda kui // | ||
- | |||
- | Põhiline iseloomustaja on alfabeetilise LCD juures tema segmentide paigutus. Ekraan on jagatud paljudeks indikaatoriteks. Igal indikaatoril on kas piisavalt palju segmente tähtede ja numbrite kuvamiseks või moodustub see väikeste ruudukujuliste segmentide (pikslite) maatriksist. Näiteks 5x7 pikslisest maatriksist piisab kõigi numbrite, ladina tähestiku ja täppidega tähtede kuvamiseks. Indikaatoreid on tavaliselt 1-4 rida ja 8-32 tulpa. Igal indikaatoril on väike vahe sees, täpselt nagu tekstis tähtedelgi. | ||
- | |||
- | [{{ : | ||
- | |||
- | Alfabeetiline LCD ekraan koosneb peale ekraani enda veel ka kontrollerist, | ||
- | |||
- | Alfabeetilised LCD ekraanid on üldjuhul passiivmaatriksiga, | ||
- | |||
- | === Praktika === | ||
- | |||
- | Kodulabori digitaalse mooduli külge ühendub 2x16 märgiline alfabeetiline LCD WC1602A. Ekraani juhtimiseks on 4-bitine andmesiin ja 3 juhtviiku, kuid selle suhtlusprotokoll on liiga mahukas, et seda siinkohal lahti seletada. Lihtsuse huvides on ekraani kasutamiseks Kodulabori teegis olemas vastavad funktsioonid, | ||
- | |||
- | Esimene asi, mis ekraani kasutamiseks teha tuleb, on see algseadistada. Vastavaks otstarbeks on funktsioon // | ||
- | |||
- | Järgnev programmikood demonstreerib alfabeetilise LCD kasutamist kellana. Kellaaeg algab alates " | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Kodulabori alfabeetilise LCD kasutamise näide. | ||
- | // LCD-le kuvatakse kellaaeg programmi algusest alates. | ||
- | // | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | int seconds = 0; | ||
- | char text[16]; | ||
- | |||
- | // LCD ekraani seadistamine | ||
- | lcd_alpha_init(LCD_ALPHA_DISP_ON); | ||
- | |||
- | // LCD ekraani puhastamine | ||
- | lcd_alpha_clear(); | ||
- | |||
- | // Programmi nimi | ||
- | lcd_alpha_write_string(" | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // Sekundite teisendamine kellaaja kujule | ||
- | // hh:mm:ss | ||
- | sprintf(text, | ||
- | (seconds / 3600) % 24, | ||
- | (seconds / 60) % 60, | ||
- | seconds % 60); | ||
- | |||
- | // Kellaaja teksti kuvamine LCD teise rea alguses | ||
- | lcd_alpha_goto_xy(0, | ||
- | lcd_alpha_write_string(text); | ||
- | |||
- | // Sekundi suurendamine 1 võrra | ||
- | seconds++; | ||
- | |||
- | // Riistvaraline paus 1000 millisekundit | ||
- | hw_delay_ms(1000); | ||
- | } | ||
- | } | ||
- | </ | ||
- | ==== Graafiline LCD ==== | ||
- | |||
- | //Vajalikud teadmised: [HW] [[et: | ||
- | |||
- | === Teooria === | ||
- | |||
- | Graafiline LCD on vedelkristall-ekraan, | ||
- | |||
- | [{{ : | ||
- | |||
- | Monokromaatilised graafilised ekraanid on tavaliselt passiivmaatriksiga, | ||
- | |||
- | ~~CL~~ | ||
- | |||
- | === Praktika === | ||
- | |||
- | Kodulabori komplekti kuulub mõõtudega 84 x 48 pikslit monokromaatiline graafiline LCD ekraan. See ekraan on sama, mida kasutatakse Nokia 3310 mobiiltelefonides. Ekraani küljes on Philipsi PCD8544 kontroller, millega saab suhelda läbi SPI-taolise järjestikliidese. Eraldi juhitav on veel ekraanimooduli taustvalgustus. Ekraaniga suhtlemine pole kuigi keeruline, kuid funktsioonide suure arvu tõttu pole siinkohal seda lahti seletatud. Kodulabori teegis on olemas funktsioonid selle kasutamiseks. | ||
- | |||
- | Graafilise LCD teegi funktsioonid on sarnased alfabeetilise LCD omadele. Esmalt tuleb ekraan algväärtustada funktsiooniga // | ||
- | |||
- | Järgnevalt on toodud näide aja loenduri kohta. Programm loendab sekundeid (ligikaudu), | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Kodulabori graafilise LCD kasutamise näide. | ||
- | // LCD-le kuvatakse kellaaeg programmi algusest alates. | ||
- | // | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | int seconds = 0; | ||
- | char text[16]; | ||
- | |||
- | // LCD ekraani algseadistamine | ||
- | lcd_gfx_init(); | ||
- | |||
- | // Ekraani puhastamine | ||
- | lcd_gfx_clear(); | ||
- | |||
- | // Taustavalgustuse tööle lülitamine | ||
- | lcd_gfx_backlight(true); | ||
- | |||
- | // Programmi nime kuvamine | ||
- | lcd_gfx_goto_char_xy(1, | ||
- | lcd_gfx_write_string(" | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // Sekundite teisendamine kellaaja kujule | ||
- | // hh:mm:ss | ||
- | sprintf(text, | ||
- | (seconds / 3600) % 24, | ||
- | (seconds / 60) % 60, | ||
- | seconds % 60); | ||
- | |||
- | // Kellaaja teksti kuvamine | ||
- | lcd_gfx_goto_char_xy(3, | ||
- | lcd_gfx_write_string(text); | ||
- | |||
- | // Sekundi suurendamine 1 võrra | ||
- | seconds++; | ||
- | |||
- | // Riistvaraline paus 1000 millisekundit | ||
- | hw_delay_ms(1000); | ||
- | } | ||
- | } | ||
- | </ | ||
- | ==== Harjutusülesanded ==== | ||
- | |||
- | Eesmärgiks on koostada programm, mis täidab kirjeldatud ülesannet. | ||
- | |||
- | === Soojendusülesanne === | ||
- | |||
- | * Loendab 7-segmendilisel indikaatoril numbreid 1..9 ning siis tagurpidi tagasi 9..1. Loendamise periood 1 sekund. | ||
- | |||
- | === Algajale === | ||
- | |||
- | - Suvalises järjekorras esitada 7-segmendilisel indikaatoril kuueteistkümnendsüsteemi arve sagedusega 1 Hz. | ||
- | - 7-segmendilisel indikaatoril panna 500 ms perioodiga ringiratast kordamööda põlema välised 6 segmenti. | ||
- | - Alfabeetilisel LCD-le kirjutada järgnev tekst: "õun öö äpu ülo" | ||
- | - Alfabeetilisel LCD-l näidata erisümboleid. Kuvada ekraanil kahel real järgnevad tekstid: "Minu programm ©", " | ||
- | - Graafilisel LCD-l kuvada 10-realine tekst, mida saab nuppudega S1 ja S2 üles-alla kerida. | ||
- | - Kolme nupuga teha kasutajaliides teksti sisestamiseks. Näiteks ühe nupuga teha märgi valik, teisega märgi kinnitamine ja kolmandaga teksti lõplik kinnitamine. Teksti maksimaalne pikkus on 10 märki ja tekst tuleb pärast sisestust tagurpidi keerata ning teisel real kuvada. Piirduda võib ladina tähestikuga. LCD omal valikul. | ||
- | |||
- | === Edasijõudnule === | ||
- | |||
- | - Graafilisel LCD-l kuvada kreeka tähti. Esitada järgnevad read: " | ||
- | - Kirjutada kümnendsüsteemi arvu sisestaja ja kahendkoodi teisendaja. Kasuta nuppe S3 - S1 sisestamaks kümnendsüsteemi arvu (S3 - sajalised, S2 - kümnelised, | ||
- | - Kirjutada funktsioon, mis kuvab graafilisel LCD-l ristküliku, | ||
- | - Teha lihtne ussimäng graafilisel LCD ekraanil. Ussi laius on 1 piksel, pikkus 5 pikslit. Ussi saab nuppudega vasakule või paremale pöörama panna. Uss peab suutma vältida kokkupõrget ekraani servaga (enne seda ära keerama). Boonuspunktid munade korjamise võimaluse ja järjest pikeneva ussi eest. Ülesande lihtsam lahendus on uss teha " | ||
- | - Kirjuta programm erinevate ilmastikunähtuste kuvamiseks graafilisel LCD-l. Päikesepaisteline ilm - päikese ikoon, vihmane ilm - pilv koos sajuga, pilves ilm - lihtsalt pilv, lumesadu - lumehelves. Ikoonide suurus võib varieeruda, peaasi, et ikoonid on selgesti eristatavad. Ikoone peab nupuvajutusega vahetada saama. | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === Kordamisküsimused === | ||
- | |||
- | - Mitu viiku kasutab 7-segmendiline numbernäidik (koos punktisegmendiga), | ||
- | - Mis määrab 7-segmendilise numbernäidiku heleduse? Kuidas seda reguleerida, | ||
- | - Kui 7-segmendiline numbernäidik on kontrolleriga otse ühendatud porti A nii, et segment A on viik PA0, B on PA1 ... ja DP on PA7, siis millised on PORTA registri väärtused numbrite 0..9 korral? | ||
- | - Mille poolest erinevad alfabeetilise LCD 4-bitine ja 8-bitine juhtliides? | ||
- | - Milliste viikude kaudu reguleeritakse alfabeetilise LCD taustavalgust ja kuidas? | ||
- | - Mis andmevahetusprotokolli kasutab graafiline LCD? Selgitage andmevahetusviikude tähendusi. | ||
- | - Kuidas teisendada kümnendsüsteemi arvu kahendsüsteemi arvuks (tekstikujule) ja vastupidi? | ||
- | - Joonistage //twisted nematic// | ||
- | - Kuidas moodustatakse graafilisel LCD-l tähed? | ||
- | - Mille poolest erineb monokromaatiline (must-valge) ja värviline LCD ekraan? | ||
- | ===== Andurid ===== | ||
- | |||
- | {{ : | ||
- | |||
- | Andurid on seadmed, mis teisendavad mingi füüsikalise suuruse, näiteks temperatuuri, | ||
- | |||
- | Analooganduris muutub füüsikalise suuruse muutudes mõni selle elektriline parameeter, tavaliselt kas pinge, vool või takistus. Kuna mikrokontrollerid on digitaalsed seadmed, siis analooganduri info edastamiseks kontrollerile tuleb see digitaalseks teisendada. Selleks kasutatakse peamiselt mikrokontrolleritesse integreeritud analoog-digitaalmuundureid. | ||
- | |||
- | Kui analoogandur juba sisaldab info digitaliseerijat, | ||
- | |||
- | ==== Potentsiomeeter ==== | ||
- | |||
- | //Vajalikud teadmised: [HW] [[et: | ||
- | |||
- | === Teooria === | ||
- | |||
- | [{{ : | ||
- | |||
- | Potentsiomeeter on kolme kontaktiga muuttakisti, | ||
- | |||
- | [{{ : | ||
- | |||
- | Tüüpiline potentsiomeeter koosneb voolu juhtiva pinnaga takistist ja sellel liuglevast liikuvast kontaktist ehk liugurist. Mida lähemal on liugur takisti servale, seda väiksem on liuguri ja selle serva vaheline takistus ning vastupidi. Takisti rolli võib täita kas suure eritakistusega materjal või takistustraadist keritud mähis. Potentsiomeetreid on olemas nii lineaarse kui ka logaritmilise takistuse ja positsiooni suhtega. Suurem osa potentsiomeetritest on pööratavad (näide kõrvaloleval pildil), kuid eksisteerib ka liugtakisteid. Potentsiomeetrite eriliik on digitaalsed potentsiomeetrid, | ||
- | |||
- | === Praktika === | ||
- | |||
- | Kodulabori Andurite mooduli plaadil asub pööratav 4,7 kΩ potentsiomeeter. Potentsiomeeter on ühendatud maa ja +5 V potentsiaalide vahele ning liugur ühendub mikrokontrolleri analoog-digitaalmuunduri kanaliga 3. Selliselt ühendatuna saab potentsiomeetri väljundpinget reguleerida vahemikus 0 kuni 5 V. Kui ka AVR-i analoog-digitaalmuunduri võrdluspinge võtta AVCC viigult, saab potentsiomeetri väljundpinge digitaalse väärtuse kogu selle reguleerimispiirkonna ulatuses. AVR ADC kasutamiseks on Kodulabori teegis kirjutatud järgmised funktsioonid: | ||
- | |||
- | ~~PB~~ | ||
- | ~~CL~~ | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Seadistuse andmetüübid | ||
- | // | ||
- | typedef enum | ||
- | { | ||
- | ADC_REF_AREF = 0x00, | ||
- | ADC_REF_AVCC = 0x01, | ||
- | ADC_REF_2V56 = 0x03 | ||
- | } | ||
- | adc_reference; | ||
- | |||
- | typedef enum | ||
- | { | ||
- | ADC_PRESCALE_2 | ||
- | ADC_PRESCALE_4 | ||
- | ADC_PRESCALE_8 | ||
- | ADC_PRESCALE_16 | ||
- | ADC_PRESCALE_32 | ||
- | ADC_PRESCALE_64 | ||
- | ADC_PRESCALE_128 = 0x07 | ||
- | } | ||
- | adc_prescale; | ||
- | |||
- | // | ||
- | // ADC käivitamine | ||
- | // | ||
- | void adc_init(adc_reference reference, adc_prescale prescale) | ||
- | { | ||
- | // ADC töötamise lubamine, sagedusjaguri valimine | ||
- | ADCSRA = bit_mask(ADEN) | (prescale & 0x07); | ||
- | |||
- | // Võrdluspinge valimine | ||
- | ADMUX = (reference & 0x03) << REFS0; | ||
- | } | ||
- | |||
- | // | ||
- | // ADC määratud kanali väärtuse muundamine | ||
- | // | ||
- | unsigned short adc_get_value(unsigned char channel) | ||
- | { | ||
- | // Kanali määramine | ||
- | ADMUX = (ADMUX & 0xF0) | (channel & 0x0F); | ||
- | |||
- | // Muundamise alustamine | ||
- | bit_set(ADCSRA, | ||
- | |||
- | // Muundamise lõpu ootamine | ||
- | while (bit_is_set(ADCSRA, | ||
- | { | ||
- | asm volatile (" | ||
- | } | ||
- | |||
- | // Tulemuse tagastamine | ||
- | return ADCW; | ||
- | } | ||
- | </ | ||
- | |||
- | Funktsioon // | ||
- | |||
- | Näiteprogrammis kasutatakse äsja selgitatud analoog-digitaalmuunduri ja 7-segmendilise LED numberindikaatori teeki. 10-bitine analoog-digitaalmuunduri väärtus korrutatakse kümnega ja jagatakse 1024-ga, et saada väärtus vahemikus 0 kuni 9. Väärtus 10 ei saa tekkida, sest C-keeles arvutatakse jagatises täisosa väärtus, mitte ümardatud tulemus. Täpsema mõõtetulemuse saamiseks kasutatakse muunduri tulemuse keskmistamise funktsiooni. Tulemusena näitab töötav programm vastavalt potentsiomeetri asendile indikaatoril numbreid 0 kuni 9. | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Kodulabori Andurite mooduli potentsiomeetri | ||
- | // näidisprogramm. 7-segmendilisel numberindikaatoril | ||
- | // kuvatakse potentsiomeetri asendit. | ||
- | // | ||
- | #include < | ||
- | #include < | ||
- | |||
- | // | ||
- | // Kanali valimine | ||
- | // | ||
- | // 1 = fototakisti | ||
- | // 2 = termotakisti | ||
- | // 3 = potentsiomeeter | ||
- | // | ||
- | #define ADC_CHANNEL 3 | ||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | int value; | ||
- | |||
- | // 7-segmendilise indikaatori seadistamine | ||
- | segment_display_init(); | ||
- | |||
- | // ADC muunduri seadistamine | ||
- | adc_init(ADC_REF_AVCC, | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // Kanali 4-kordselt ümardatud väärtuse lugemine | ||
- | value = adc_get_average_value(ADC_CHANNEL, | ||
- | |||
- | // Näidu sajandike näitamine | ||
- | segment_display_write(value * 10 / 1024); | ||
- | } | ||
- | } | ||
- | </ | ||
- | ==== Termistor ==== | ||
- | |||
- | //Vajalikud teadmised: [HW] [[et: | ||
- | |||
- | === Teooria === | ||
- | |||
- | [{{ : | ||
- | |||
- | Termistor on takisti, mille takistus muutub temperatuuriga. Termistore on kahte liiki: positiivse ja negatiivse temperatuuri koefitsiendiga. Positiivse koefitsiendiga termistori takistus temperatuuri tõustes kasvab ja negatiivsel väheneb. Vastavad lühendatud ingliskeelsed nimed on neil PTC (//positive temperature coefficient// | ||
- | |||
- | Termistori kasutamise teeb keeruliseks tema takistuse temperatuurisõltuvuse mittelineaarsus. Lineaarne on sõltuvus vaid väikestes vahemikes, mitmekümnekraadise ja suurema mõõtepiirkonna arvutamiseks sobib Steinhart-Harti kolmandat järku eksponentsiaalne võrrand. NTC termistoride jaoks on olemas järgmine B-parameetriga lihtsustatud võrrand: | ||
- | |||
- | {{: | ||
- | |||
- | kus:\\ | ||
- | * T< | ||
- | * R< | ||
- | * B on B-parameeter. | ||
- | |||
- | B-parameeter on koefitsient, | ||
- | |||
- | Termistori takistust mõõdetakse kaudselt pingejaguriga, | ||
- | |||
- | Piiratud ressurssidega ja suurt täpsust mittenõudvates rakendustes kasutatakse eelnevalt välja arvutatud temperatuuri ja takistuse vahelise sõltuvuse tabelit. Tabelis on üldjuhul kirjas kindla vahemikuga temperatuurinäitude vastavus anduri takistuse, pinge või analoog-digitaalmuunduri väärtusega. Tabeli puhul on kogu eksponentsiaalne arvutus eelnevalt ära tehtud ja programmis tuleb vaid mõõdetud parameetrile vastav rida üles otsida ja temperatuur välja lugeda. | ||
- | |||
- | === Praktika === | ||
- | |||
- | Kodulabori Andurite mooduli plaat on varustatud 10 kΩ nimitakistusega NTC tüüpi termistoriga. Temperatuuril 25-50 °C on termistori B-parameeter 3900. Termistori üks viik on ühendatud +5 V toitega ja teine mikrokontrolleri analoog-digitaalmuunduri kanaliga 2 (viik PF2). Sama mikrokontrolleri viigu ja maaga on ühendatud ka tavaline 10 kΩ takisti, mis koos termistoriga moodustab pingejaguri. Kuna tegu on NTC termistoriga, | ||
- | |||
- | Temperatuuri leidmiseks on AVR-i peal otstarbekas kasutada temperatuuri ja analoog-digitaalmuunduri väärtuste teisendustabelit. Mõistlik on leida soovitud temperatuurivahemikust igale kraadile vastav analoog-digitaalmuunduri väärtus, sest vastupidine tabel läheb 10-bitise ADC väärtuste hulga tõttu liiga suureks. Tabeli tegemiseks on soovitatav kasutada mõnd tabelarvutuse programmi (MS Excel, Openoffice Calc vmt.). Eespool toodud NTC termistorite jaoks kohandatud Steinhart-Harti valemiga saab leida temperatuurile vastava termistori takistuse. Takistusest saab arvutada pingejaguri väljundpinge ning sellest omakorda ADC väärtuse. Leitud väärtused saab järgneval viisil programmi sisse kirjutada: | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Temperatuuri ADC väärtuseks teisendamise tabel. | ||
- | // Iga massiivi element tähistab ühte Celsiuse kraadi. | ||
- | // Elemendid algavad -20 kraadist ja lõpevad 100 kraadiga. | ||
- | // Kokku on massiivis 121 elementi. | ||
- | // | ||
- | const signed short min_temp = -20; | ||
- | const signed short max_temp = 100; | ||
- | |||
- | const unsigned short conversion_table[] = | ||
- | { | ||
- | 91, | ||
- | 160, | ||
- | 257, | ||
- | 375, | ||
- | 501, | ||
- | 619, | ||
- | 720, | ||
- | 799, | ||
- | 859, | ||
- | 903, | ||
- | 934, | ||
- | }; | ||
- | </ | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | Et tabelist ADC väärtuse järgi temperatuur leida, võib kasutada järgmist algoritmi: | ||
- | |||
- | <code c> | ||
- | // | ||
- | // ADC väärtuse teisendamine Celsiuse kraadideks. | ||
- | // | ||
- | signed short thermistor_calculate_celsius(unsigned short adc_value) | ||
- | { | ||
- | signed short celsius; | ||
- | |||
- | // Tabeli tagurpidi läbikäimine | ||
- | for (celsius = max_temp - min_temp; celsius >= 0; celsius--) | ||
- | { | ||
- | // Kui tabeli väärtus on sama või suurem kui | ||
- | // mõõdetud tulemus, siis temperatuur on vähemalt | ||
- | // sama kõrge kui elemendile vastav temperatuur | ||
- | if (adc_value >= conversion_table[celsius]) | ||
- | { | ||
- | // Kuna tabel algab nullist, aga elementide | ||
- | // väärtus -20 kraadist, siis tuleb väärtust nihutada | ||
- | return celsius + min_temp; | ||
- | } | ||
- | } | ||
- | |||
- | // Kui väärtust ei leitud, tagastatakse minimaalne temperatuur | ||
- | return min_temp; | ||
- | } | ||
- | </ | ||
- | |||
- | Algoritm otsib tabelist vahemikku, kuhu ADC väärtus jääb, ja saab teada selle vahemiku aluspiiri järjekorranumbri. Järjekorranumber tähistab kraade, sellele tuleb ainult algtemperatuur otsa liita ja nii saadaksegi 1 kraadi täpsusega temperatuur. | ||
- | |||
- | Toodud teisendustabel ja funktsioon on juba olemas Kodulabori teegis, nii et käesolevas harjutuses neid ise kirjutama ei pea. Teisendamise funktsioonil on teegis nimeks // | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Kodulabori Andurite mooduli termistori näidisprogramm. | ||
- | // LCD ekraanil kuvatakse temperatuur kraadides. | ||
- | // | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | unsigned short value; | ||
- | signed short temperature; | ||
- | char text[16]; | ||
- | |||
- | // LCD ekraani seadistamine | ||
- | lcd_alpha_init(LCD_ALPHA_DISP_ON); | ||
- | |||
- | // LCD ekraani puhastamine | ||
- | lcd_alpha_clear(); | ||
- | |||
- | // Programmi nimi | ||
- | lcd_alpha_write_string(" | ||
- | |||
- | // ADC muunduri seadistamine | ||
- | adc_init(ADC_REF_AVCC, | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // Termistori pinge 4-kordselt ümardatud väärtuse lugemine | ||
- | value = adc_get_average_value(2, | ||
- | |||
- | // ADC väärtuse kraadideks ümberarvutamine | ||
- | temperature = thermistor_calculate_celsius(value); | ||
- | |||
- | // Temperatuuri tekstiks teisendamine | ||
- | // Kraadi märgi kuvamiseks on oktaalarv 337 | ||
- | sprintf(text, | ||
- | |||
- | // Teksti kuvamine LCD teise rea alguses | ||
- | lcd_alpha_goto_xy(0, | ||
- | lcd_alpha_write_string(text); | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | /* | ||
- | === Lisamaterjalid === | ||
- | |||
- | * {{: | ||
- | */ | ||
- | ==== Fototakisti ==== | ||
- | |||
- | //Vajalikud teadmised: [HW] [[et: | ||
- | |||
- | === Teooria === | ||
- | |||
- | [{{ : | ||
- | [{{ : | ||
- | |||
- | Fototakisti on andur, mille elektriline takistus muutub sõltuvalt temale pealelangeva valguse intensiivsusest. Mida intensiivsem on valgus, seda rohkem tekib vabu laengukandjaid ning seda väiksemaks jääb elemendi takistus. Fototakisti kaks välist metallkontakti ulatuvad läbi keraamilise alusmaterjali valgustundliku kileni, mis oma geomeetria ja materjali omaduse poolest määravad elektrilised takistuslikud omadused. Kuna fototundlik materjal on iseloomult suure takistusega, | ||
- | |||
- | ^ Värv ^ Lainepikkuse vahemik (nm) ^ | ||
- | | Lilla | 400 – 450 | | ||
- | | Sinine | ||
- | | Roheline | ||
- | | Kollane | ||
- | | Oranž | ||
- | | Punane | ||
- | |||
- | Fototakistil on kindlasti määratud ka töötemperatuuri vahemik. Kui tahta lasta anduril töötada erinevatel temperatuuridel, | ||
- | |||
- | Valguse intensiivsuse iseloomustamiseks kasutatakse füüsikalist suurust valgustustihedus (tähis E), mis näitab mingile pinnale jõudva valgusvoo hulka. Mõõdetavaks ühikuks on luks (lx), kus 1 luks tähendab, et 1 m< | ||
- | |||
- | ^ Keskkond | ||
- | | Täiskuu | ||
- | | Hämarus | ||
- | | Auditoorium | ||
- | | Klassiruum | ||
- | | Päikesetõus või -loojang | ||
- | | Haigla operatsioonisaal | ||
- | | Otsene päikesevalgus | ||
- | |||
- | === Praktika === | ||
- | |||
- | Kodulabori Andurite mooduli plaat on varustatud VT935G fototakistiga. Selle üks viik on ühendatud +5 V toitega ja teine mikrokontrolleri analoog-digitaalmuunduri kanaliga 1 (viik PF1). Sama mikrokontrolleri viigu ja maaga on ühendatud ka tavaline 10 kΩ takisti, mis koos fototakistiga moodustab pingejaguri. Kuna fototakisti elektriline takistus väheneb temale langeva valguse intensiivsuse kasvades, siis mõõdetav pinge mikrokontrolleri viigu peal kasvab valguse intensiivsuse kasvades. Tasuks arvestada, et Kodulaboris kasutatav fototakisti reageerib kõige intensiivsemalt kollasele ja oranžile valgusele. | ||
- | |||
- | VT935G andur ei olegi tegelikult mõeldud konkreetseks mõõteseadmeks, | ||
- | |||
- | Käesolev harjutus on aga natukese keerulisem, kuna leitakse andurile valgeva valguse valgustustihedust luksides. Selle tegemiseks on kasutusel ligikaudne arvutusvalem ja ujukoma arvud. Ujukoma arvud on C-keeles //float// ja //double// tüüpi, millega saab esitada murdarve. Nende puuduseks on suhteliselt suur ressursinõudlikkus. Arvutites on nende arvutamiseks spetsiaalne riistvara, 8-bitisel AVR mikrokontrolleril tehakse arvutused tarkvaras, mis võtab suhteliselt palju programmimälu ja aega. Kui puudused pole olulised, on ujukoma arvud väärt kasutamist. | ||
- | |||
- | [{{ : | ||
- | |||
- | Fototakisti valgustustiheduse ja elektritakistuse vahelise seose kohta annab anduri andmeleht ligikaudse valemi. Nagu kõrvalolevalt graafikult näha, on logaritmskaalas valgustustihedus ja takistus ligikaudu lineaarses seoses ning moodustavad sirge võrrandi, sest kehtib teisendus: | ||
- | |||
- | log(a/b) = log(a) - log(b) | ||
- | |||
- | Seost iseloomustab γ faktor (sirge tõus), mis VT935G anduril on 0,9. Teada on ka joone ühe punkti andmed: 18,5 kΩ takistus (R< | ||
- | |||
- | log(E< | ||
- | E< | ||
- | |||
- | Sellega on takistusest valgustustiheduse arvutamise valem olemas. Takistust otse aga mikrokontrolleriga mõõta ei saa - selleks on fototakisti pingejaguris, | ||
- | |||
- | U< | ||
- | |||
- | Pingejaguri valemist (vaata pingejaguri peatükki) saab leida skeemis ülemise fototakisti takistuse (R< | ||
- | |||
- | R< | ||
- | |||
- | Järgnevalt on pinge ja takistuse arvutamisel teadaolevad tegurid asendatud väärtustega ja alaindeksid ära jäetud: | ||
- | |||
- | U = 5 ⋅ (ADC / 1024) \\ \\ | ||
- | R = (10 ⋅ 5) / U - 10 \\ \\ | ||
- | |||
- | Valgustustiheduse leidmisel saab teha lihtsustavaid teisendusi: | ||
- | |||
- | E = 10< | ||
- | = 10< | ||
- | = (18, | ||
- | |||
- | Arvutades välja muutuja R ees oleva konstandi, jääb avaldis kujule: | ||
- | |||
- | E = 255,84 ⋅ R< | ||
- | |||
- | Nende valemite abil saab kasutada vaid Kodulabori Andurite mooduli plaadil olevat fototakistit. Teiste komponentidega skeemi kasutades tuleks valemites muuta vastavaid arvväärtusi. Järgnevalt on toodud näidisprogrammi lähtekood, mis teostab ADC-ga mõõtmist, arvutamist ja valgustustiheduse kuvamist LCD ekraanile. Kuid veel enne programmi kompileerimist tuleb projektis teha seadistused ujukoma arvude kasutuselevõtuks. Selle kohta on lühiõpetus tarkvara paigaldamise peatükis. | ||
- | |||
- | Näidisprogrammis defineeritakse pinge, takistuse ja valgustustiheduse muutujad ujukoma tüüpi arvuna //double//. Arvud, mida soovitakse kindlasti ujukoma tehetes kasutada, peavad alati sisaldama komakohta (C-keeles punkti), olgu kas või nulli, sest siis ei tõlgenda kompilaator neid valesti. //sprintf// abil ujukoma arvu tekstiks teisendades tuleb kasutada " | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Kodulabori Andurite mooduli fototakisti näidisprogramm. | ||
- | // LCD ekraanil kuvatakse ligikaudne valgustustihedus luksides | ||
- | // | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | char text[16]; | ||
- | unsigned short adc_value; | ||
- | double voltage, resistance, illuminance; | ||
- | |||
- | // LCD ekraani seadistamine | ||
- | lcd_alpha_init(LCD_ALPHA_DISP_ON); | ||
- | |||
- | // LCD ekraani puhastamine | ||
- | lcd_alpha_clear(); | ||
- | |||
- | // Programmi nimi | ||
- | lcd_alpha_write_string(" | ||
- | |||
- | // ADC muunduri seadistamine | ||
- | adc_init(ADC_REF_AVCC, | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // Fototakisti keskmistatud väärtuse lugemine | ||
- | adc_value = adc_get_average_value(1, | ||
- | |||
- | // Pinge arvutamine ADC sisendis | ||
- | voltage = 5.0 * ((double)adc_value / 1024.0); | ||
- | |||
- | // Fototakisti takistuse arvutamine pingejaguris | ||
- | resistance = (10.0 * 5.0) / voltage - 10.0; | ||
- | |||
- | // Valgustustiheduse luksides arvutamine | ||
- | illuminance = 255.84 * pow(resistance, | ||
- | |||
- | // Valgustustiheduse tekstiks teisendamine | ||
- | sprintf(text, | ||
- | |||
- | // Näidu LCD-l kuvamine | ||
- | lcd_alpha_goto_xy(0, | ||
- | lcd_alpha_write_string(text); | ||
- | |||
- | // Viide 500 ms | ||
- | sw_delay_ms(500); | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | ==== Infrapuna kaugusandur ==== | ||
- | |||
- | //Vajalikud teadmised: [HW] [[et: | ||
- | |||
- | === Teooria === | ||
- | |||
- | [{{ : | ||
- | |||
- | Objekti kauguse mõõtmiseks on olemas triangulatsioonimeetodil töötavad optilised andurid. Levinuimad neist on firma Sharp poolt toodetavad infrapuna (inglise keeles // | ||
- | |||
- | [{{ : | ||
- | |||
- | Sharp-i kaugusandurite väljund on pöördvõrdeline - kauguse kasvades see väheneb ja järjest aeglasemalt. Täpne kauguse ja väljundi vaheline graafik on toodud andurite andmelehel. Anduritel on vastavalt tüübile ka mõõtepiirkond, | ||
- | |||
- | === Praktika | ||
- | |||
- | [{{ : | ||
- | |||
- | Kodulabori andurite komplektis on Sharp-i infrapuna kaugusmõõdik GP2Y0A21YK mõõtepiirkonnaga 10-80 cm. Anduri väljundpinge on kuni 3 V sõltuvalt mõõdetavast kaugusest. Andur ühendub andurite mooduli külge ja selle väljundpinge suunatakse AVR-i analoog-digitaalmuunduri kanalisse 0. Eelnevate andurite harjutuste baasil saab lihtsalt teha programmi, mis mõõdab kaugusmõõdiku väljundpinget, | ||
- | |||
- | GP2Y0A21YK andmelehel on toodud väljundpinge ja mõõdetud kauguse vahelise sõltuvuse graafik. See pole lineaarne, kuid väljundpinge ja kauguse pöördväärtuse graafik peaaegu juba on, ning sellest on suhteliselt lihtne leida valem pinge kauguseks teisendamiseks. Valemi leidmiseks tuleb sama graafiku punktid sisestada mõnda tabelarvutuse programmi ja nendest uuesti graafik luua. Tabelarvutusprogrammides on graafiku punktide põhjal võimalik arvutada automaatselt välja trendijoon. Järgnevalt on toodud GP2Y0A21YK väljundpinge ja kauguse korrigeeritud pöördväärtuse vahelise seose graafik koos lineaarse trendijoonega. Väljundpinge on valemi lihtsustamise nimel juba teisendatud 10-bitiseks +5 V võrdluspingega analoog-digitaalmuunduri väärtuseks. | ||
- | |||
- | [{{ : | ||
- | |||
- | Nagu graafikult näha, kattub trendijoon (sinine) | ||
- | |||
- | 1 / (d + k) = a ⋅ ADC + b | ||
- | |||
- | kus | ||
- | |||
- | * d on kaugus sentimeetrites | ||
- | * k on korrigeerimiskonstant (leitud katse-eksitusmeetodil) | ||
- | * ADC on pinge digitaliseeritud väärtus | ||
- | * a on lineaarliige (väärtus tuleb trendijoone võrrandist) | ||
- | * b on vabaliige (väärtus tuleb trendijoone võrrandist) | ||
- | |||
- | Valemist saab avaldada kauguse d: | ||
- | |||
- | d = (1 / (a ⋅ ADC + B)) - k | ||
- | |||
- | Põhimõtteliselt saakski selle valemiga kauguse välja arvutada, kuid see eeldaks ujukoma-arvutusi, | ||
- | |||
- | d = (1 / a) / (ADC + B / a) - k | ||
- | |||
- | Viies valemisse korrigeerimiskonstandi väärtuse ja trendijoone võrrandist saadud lineaar- ja vabaliikme (saadud jooniselt), tuleb kauguse arvutamise valemiks: | ||
- | |||
- | d = 5461 / (ADC - 17) - 2 | ||
- | |||
- | See valem on arvutatav 16-bitiste täisarvudega ja täiesti jõukohane AVR-ile. Enne arvutamist tuleb aga veenduda, et ADC väärtus oleks üle 17, sest muidu tekib nulliga jagamine või negatiivne kaugus, mis on ebaloogiline. | ||
- | |||
- | Järgnevalt on toodud Kodulabori teegis kirja pandud funktsioon ADC väärtuse sentimeetriteks teisendamise kohta. Lineaar- ja vabaliige ning korrigeerimiskonstant pole funktsiooni jäigalt sisse kirjutatud, vaid need antakse ette IR kaugusanduri parameetrite struktuuri objektiga. Hoides parameetreid eraldi konstandis, saab hiljem programmi lihtsalt lisada uusi IR kaugusandurite mudeleid. | ||
- | ~~PB~~ | ||
- | <code c> | ||
- | // | ||
- | // IR kaugusanduri parameetrite struktuur | ||
- | // | ||
- | typedef const struct | ||
- | { | ||
- | const signed short a; | ||
- | const signed short b; | ||
- | const signed short k; | ||
- | } | ||
- | ir_distance_sensor; | ||
- | |||
- | // | ||
- | // GP2Y0A21YK anduri parameetrite objekt | ||
- | // | ||
- | const ir_distance_sensor GP2Y0A21YK = { 5461, -17, 2 }; | ||
- | |||
- | // | ||
- | // IR kaugusanduri ADC väärtuse sentimeetriteks teisendamine | ||
- | // Tagastab -1, kui teisendus ei õnnestunud | ||
- | // | ||
- | signed short ir_distance_calculate_cm(ir_distance_sensor sensor, | ||
- | unsigned short adc_value) | ||
- | { | ||
- | if (adc_value + sensor.b <= 0) | ||
- | { | ||
- | return -1; | ||
- | } | ||
- | |||
- | return sensor.a / (adc_value + sensor.b) - sensor.k; | ||
- | } | ||
- | </ | ||
- | |||
- | Teisenduse tegemiseks tuleb välja kutsuda // | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Kodulabori IR kaugusmõõdiku näidisprogramm. | ||
- | // LCD ekraanil kuvatakse mõõdetud kaugus sentimeetrites. | ||
- | // | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | signed short value, distance; | ||
- | char text[16]; | ||
- | |||
- | // LCD ekraani seadistamine | ||
- | lcd_alpha_init(LCD_ALPHA_DISP_ON); | ||
- | |||
- | // LCD ekraani puhastamine | ||
- | lcd_alpha_clear(); | ||
- | |||
- | // Programmi nimi | ||
- | lcd_alpha_write_string(" | ||
- | |||
- | // ADC muunduri seadistamine | ||
- | adc_init(ADC_REF_AVCC, | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // Anduri väljundpinge 4-kordselt ümardatud väärtuse lugemine | ||
- | value = adc_get_average_value(0, | ||
- | |||
- | // ADC väärtuse kauguseks ümberarvutamine | ||
- | distance = ir_distance_calculate_cm(GP2Y0A21YK, | ||
- | |||
- | // Kas saab kauguse või veateate kuvada ? | ||
- | if (distance >= 0) | ||
- | { | ||
- | sprintf(text, | ||
- | } | ||
- | else | ||
- | { | ||
- | sprintf(text, | ||
- | } | ||
- | |||
- | // Teksti kuvamine LCD teise rea alguses | ||
- | lcd_alpha_goto_xy(0, | ||
- | lcd_alpha_write_string(text); | ||
- | |||
- | // Paus | ||
- | sw_delay_ms(500); | ||
- | } | ||
- | } | ||
- | </ | ||
- | /* | ||
- | === Lisamaterjalid === | ||
- | |||
- | * {{: | ||
- | * [[http:// | ||
- | */ | ||
- | ==== Ultraheli kaugusmõõdik ==== | ||
- | |||
- | //Vajalikud teadmised: [HW] [[et: | ||
- | |||
- | === Teooria === | ||
- | |||
- | [{{ : | ||
- | |||
- | Ultraheli kaugusmõõdik määrab objekti(de) kaugust, mõõtes helilaine objektilt tagasipeegeldumise aega. Helilaine sagedus asub ultraheli sageduse piirkonnas, mis tagab kontsentreerituma helilaine suuna, sest kõrgema sagedusega heli hajub keskkonnas vähem. Tüüpiline ultraheli kaugusmõõdik koosneb kahest membraanist, | ||
- | |||
- | [{{ : | ||
- | |||
- | Ultraheli kaugusmõõdikutel on igapäevaelus mitmeid rakendusi. Neid kasutatakse mõõdulintide asendajatena kauguse mõõtmise seadmetes, näiteks ehitusel. Tänapäeva autod on varustatud tagurdamisel takistusest hoiatavate ultraheliandurite ja hoiatussignaaliga. Peale kauguse mõõtmise võivad nad lihtsalt registreerida objekti olemasolu mõõtepiirkonnas, | ||
- | |||
- | === Praktika === | ||
- | |||
- | Kodulabori Andurite mooduli komplektis on Devantech SRF04 või SRF05 ultraheli kaugusmõõdik. SRF04/SRF05 on ainult andur, mis otseselt kauguse infot ei väljasta. Anduril on peale toiteviikude veel päästiku ja kaja viik. Päästiku viiku kõrgeks seades genereerib andur 8-perioodilise 40 kHz ultraheli laine. Sel hetkel läheb kõrgeks kaja viik ja jääb kõrgeks niikauaks, kuni peegeldunud helilaine on andurini jõudnud. Seega põhimõtteliselt näitab kaja signaal aega, mille jooksul heli levib objektini ja tagasi. Mõõtes seda aega, korrutades seda heli levimise kiirusega ja jagades kahega, saab leida objekti kauguse. Päästiku, helilaine kiirguri ja kaja signaale ajas iseloomustab kõrvalolev graafik. | ||
- | |||
- | [{{ : | ||
- | |||
- | Devantech-i ultrahelianduri AVR-iga kasutamiseks tuleb selle päästiku ja kaja viigud ühendada mõnede AVR-i viikudega. Aja mõõtmiseks on sobiv kasutada 16-bitist taimerit, näiteks //timer3//. Järgnevalt on toodud funktsioon, mis teostab kogu mõõtmisprotseduuri - genereerib päästiku signaali, käivitab taimeri, mõõdab kajasignaali pikkust ja teisendab selle kauguseks sentimeetrites. Funktsioon on blokeeruv ehk protsessor on sellega hõivatud senikaua, kuni mõõtetulemus on käes või mõõtmine venib lubatust pikemaks. Mida kiiremini kaja saabub, seda kiiremini saab mõõtetulemuse. Kui kaja ei saabugi, ootab funksioon seda ~36 ms ja tagastab seejärel 0. Oluline on mõõtmiste vahele jätta mõnikümmend millisekundit pausi, et eelmisel mõõtmisel tekitatud helilaine jõuaks sumbuda ega rikuks uut mõõtmist. Kui kasutatakse samaaegselt mitut ultraheli andurit, tuleb samuti jälgida, et helilained ei kattuks. | ||
- | |||
- | <code c> | ||
- | #define ULTRASONIC_SPEED_OF_SOUND 33000 // cm/s | ||
- | |||
- | // | ||
- | // Ultraheli kaugusanduriga mõõtmine | ||
- | // | ||
- | unsigned short ultrasonic_measure(pin trigger, pin echo) | ||
- | { | ||
- | // Viikude seadistus | ||
- | pin_setup_output(trigger); | ||
- | pin_setup_input_with_pullup(echo); | ||
- | |||
- | // Taimer 3 normaalrežiimi | ||
- | // perioodiga F_CPU / 8 | ||
- | timer3_init_normal(TIMER3_PRESCALE_8); | ||
- | |||
- | // Päästiku viik kõrgeks | ||
- | pin_set(trigger); | ||
- | |||
- | // Taimeri nullimine | ||
- | timer3_overflow_flag_clear(); | ||
- | timer3_set_value(0); | ||
- | |||
- | // ~10 us ootamine | ||
- | while (timer3_get_value() < 18) {} | ||
- | |||
- | // Päästiku viik madalaks | ||
- | pin_clear(trigger); | ||
- | |||
- | // Kaja signaali alguse ootamine | ||
- | while (!pin_get_value(echo)) | ||
- | { | ||
- | // Liiga kaua oodatud ? | ||
- | if (timer3_overflow_flag_is_set()) | ||
- | { | ||
- | return 0; | ||
- | } | ||
- | } | ||
- | |||
- | // Taimeri nullimine | ||
- | timer3_set_value(0); | ||
- | |||
- | // Kaja signaali lõpu ootamine | ||
- | while (pin_get_value(echo)) | ||
- | { | ||
- | // Liiga kaua oodatud ? | ||
- | if (timer3_overflow_flag_is_set()) | ||
- | { | ||
- | return 0; | ||
- | } | ||
- | } | ||
- | |||
- | // Mõõdetud aja kauguseks teisendamine | ||
- | // | ||
- | return (unsigned long)timer3_get_value() * | ||
- | ULTRASONIC_SPEED_OF_SOUND / (F_CPU / 4); | ||
- | } | ||
- | </ | ||
- | |||
- | Toodud funktsioon jätab päästiku ja kaja viigu kasutaja valida, nii et andurit saab ühendada sinna, kus on sobivam või kus on ruumi. Lisaks võimaldab viikude valiku vabadus funktsiooni kasutada ka mujal kui Kodulabori komplektis. Toodud funktsioon kuulub ka Kodulabori teeki, nii et seda ei pea oma programmi eraldi kirjutama. Peab aga arvestama, et Kodulabori teegis on see funktsioon jäigalt seotud Kodulabori Kontrollermooduli taktsagedusega 14,7456 Mhz ja muude taktsageduste puhul annaks funktsioon vale tulemuse. Muu taktsageduse korral tuleb see funktsioon ise oma programmmi kirjutada. Järgnevalt esitatud programmikood demonstreerib SRF04/SRF05 ultrahelianduri kasutamist Kodulabori teegiga. | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Kodulabori ultraheli kaugusanduri näidisprogramm. | ||
- | // Kauguse mõõtmise funktsioon on blokeeruv. | ||
- | // | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | |||
- | // | ||
- | // Ultraheli anduri viigud | ||
- | // | ||
- | pin pin_trigger = PIN(G, 1); | ||
- | pin pin_echo | ||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | unsigned short distance; | ||
- | char text[16]; | ||
- | |||
- | // LCD ekraani seadistamine | ||
- | lcd_alpha_init(LCD_ALPHA_DISP_ON); | ||
- | |||
- | // LCD ekraani puhastamine | ||
- | lcd_alpha_clear(); | ||
- | |||
- | // Programmi nimi | ||
- | lcd_alpha_write_string(" | ||
- | |||
- | // Väike paus | ||
- | sw_delay_ms(100); | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // Mõõtmine | ||
- | distance = ultrasonic_measure(pin_trigger, | ||
- | |||
- | // Mõõtmine õnnestus ? | ||
- | if (distance > 0) | ||
- | { | ||
- | // Kauguse tekstiks teisendamine | ||
- | sprintf(text, | ||
- | } | ||
- | // Mõõtmisel tekkis viga ? | ||
- | else | ||
- | { | ||
- | // Vea tekst | ||
- | sprintf(text, | ||
- | } | ||
- | |||
- | // Teksti kuvamine LCD teise rea alguses | ||
- | lcd_alpha_goto_xy(0, | ||
- | lcd_alpha_write_string(text); | ||
- | |||
- | // Väike paus | ||
- | sw_delay_ms(500); | ||
- | } | ||
- | } | ||
- | </ | ||
- | ==== Harjutusülesanded ==== | ||
- | |||
- | Eesmärgiks on koostada programm, mis täidab kirjeldatud ülesannet. | ||
- | |||
- | === Soojendusülesanne === | ||
- | |||
- | * Potentsiomeetri takistuse väärtus kuvatakse LCD-l oomides. Potentsiomeetri takistuse nimiväärtus on 5 kΩ. | ||
- | |||
- | === Algajale === | ||
- | |||
- | - Potentsiomeetri takistuse väärtus vahemikus (0...999 Ω) kuvatakse LCD-l oomides ja (1000...5000 Ω) kilo-oomides. Potentsiomeetri takistuse nimiväärtus on 5 kΩ. Tulemus näidata korrektsete ühikute ja sümbolitega. | ||
- | - Objekti kauguse mõõtmine. Infrapuna anduriga mõõdetakse objekti kaugust nupu S1 vajutamisel. Mõõtmise ajal vilgutatakse korraks kollast LED-i. Kui objekt on kaugemal kui 50 cm, süttib roheline LED, kui objekt on lähemal kui 50 cm, süttib punane LED. | ||
- | - Mõõdetakse objekti kaugust infrapuna anduriga ja tulemus kuvatakse kolme valgusdioodi (LED1...LED3) abil kahendkujul. Kauguse suurenemisel peab vastavalt kasvama ka kuvatav väärtus. Skaalaks võtta ligikaudu 1 bit = 1 dm. | ||
- | - NTC temperatuurianduri väärtus kuvatakse LCD-l kraadides. Nupu S2 abil saab muuta ühikuid: Kelvin (K), Fahrenheit (F) ja Celsius (C). Temperatuuri näidatakse korrektsete ühikute ja sümbolitega. | ||
- | - Kasutades valgustugevuse andurit, tuvastatakse järsk valgustugevuse muutus (laevalgustuse sisse-välja lülitamine). Kui muutus on järsk, alarmeeritakse sellest punase LED-i vilkumisega (5 sekundit). Kui valgustugevus muutub sujuvalt, näidatakse selle muutumise suunda. Roheline LED tähistab valgusetugevuse suurenemist ja kollane valgustugevuse vähenemist. | ||
- | |||
- | === Edasijõudnule === | ||
- | |||
- | - Andmesalvestaja. Pidevalt mõõdetakse kõigi analoogandurite väärtusi ja jooksvalt salvestatakse miinimum- ja maksimumväärtused. Nupuga S1 saab vahetada LCD-l kuvatava anduri infot. Kuvada tuleb anduri nimi (lühidalt) ja käesolev-, minimaalne- ning maksimaalne näit. Andurite vahetusjärjekord: | ||
- | - Kaugusmõõtur. Vajutades nupule S2, tehakse 10 järjestikulist mõõtmist ühe sekundi jooksul. Pärast mõõtmist kuvatakse mõõdetava objekti keskmine kaugus detsimeetrites 7-segmendilisel LED numberindikaatoril. Vajutades nupule S1, kuvatakse minimaalne mõõtetulemus, | ||
- | - Liikumise kiirus. Vastavalt objekti kauguse muutuse suurusele näidatakse seda LED-idel: aeglane muutus rohelise LED-iga, mõõdukas muutus kollase LED-iga ja kiire muutus punase LED-iga. Kiirust võib kuvada ka LCD ekraanil. | ||
- | - Automaatne mõõtepiirkond. Vastavalt jooksvale mõõtetulemusele leitakse minimaalne ja maksimaalne mõõdetav temperatuur ning vastavalt sellele piirkonnale skaleeritakse näitu numbrist 0 numbrini 9. Näit kuvatakse 7-segmendilisel numberindikaatoril. | ||
- | - Kombineerides infrapuna ja ultraheli kaugusanduri, | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === Kordamisküsimused === | ||
- | |||
- | - Mis on ATmega128 mikrokontrolleri analoog-digitaalmuunduri (ADC) täpsus? Milline on vähim sisendi pinge muutus, mida on võimalik mõõta? | ||
- | - Kaua võtab aega üks ADC muundamise protsess? Kuidas saab muuta muunduri töösagedust? | ||
- | - Milline on ADC sisendpinge piirkond? Kas ja kuidas on võimalik seda muuta? | ||
- | - Mis vahe on positiivse temperatuuri koefitsiendiga (PTC) ja negatiivse temperatuuri koefitsiendiga (NTC) termistoril? | ||
- | - Mis on pingejaguri eesmärk mõõteahelas? | ||
- | - Koostage pingejagur, mis võimaldaks ATmega128 mikrokontrolleriga kasutada analoogandurit, | ||
- | - Kui potentsiomeetri otstele lisada eraldi takistid ja rakendada neile pinge 5 V, siis millised peavad olema lisatakistite ja potentsiomeetri takistus, et pinget potentsiomeetri liuguril saaks reguleerida 1 V ja 2 V vahel (potentsiomeetrit servast-serva pöörates)? | ||
- | - Millised keskkonnaparameetrid mõjutavad ultraheli kaugusanduri tööd? Mil määral ja miks? | ||
- | - Milliseid valgustundlikke andureid võiks kasutada robootikaprojektis? | ||
- | - Kuidas mõõdetakse valguse abil veel kaugust peale triangulatsioonimeetodi? | ||
- | ===== Mootorid ===== | ||
- | |||
- | {{ : | ||
- | |||
- | Mootorid on täiturseadmed, | ||
- | |||
- | Elektrimootorite liigitamiseks on mitu erinevat viisi, kuid olulisim on mootorite jaotamine alalisvoolu ja vahelduvvoolu mootoriteks. Lisaks sellele saab elektrimootoreid liigitada harjadega ja harjadeta mootoriteks, | ||
- | ==== Alalisvoolumootor ==== | ||
- | |||
- | //Vajalikud teadmised: [HW] [[et: | ||
- | |||
- | === Teooria === | ||
- | |||
- | [{{ : | ||
- | |||
- | Püsimagnetiga alalisvoolumootorid on laialt levinud erinevates rakendustes, | ||
- | |||
- | [{{ : | ||
- | |||
- | Püsimagnetiga alalisvoolumootorid on lihtsa ehitusega ja elementaarse juhtimisega mootorid. Kuigi juhtimine on lihtne, ei ole nende pöörlemiskiirus üldjuhul täpselt juhtsignaaliga määratletav, | ||
- | |||
- | Harjadega alalisvoolumootorid töötavad alalispingel ning põhimõtteliselt ei vaja eraldi juhtelektroonikat, | ||
- | | ||
- | [{{ : | ||
- | |||
- | H-sillas tüürivad mootori pöörlemiseks vajalikku voolu neli transistori (või nende gruppi). H-silla elektriskeem meenutab H-tähte - sellest ka nimi. H-silla eripära seisneb mootorile mõlemat pidi polaarsuse rakendamise võimaluses. Kõrvaloleval pildil on toodud H-silla põhimõtteskeem lülitite näitel. Kui selles skeemis sulgeda kaks diagonaalis asetsevat lülitit, hakkab mootor tööle. Mootori pöörlemissuund sõltub aga sellest, kummas diagonaalis lülitid suletakse. Reaalses H-sillas on lülitite asemel muidugi transistorid, | ||
- | |||
- | H-sillaga saab peale pöörlemissuuna muuta ka mootori pöörlemiskiirust - selleks tuleb transistore pulsilaiusmodulatsiooniga (PWM) pidevalt avada ja sulgeda, nii et summaarne mootorile antav energia on midagi seismise ja täisvõimsuse vahepealset. Avatud aega kogu PWM perioodist nimetatakse ka töötsükliks (inglise keeles //duty cycle//), mida tähistatakse protsentidega. 0% tähendab, et transistor on pidevalt suletud, ehk ei juhi voolu, 100% tähendab, et transistor on pidevalt avatud, ehk juhib voolu. PWM sagedus peab olema piisavalt kõrge, et vältida mootorivõlli vibreerimist. Madalal sagedusel tekitab mootor lisaks ka müra ja seepärast kasutatakse enamasti üle 20 kHz moduleerimissagedust. Samas kannatab väga suurtel sagedustel H-silla efektiivsus. Mootorivõlli vibreerimist vähendavad ka rootori inerts ja mootori mähiste induktiivsus. | ||
- | |||
- | Väiksemate voolude juhtimiseks leiab H-sildu integreeritud komponendina ehk ajurina, suuremate voolude jaoks kasutatakse spetsiaalseid võimsustransistore (//Power MOSFET//). H-silda koos sinna kuuluva elektroonikaga nimetatakse ka mootorikontrolleriks. | ||
- | |||
- | Märkus: Mitte ajada segamini RC (raadiojuhitav servomootor) PWM signaali tavaliste PWM signaalidega. | ||
- | |||
- | === Praktika === | ||
- | |||
- | Kodulaboris kasutatav alalisvoolumootorite ajur L293D sisaldab endas kahte integreeritud H-silda ja kaitsedioode. Mootorit juhitakse kolme digitaalse signaaliga, millest üks on üldine tööd lubav signaal (inglise keeles // | ||
- | |||
- | Kodulabori Mootorite mooduli plaadil on võimalus kuni nelja alalisvoolumootori ühendamiseks. Skeemid ja ühendamise õpetuse leiab Mootorite mooduli peatükist. Sisuliselt on iga mootori jaoks H-sild, mida juhitakse kahe mikrokontrolleri digitaalse väljundviiguga, | ||
- | |||
- | ^ Sisend A ^ Sisend B ^ Väljund A ^ Väljund B ^ Tulemus | ||
- | | 0 | ||
- | | 1 | ||
- | | 1 | ||
- | | 0 | ||
- | |||
- | Alalisvoolumootoreid võib juhtida otse, manipuleerides mikrokontrolleri viikudega mootoriajuri sisendviike, | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Alalisvoolumootori kontrolleri viikude seadistus | ||
- | // | ||
- | static pin dcmotor_pins[4][2] = | ||
- | { | ||
- | { PIN(B, 7), PIN(B, 4) }, | ||
- | { PIN(D, 1), PIN(D, 0) }, | ||
- | { PIN(D, 7), PIN(D, 6) }, | ||
- | { PIN(D, 5), PIN(D, 4) } | ||
- | }; | ||
- | |||
- | // | ||
- | // Valitud alalisvoolumootori juhtimise lubamine | ||
- | // | ||
- | void dcmotor_init(unsigned char index) | ||
- | { | ||
- | pin_setup_output(dcmotor_pins[index][0]); | ||
- | pin_setup_output(dcmotor_pins[index][1]); | ||
- | } | ||
- | |||
- | // | ||
- | // Valitud alalisvoolumootori töötamise ja töötamise suuna määramine | ||
- | // | ||
- | void dcmotor_drive(unsigned char index, signed char direction) | ||
- | { | ||
- | pin_set_to(dcmotor_pins[index][0], | ||
- | pin_set_to(dcmotor_pins[index][1], | ||
- | } | ||
- | </ | ||
- | |||
- | Teegis defineeritakse // | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | Järgnevalt on toodud näidisprogramm, | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Kodulabori mootorite mooduli | ||
- | // alalisvoolumootori testprogramm | ||
- | // | ||
- | #include < | ||
- | #include < | ||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | // Suuna muutuja | ||
- | signed char direction = 1; | ||
- | |||
- | // Mootorite 0 ja 1 seadistamine | ||
- | dcmotor_init(0); | ||
- | dcmotor_init(1); | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // Üks mootor käib ühtepidi, teine teistpidi | ||
- | dcmotor_drive(0, | ||
- | dcmotor_drive(1, | ||
- | |||
- | // Paus 1 sekund | ||
- | sw_delay_ms(1000); | ||
- | |||
- | // Suuna ümberpööramine | ||
- | direction = -direction; | ||
- | } | ||
- | } | ||
- | </ | ||
- | ==== Servomootor ==== | ||
- | |||
- | //Vajalikud teadmised: [HW] [[et: | ||
- | |||
- | === Teooria === | ||
- | |||
- | [{{ : | ||
- | |||
- | [{{ : | ||
- | |||
- | RC (lühend, inglise keeles // | ||
- | |||
- | Servomootori juhtsignaaliks on spetsiifiline pulsilaiusmodulatsiooni (PWM) signaal, kus pulsi laius määrab ära rootori asendi. Signaali perioodiks on 20 ms (sagedus 50 Hz) ja kõrge poolperioodi laiuseks 1-2 ms. 1 ms tähistab rootori üht äärmist asendit ja 2 ms teist rootori äärmist asendit. 1,5 ms tähistab rootori keskasendit. | ||
- | |||
- | Traditsiooniline RC servomootor kannab ka analoog-servomootori nime. Põhjus on selles, et viimasel kümnendil tekkisid ka nii-öelda digitaalsed servomootorid. Nende kahe vahe seisneb selles, et analoog-servomootoris juhitakse mootorit sellesama 50 Hz PWM sisendsignaaliga, | ||
- | |||
- | ~~CL~~ | ||
- | ~~PB~~ | ||
- | |||
- | === Praktika === | ||
- | |||
- | Kodulabori Mootorite mooduli plaadil on kaks pistikut RC servomootorite ühendamiseks. Pistikute PWM signaali otsad on ühendatud mikrokontrolleri PB5 ja PB6 viikudega, mille alternatiivfunktsioonideks on 16-bitise taimer 1 võrdlusüksuste A ja B väljundid. Taimer 1 on võimeline raudvaraliselt tekitama PWM signaali ja seetõttu on mootorite juhtimine programmis väga lihtne. Keerulisem on ainult taimeri seadistamine. | ||
- | |||
- | Taimer 1 tuleb seadistada PWM signaali tekitamise režiimi, kus taimeri maksimaalne väärtus on määratud ICR registriga. Taimeri taktijaguri ja programmis muudetava maksimaalse väärtusega saab täpselt ära määrata servomootori juhtimiseks vajaliku PWM signaali sageduse. Taimeri võrdlusregistriga saab määrata kummagi PWM signaali kõrge poolperioodi pikkuse. Taimeritel on nimelt spetsiaalsed võrdlusüksused, | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Taimeri väärtus PWM täisperioodi (20 ms) saavutamiseks. | ||
- | // F_CPU on mikrokontrolleri taktsagedus, | ||
- | // ja 50 hertsiga. | ||
- | // | ||
- | #define PWM_PERIOD | ||
- | |||
- | // | ||
- | // PWM servo keskasend (1,5 ms / 20 ms) | ||
- | // Keskasend saadakse täisperioodist 15/200 võtmisega | ||
- | // | ||
- | #define PWM_MIDDLE_POS | ||
- | |||
- | // | ||
- | // Kordamistegur, | ||
- | // +1 liidetakse selleks, et poolperiood kindlasti ulatuks 1 ja 2 ms | ||
- | // piiridesse või siis natuke üle. | ||
- | // | ||
- | #define PWM_RATIO | ||
- | |||
- | // | ||
- | // Viikude seadistus | ||
- | // | ||
- | static pin servo_pins[2] = | ||
- | { | ||
- | PIN(B, 5), PIN(B, 6) | ||
- | }; | ||
- | |||
- | // | ||
- | // Määratud servomootori tööks valmistamine. | ||
- | // | ||
- | void servomotor_init(unsigned char index) | ||
- | { | ||
- | // PWM signaali viik väljundiks | ||
- | pin_setup_output(servo_pins[index]); | ||
- | |||
- | |||
- | // Taimer 1 seadistamine | ||
- | // Taktijagur 8 | ||
- | // Kiire PWM režiim kus TOP = ICR | ||
- | // OUTA ja OUTB võrdusel madalaks | ||
- | timer1_init_fast_pwm( | ||
- | TIMER1_PRESCALE_8, | ||
- | TIMER1_FAST_PWM_TOP_ICR, | ||
- | TIMER1_FAST_PWM_OUTPUT_CLEAR_ON_MATCH, | ||
- | TIMER1_FAST_PWM_OUTPUT_CLEAR_ON_MATCH, | ||
- | TIMER1_FAST_PWM_OUTPUT_DISABLE); | ||
- | |||
- | // Perioodi määramine maksimaalse väärtuse kaudu | ||
- | timer1_set_input_capture_value(PWM_PERIOD); | ||
- | } | ||
- | |||
- | // | ||
- | // Servomootori positsiooni määramine | ||
- | // Positsiooni parameeter on -100 kuni 100 protsenti | ||
- | // | ||
- | void servomotor_position(unsigned char index, signed short position) | ||
- | { | ||
- | switch (index) | ||
- | { | ||
- | case 0: | ||
- | timer1_set_compare_match_unitA_value( | ||
- | PWM_MIDDLE_POS + position * PWM_RATIO); | ||
- | break; | ||
- | |||
- | case 1: | ||
- | timer1_set_compare_match_unitB_value( | ||
- | PWM_MIDDLE_POS + position * PWM_RATIO); | ||
- | break; | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | Näiteprogramm kasutab kirjeldatud Kodulabori teegi funktsioone. Programmi alguses pannakse esimese servomootori PWM signaali genereeriv taimer tööle // | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Kodulabori mootorite mooduli servomootori | ||
- | // testprogramm. | ||
- | // | ||
- | #include < | ||
- | #include < | ||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | short position; | ||
- | |||
- | // ADC seadistamine | ||
- | adc_init(ADC_REF_AVCC, | ||
- | |||
- | // Mootori seadistamine | ||
- | servomotor_init(0); | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // Potentsiomeetrist positsiooni lugemine ja servo- | ||
- | // mootori piirkonda teisendamine | ||
- | position = ((short)adc_get_value(3) - (short)512) / (short)5; | ||
- | |||
- | // Servomootori positsiooni määramine | ||
- | servomotor_position(0, | ||
- | } | ||
- | } | ||
- | </ | ||
- | ==== Samm-mootor ==== | ||
- | |||
- | //Vajalikud teadmised: [HW] [[et: | ||
- | |||
- | === Teooria === | ||
- | |||
- | [{{ : | ||
- | |||
- | Samm-mootoreid kasutatakse laialdaselt täpsust nõudvates rakendustes. Erinevalt alalisvoolumootorist puuduvad samm-mootoris harjad ja kommutaator - selleks on seal mitu eraldiseisvat mähist, mida kommuteeritakse välise elektroonikaga (ajuriga). Rootori pööramine toimub mähiseid sammhaaval kommuteerides, | ||
- | |||
- | * muutuva magnetilise takistusega (suur täpsus, madal pöördemoment, | ||
- | * püsimagnetiga (madal täpsus, kõrge pöördemoment, | ||
- | * hübriidne (suur täpsus, kõrge pöördemoment, | ||
- | |||
- | Muutuva magnetilise takistusega samm-mootorites on hambulised mähised ja hambuline rauast rootor. Suurim tõmbejõud tekib mõlema poole hammaste kattumisel. Püsimagnetiga samm-mootorites on, nagu nimigi ütleb, püsimagnet, | ||
- | |||
- | Sõltuvalt samm-mootori mudelist läheb mootori võlli ühe täispöörde (360 kraadi) tegemiseks vaja sadu kommuteerimissamme. Stabiilse ja sujuva liikumise tagamiseks kasutatakse sobivat juhtelektroonikat, | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | **Unipolaarne samm-mootor** | ||
- | |||
- | [{{ : | ||
- | |||
- | Unipolaarne samm-mootor on viie või kuue juhtmega. Vastavalt ajami skeemile käivitatakse korraga ainult üks neljandik mähistest. //Vcc// liinid on tavaliselt ühendatud mootori positiivse toitepingega. Mähiste otsad 1a, 1b, 2a, ja 2b ühendatakse kommuteerimisel läbi transistoride ainult maaga, mistõttu nende juhtelektroonika on suhteliselt lihtne. | ||
- | |||
- | **Bipolaarne samm-mootor** | ||
- | |||
- | [{{ : | ||
- | |||
- | Bipolaarne samm-mootor erineb unipolaarsest samm-mootorist selle poolest, et mähiste polaarsust muudetakse kommutatsiooni ajal. Korraga aktiveeritakse pooled mähised, mis tagab võrreldes unipolaarse samm-mootoritega suurema efektiivsuse. Bipolaarsetel samm-mootoritel on neli juhet, mis ühendatakse kõik eraldi poolsillaga. Kommuteerimisel rakendavad poolsillad mähiste otstele kas positiivset või negatiivset pinget. Unipolaarseid samm-mootoreid saab käivitada ka bipolaarse ajuri abil: selleks tuleb ühendada vaid mähiste liinid 1a, 1b, 2a ja 2b (//Vcc// jääb ühendamata). | ||
- | |||
- | Mõlemat liiki mähisega samm-mootori juhtimiseks vajalikku kommutatsiooni täissammu ja poolsammu režiimis kujutab järgnev tabel. Kuna unipolaarsete samm-mootorite ajurite puhul toimub vaid transistoride avamine, siis nende samme on kujutatud loogiliste arvudega 0 ja 1. Bipolaarse samm-mootori juhtimine võib vajada rohkem signaale, ja selle samme on kujutatud ajuri väljundite polaarsusega. | ||
- | |||
- | ^ ^ | ||
- | ^ Samm ^ 1A ^ 2A ^ 1B ^ 2B ^ 1A ^ 2A ^ 1B ^ 2B ^ | ||
- | ^ | ||
- | | 1 ^ 1 | 0 | 0 | 0 ^ + | - | - | - | | ||
- | | 2 | 0 ^ 1 | 0 | 0 | - ^ + | - | - | | ||
- | | 3 | 0 | 0 ^ 1 | 0 | - | - ^ + | - | | ||
- | | 4 | 0 | 0 | 0 ^ 1 | - | - | - ^ + | | ||
- | ^ | ||
- | | 1 ^ 1 | 0 | 0 | 0 ^ + | - | - | - | | ||
- | | 2 ^ 1 ^ 1 | 0 | 0 ^ + ^ + | - | - | | ||
- | | 3 | 0 ^ 1 | 0 | 0 | - ^ + | - | - | | ||
- | | 4 | 0 ^ 1 ^ 1 | 0 | - ^ + ^ + | - | | ||
- | | 5 | 0 | 0 ^ 1 | 0 | - | - ^ + | - | | ||
- | | 6 | 0 | 0 ^ 1 ^ 1 | - | - ^ + ^ + | | ||
- | | 7 | 0 | 0 | 0 ^ 1 | - | - | - ^ + | | ||
- | | 8 ^ 1 | 0 | 0 ^ 1 ^ + | - | - ^ + | | ||
- | |||
- | === Praktika === | ||
- | |||
- | Harjutuse eesmärk on tööle panna bipolaarne samm-mootor, | ||
- | |||
- | Bipolaarse samm-mootori juhtimiseks on Kodulabori teegis olemas funktsioon // | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Bipolaarse samm-mootori juhtimise ettevalmistamine | ||
- | // | ||
- | void bipolar_init(void) | ||
- | { | ||
- | DDRB |= 0x0F; | ||
- | PORTB &= 0xF0; | ||
- | } | ||
- | |||
- | // | ||
- | // Bipolaarse samm-mootori liigutamine poolsammudega | ||
- | // | ||
- | void bipolar_halfstep(signed char dir, | ||
- | unsigned short num_steps, unsigned char speed) | ||
- | { | ||
- | unsigned short i; | ||
- | unsigned char pattern, state1 = 0, state2 = 1; | ||
- | |||
- | // Suuna kindlustamine +- 1 | ||
- | dir = ((dir < 0) ? -1 : +1); | ||
- | |||
- | // Poolsammude teostamine | ||
- | for (i = 0; i < num_steps; i++) | ||
- | { | ||
- | state1 += dir; | ||
- | state2 += dir; | ||
- | |||
- | // Mustri loomine | ||
- | pattern = (1 << ((state1 % 8) >> 1)) | | ||
- | (1 << ((state2 % 8) >> 1)); | ||
- | |||
- | // Väljundi määramine | ||
- | PORTB = (PORTB & 0xF0) | (pattern & 0x0F); | ||
- | |||
- | // Pausi tegemine sammu teostamise ootamiseks | ||
- | sw_delay_ms(speed); | ||
- | } | ||
- | |||
- | // Mootori peatamine | ||
- | PORTB &= 0xF0; | ||
- | } | ||
- | </ | ||
- | |||
- | Funktsioonide kasutamist demonstreerib näiteprogramm, | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Kodulabori mootorite mooduli bipolaarse | ||
- | // samm-mootori testprogramm | ||
- | // | ||
- | #include < | ||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | // Mootori seadistamine | ||
- | bipolar_init(); | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // Pööramine ühele poole 200 poolsammu kiirusega 30 ms/samm | ||
- | bipolar_halfstep(+1, | ||
- | |||
- | // Pööramine teisele poole 200 poolsammu kiirusega 30 ms/samm | ||
- | bipolar_halfstep(-1, | ||
- | } | ||
- | } | ||
- | </ | ||
- | ==== Harjutusülesanded | ||
- | Eesmärgiks on koostada programm, mis täidab kirjeldatud ülesannet. | ||
- | |||
- | === Soojendusülesanne === | ||
- | |||
- | * Alalisvoolumootori juhtimine Digitaalmooduli plaadi nuppudega. Vajutades nupule S1 pöörleb mootor päripäeva. Vajutades nupule S3 pöörleb mootor vastupäeva. Vajutades nupule S2 mootor seisab. | ||
- | |||
- | === Algajale === | ||
- | |||
- | - Alalisvoolumootori juhtimine. Simuleeritakse alalisvoolumootori ja puuteandurite kasutamisega roboti liikumist. Puuteanduriteks on Digitaalmooduli nupud S1, S2 ja S3. Mootorit juhitakse nuppude allavajutamisega. S1 ja S2 eraldi vajutamisel peatab mootori kaheks sekundiks ning seejärel käivitab mootor uuesti. Kui mõlemad nupud on samaaegselt alla vajutatud, siis mootor seisab kuni nuppude vabastamiseni. (Robotil tuleks rakendada sarnast skeemi kahe eraldi mootori juhtimiseks). | ||
- | - Servomootor. Servomootorit juhitakse Digitaalmooduli plaadi nuppude abil. S1 allavajutamisel pöörleb servomootori hoob ühe sammu võrra vasakule, S3 allavajutamisel pöörleb servomootori hoob ühe sammu võrra paremale ning S2 allavajutamisel liigub hoob algasendisse (keskmine positsioon). Servomootori hoova asendit näidatakse sammudena 7-segmendilisel indikaatoril (keskmine asend on number 5). | ||
- | - Radar. Simuleeritakse infrapuna kaugusanduriga radari tööd. Andur tuleb paigaldada servomootori hoovale. Servomootori hoob koos anduriga liigub pidevalt ühest äärmisest asendist teise. Kui andurist lähemale kui 0,5 m ilmub objekt, peatatakse servomootor 5 sekundiks ning Kontrollermooduli plaadil oleva LED-i (PB7) abil antakse märku, et objekt on leitud. Peale 5 sekundilist LED-i vilgutamist jätkatakse skaneerimist. | ||
- | - Samm-mootor. Samm-mootor pöörleb iga nupule S1 ja S3 vajutamise järel 50 sammu, vastavalt päri- või vastupäeva. Nupp S2 katkestab pöörlemise viivitamatult. | ||
- | - Ühendatud on kõik kolm eri tüüpi mootorit. Nupule vajutus käivitab ja peatab vastava mootori. S1 juhib alalisvoolumootorit, | ||
- | |||
- | === Edasijõudnule === | ||
- | |||
- | - Alalisvoolumootor kiirendab S1 nupu allavajutamisel ning hoiab S1 nupu vabastamisel saavutatud kiirust. S2 nupu allavajutatud asendis hoidmise ajal mootor aeglustub sujuvalt. S3 allavajutamisel peatub mootor viivitamatult. Erineva kiiruse saab genereerides pulsilaiusmodulatsiooni signaali. | ||
- | - Objekti jälgimine. Kasutades ultraheli kaugusandurit, | ||
- | - Samm-mootoriga teha analoogkella sekundiosuti. Mootor peab ühe täispöördega täpselt 60 sammu tegema. Liikumine peab olema astmeline mitte sujuv. Kasutada tuleb pool- või mikrosammu. | ||
- | - Kiirendav samm-mootor. Programm võimaldab muuta samm-mootori kiirendamist/ | ||
- | - Koostage alalisvoolumootorile PID regulaator. NB! Harjutus vajab tagasisidega mootorit. Ülesande võib lahendada ka teoreetiliselt. | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === Kordamisküsimused === | ||
- | |||
- | - Milleks kasutatakse H-silda? Milline on selle tööprintsiip? | ||
- | - Kuidas on määratud RC servomootori võlli asend? | ||
- | - Milline on põhierinevus uni- ja bipolaarsete samm-mootorite vahel? | ||
- | - Kuidas rakendada samm-mootoris poolsamm- ja mikrosamm režiime? | ||
- | - Kuidas juhitakse alalisvoolumootori pöörlemiskiirust? | ||
- | - Millist pulsilaiusmodulatsiooni (PWM) töötsüklit on vaja, et saavutada alalisvoolumootori võlli pöörlemiskiiruseks 70% nominaalsest pöörlemiskiirusest? | ||
- | - Kuidas määratakse koodri kasutamisel mootori pöörlemissuund? | ||
- | - Kuidas saab alalisvoolumootorit elektriliselt pidurdada? | ||
- | - Mis juhtub, kui samm-mootori puhul on kommutatsioon liiga kiire? | ||
- | - Kas ja kuidas on võimalik kasutada dünaamilist pidurdamist? | ||
- | ===== Sideliidesed ===== | ||
- | |||
- | {{ : | ||
- | |||
- | Mikrokontrolleritega saab juhtida täitureid, lugeda andurite väärtusi ja teha mitmeid muid toiminguid, kuid alati jääb vajadus ühendada seadmeid, millega ei saa suhelda lihtsaid digitaalseid signaale edastades. Põhjuseks võib olla näiteks seadme juhtimiseks vajaminevate juhtsignaalide liiga suur arv või suur andmehulk. Seepärast on nii mikrokontrolleritele kui muule elektroonikale välja arendatud terve hulk erinevaid andmesideliideste standardeid. Standardid määravad ära signaalide elektrilised parameetrid ja nende signaalide edastamise reeglid ehk protokolli. | ||
- | |||
- | Üks lihtne näide protokollist on morse kood, kus infot edastatakse piiksude ja pausidega ning nende pikkustega. Sarnaselt toimivad ka digitaalsed andmesideprotokollid, | ||
- | ==== RS-232 ==== | ||
- | |||
- | //Vajalikud teadmised: [HW] [[et: | ||
- | |||
- | === Teooria === | ||
- | |||
- | [{{ : | ||
- | |||
- | RS-232 on füüsilise andmesideliidese standard, mida kasutatakse binaarandmete edastamiseks. Standard on kasutusel peamiselt arvutite jadaportides, | ||
- | |||
- | RS-232 liidest kasutatakse peamiselt koos UART nime kandva riistvaralise andmesidemooduliga, | ||
- | |||
- | UART on lahtitõlgituna " | ||
- | |||
- | [{{ : | ||
- | |||
- | Andmete edastamine toimub UART liideses kaadri (inglise keeles //frame//) kaupa, milles on andmebitte olenevalt seadistusest 5 kuni 9. Enamlevinud andmehulk on siiski 8 bitti, ehk 1 bait. Peale andmebittide edastatakse kaadriga ka lisabitte, mille abil toimub andmete saabumise ja lõppemise hetke äratundmine vastuvõtja poolel. Esimest neist nimetatakse startbitiks, | ||
- | |||
- | Peale kaadri struktuuri on veel üks tähtis parameeter - see on boodikiirus (inglise keeles //baud rate//), millega määratakse edastatavate sümbolite arv ühes sekundis. Bood näitab nimelt sümbolite arvu. UART puhul on 1 bood aga 1 bitt ja seepärast kaadri juures bittidest saigi räägitud. Põhimõtteliselt võib andmete edastamiseks kasutada ükskõik millist boodikiirust, | ||
- | |||
- | Lisainformatsioonina võiks teada, et RS-232 standard sisaldab peale andmesignaalide (RX, TX) veel andmevoo-kontrolli viike DTR, DCD, DSR, RI, RTS ja CTS, mida kasutatakse seadmetevahelise suhtluse juhtimiseks. Näiteks võib seade nende kaudu teada anda, kas ta on valmis andmeid vastu võtma või mitte. Kuna RS-232 liidese originaaleesmärk oli ühendada arvuteid modemiga, siis mõned signaalid on (pigem olid) kasutusel telefoniliini seisundi näitamiseks. | ||
- | |||
- | === Praktika === | ||
- | |||
- | Kodulabori Kontrollermooduli plaadil on RS-232 isa-tüüpi pesa. Selle kaudu saab kontrolleri arvutiga või teise kontrolleriga ühendada. Arvutiga ühendamiseks tuleb kasutada tavalist pööramata kaablit, mille üks pistik on ema-tüüpi, | ||
- | |||
- | <code c> | ||
- | // | ||
- | // Kodulabori Kontrollerimooduli arvutiga RS-232 kaudu liidestamine. | ||
- | // Näide kasutab Digitaalset sisend-väljundmoodulit koos LCD ekraaniga. | ||
- | // Arvuti terminalis sisestatud tekst kuvatakse LCD-l. | ||
- | // | ||
- | #include < | ||
- | #include < | ||
- | |||
- | // | ||
- | // USART liidese määramine | ||
- | // | ||
- | usart port = USART(0); | ||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | char c; | ||
- | unsigned char row = 1; | ||
- | |||
- | // USART liidese seadistamine | ||
- | usart_init_async(port, | ||
- | USART_DATABITS_8, | ||
- | USART_STOPBITS_ONE, | ||
- | USART_PARITY_NONE, | ||
- | USART_BAUDRATE_ASYNC(9600)); | ||
- | |||
- | // LCD ekraani seadistamine | ||
- | lcd_alpha_init(LCD_ALPHA_DISP_ON_BLINK); | ||
- | |||
- | // Ekraanil tervituse ütlemine | ||
- | lcd_alpha_write_string(" | ||
- | |||
- | // Kursori teise rea algusesse viimine | ||
- | lcd_alpha_goto_xy(0, | ||
- | |||
- | // Arvutile tere ütlemine | ||
- | usart_send_string(port, | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // Jadaliidesest märgi lugemine | ||
- | if (usart_try_read_char(port, | ||
- | { | ||
- | // Kas tegu on reavahetuse märgiga? | ||
- | if (c = ' | ||
- | { | ||
- | // Rea vahetamine | ||
- | row = 1 - row; | ||
- | |||
- | // Rea tühjendamine eelmisest teatest | ||
- | lcd_alpha_clear_line(row); | ||
- | } | ||
- | else | ||
- | { | ||
- | // Märgi otse ekraanile väljastamine | ||
- | lcd_alpha_write_char(c); | ||
- | } | ||
- | } | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | [{{ : | ||
- | |||
- | Windows XP operatsioonisüsteemiga on kaasas programm HyperTerminal. See avaneb //Start// menüüst // | ||
- | ==== Harjutusülesanded | ||
- | |||
- | Eesmärgiks on koostada programm, mis täidab kirjeldatud ülesannet. | ||
- | |||
- | === Soojendusülesanne === | ||
- | |||
- | * Saadetakse arvutile kord sekundis järjest suurenevat numbrit. Number peab olema teksti kujul ja lõppema reavahetusmärgiga (\n). | ||
- | |||
- | === Algajale === | ||
- | |||
- | - Oodatakse arvutilt RS-232 liidese kaudu käsklusi (tähemärke). Käsk ' | ||
- | - Nupule vajutades saadetakse arvutisse RS-232 liidese kaudu vastava nupu nimi (S1, S2, S3). | ||
- | |||
- | === Edasijõudnule === | ||
- | |||
- | - Kahe Kontrollermooduli RS-232 vaheline suhtlus. Nupule vajutades saadab kontroller nupu numbri. Numbri saabumisel muudetakse vastava LED-i olekut. ' | ||
- | - Teha " | ||
- | |||
- | === Kordamisküsimused === | ||
- | |||
- | - Kirjelda UART kaadrit. | ||
- | - Mis asi on boodikiirus? | ||
- | - Mis vahe on täis- ja poolduplekssidel? | ||
- | - Leida vähemalt 3 erinevat andurit, mis kasutavad jadaliidest. | ||
- | - Mis vahe on UART ja USART liidestel? Kumb on kiirem? | ||
- | - Kuidas töötab SPI liides? | ||
- | - Nimetage liideseid, mis võimaldavad ühele siinile ühendada vähemalt 100 seadet. | ||
- | - Loetlege erinevaid topoloogiaid ja selgitage nende erinevusi. | ||
- | - Mis pingenivool toimivad RS-232 ja UART ühendused? | ||
- | - Kui palju aega kulub 1 MiB edastamiseks boodikiirusel 9600 bps, kui andmebitte on 8, stoppbitte 1 ja paarsuse kontroll puudub? | ||
- | ====== Näidisprojekt ====== | ||
- | |||
- | {{: | ||
- | |||
- | Näidisprojektis üritatakse tuua konkreetsed juhised, kuidas koostada projekti dokumentatsiooni, | ||
- | ===== Dokumentatsioon ===== | ||
- | |||
- | Lihtsa mehhatroonikaseadme koostamisel on vaja projekteerida seadme konstruktsioon ja mehaanika, elektroonika ja sensoorika ning juhtimine ja tarkvara. | ||
- | Projektide lõppemisel tuleks koostada töö aruanne - dokumentatsioon, | ||
- | |||
- | * **Tiitelleht** | ||
- | * **Lühikokkuvõte** | ||
- | * **Lühikokkuvõte (võõrkeeles)** | ||
- | * **Sisukord** | ||
- | - **Lähteülesanne** | ||
- | - **Nõuded ja piirangud süsteemile** | ||
- | - **Süsteemi üldine mudel** \\ Süsteemi struktuuri ja funktsionaalsuse mudelid plokkdiagrammidena. Lisaks võib koostada kasutusjuhtude diagrammi, liideste diagrammi jms. | ||
- | - **Ideelahendused** \\ Vähemalt kolm erinevat kontseptuaalset lahendust, kuidas antud ülesanne lahendada. Sobivad täiesti skaneeritud käsitsi visandatud skeemid, visandid jms. dokumentatsioon koos kommentaaridega. | ||
- | - **Mehaanika** \\ Soovitatavalt 3D mudel koos oluliste sõlmede tööjooniste ja valmistamisjuhistega. Kui mingi sõlm nõuab erijuhiseid koostamiseks, | ||
- | - **Elektroonika** \\ Üldine plokkskeem, kus on näidatud kasutatavad moodulid (nn. kontroller, mootori ajur, mootor, kooder jne., ning nendevahelised ühendused). Võimalusel standardne elektroonikaskeem ja trükkplaadi montaažiskeem. | ||
- | - **Juhtimine** \\ Juhtimise algoritm ja algkood. Kui on kasutatud omaloodud funktsioone, | ||
- | - **Valmislahendus** \\ Kirjeldus ja pildid | ||
- | - **Majanduskalkulatsioonid** \\ Komponentide nimekiri koos maksumusega, | ||
- | - **Projektijuhtimine** \\ Projekti ajakava, ressursside jaotus, tööjaotus, | ||
- | - **Kokkuvõte ja järeldused** \\ Mis oli keeruline, mida teeks edaspidi teisiti, mida projekt andis jne. Kokkuvõttes kirjeldatakse lühidalt tehtud tööd, esinenud probleeme ja lõpptulemuse kirjeldust. Samuti on kokkuvõttesse hea lisada oma arvamus projekti vajalikkusest, | ||
- | * **Viited ja kasutatud materjal** | ||
- | * **Lisad** | ||
- | |||
- | Järgnevalt on esitatud näiteprojekt, | ||
- | ===== Liikurroboti platvorm ===== | ||
- | |||
- | Liikurrobot (mobiilne robot) on üks tüüpilisemaid roboteid, mida soovitakse ehitada. Väga populaarsed on sumorobotid, | ||
- | |||
- | Alljärgnevalt vaatame ühte tüüpilist liikurroboti platvormi projekti dokumentatsiooni ja selle projekteerimise erinevaid etappe. | ||
- | |||
- | === Lähteülesanne === | ||
- | |||
- | Projekteerida ja valmistada Kodulabori komponentide baasil multifunktsionaalne liikurroboti platvorm koos baasnavigatsiooni funktsionaalsusega. Robotplatvorm peab võimaldama lihtsalt muuta tema operatiivfunktsionaalsust, | ||
- | * Manipulaator | ||
- | * Radar | ||
- | * Kaamera | ||
- | Robot peab olema võimeline liikuma tasasel pinnal sisetingimustes. | ||
- | |||
- | == Nõuded == | ||
- | |||
- | * Maksimaalsed gabariidid: 20 cm x 20 cm x 20 cm | ||
- | * Maksimaalne kaal 2 kg | ||
- | * Liikumiskiirus max. 0,2 m/s | ||
- | * Täisautonoomne | ||
- | |||
- | == Piirangud projekteerimisele == | ||
- | |||
- | * Peab olema koostatud valdavalt Kodulabori komponentidest | ||
- | * Ei tohi ületada maksumust 10 000 krooni | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === Süsteemi üldine mudel === | ||
- | |||
- | Süsteemi üldine mudel on esitatud plokkdiagrammidena. Süsteemi mudel kirjeldab süsteemi struktuuri, käitumist jt. olulisi aspekte. Alljärgnevalt on näiteks toodud süsteemi struktuuri üldine hierarhiline mudel. | ||
- | |||
- | [{{ : | ||
- | |||
- | === Ideelahendused === | ||
- | |||
- | Antud ülesande lahenduseks kasutas meeskond ajurünnaku metoodikat ja genereeris 3 põhimõtteliselt erinevat lahendust. Koostati hindamismaatriks, | ||
- | |||
- | [{{ : | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | Lihtsustatud hindamismaatriks oli järgmine: | ||
- | |||
- | ^ Funktsioon/ | ||
- | |Maksumus | 3 | 4 | 6 | 0,8 | | ||
- | |Valmistamise keerukus | 2 | 4 | 7 | 0,7 | | ||
- | |Manööverdamisvõime | 4 | 8 | 8 | 0,5 | | ||
- | |Läbivus | 5 | 8 | 2 | 0,3 | | ||
- | |Kodulabori rakendatavus | 5 | 4 | 5 | 0,9 | | ||
- | |Kaal | 5 | 6 | 7 | 0,8 | | ||
- | ^Kokku (koos kaaluteguriga) ^ 19^27^ 28^ ^ | ||
- | |||
- | Hindamisskaala oli 1-10 punkti ja kaalutegur 0-1. Kaalutegurid olid valitud lähtuvalt süsteemile esitatud nõuetest ja piirangutest. Kuigi näiteks lahendus 2 oli oluliselt võimekam raskel maastikul liikumisel, ei olnud seda lähteülesandes nõutud ja vastava funktsionaalsuse kaalutegur oli sellest tulenevalt madal. | ||
- | |||
- | Hindamise tulemusena osutus antud ülesande optimaalseimaks lahenduseks ratastel liikuv kahe eraldi mootoriga platvorm. Edasine töö jätkus valitud lahenduse edasiarendusega reaalseks süsteemiks. | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === Mehaanika === | ||
- | |||
- | Mehaanika püüti valmistada võimalikult lihtne, järgides samal ajal modulaarsuse põhimõtet. Esimene ja tagumine põrkeraud on identsed moodulid. Elektroonika osas on kasutatud kolme moodulit, mis on paigutatud üksteise peale, võimaldades nii lihtsaid ribakaabelühendusi ja tagades samal ajal moodulite suhteliselt lihtsa vahetatavuse. Mootoriteks on valitud Kodulabori komplektis olevad integreeritud reduktori ja koodriga mootorid, mis on ühendatud otse mootorite ajurplaadiga. Ratasteks on kasutatud mudellennuki rattaid, mis on väga kerged ja piisavalt tugevad antud roboti jaoks. Valmistamise lihtsuse huvides on roboti alusplaat ja pealmine plaat identsed. Plaadid on varustatud avadega, võimaldades nii pealmisele plaadile kinnitada erinevaid seadmeid. Kahe plaadi vahele mahub lisaks elektroonikamoodulitele ka aku. | ||
- | |||
- | [{{ : | ||
- | |||
- | Eraldi on projekteeritud roboti põrkeraud, mis on integreeritud puute- ja joonejälgimise anduritega. Põrkerauad on valmistatud trükiplaatidest, | ||
- | |||
- | [{{ : | ||
- | |||
- | === Elektroonika === | ||
- | |||
- | Süsteemi elektroonika on kirjeldatud põhimõttelahendusena ja klassikalise elektriskeemina koos trükiplaadi montaažiskeemina. | ||
- | |||
- | [{{ : | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | Näitena on toodud roboti põrkeraua joonejälgimise andurite elektriskeem ja vastava trükiplaadi (PCB) montaažiskeemiga. | ||
- | |||
- | [{{ : | ||
- | |||
- | [{{ : | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === Juhtimine === | ||
- | |||
- | Roboti juhtimine tuleneb süsteemi käitumismudelist ja on määratud lähteülesande funktsionaalsusega ning nõuete ja piirangutega. Süsteemi käitumismudelist luuakse täpsustatud juhtprogrammi algoritm, millest omakorda lähtutakse tarkvara programmikoodi koostamisel. Kõik kolm taset (käitumismudel-algoritm-lähtekood) peavad olema omavahel kooskõlas. | ||
- | |||
- | == Algoritm == | ||
- | |||
- | Algoritm kirjeldab süsteemi juhtloogikat ja on esitatud plokkdiagrammina. Lihtsama algoritmi koostamiseks piisab paarist elemendist ja nendevaheliste seoste kirjeldamisest. Kui roboti algoritm on koostatud korrektselt, | ||
- | Algoritmis on kasutatud põhiliselt kahte erinevat objekti: ümardatud nurkadega ristkülik, mis tähistab mingit tegevust ja väike romb mingi tingimuse kontrollimiseks, | ||
- | |||
- | Algoritmis kasutatud tähiste tähendused: | ||
- | |||
- | ^Tähis^Tähendus^0^1^-1^ | ||
- | |M1|vasak mootor|seisab|pöörleb päripäeva|pöörleb vastupäeva| | ||
- | |M2|parem mootor|seisab|pöörleb päripäeva|pöörleb vastupäeva| | ||
- | |F|esimene keskmine puuteandur|signaal puudub|signaal olemas| | | ||
- | |FR|esimene parem puuteandur|signaal puudub|signaal olemas | | | ||
- | |FL|esimene vasak puuteandur|signaal puudub|signaal olemas | | | ||
- | |d|viide| | | | | ||
- | |||
- | [{{ : | ||
- | |||
- | == Lähtekood == | ||
- | |||
- | Lihtne navigeerimine | ||
- | <code c> | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | |||
- | // Põrkeandurite viikude defineerimine | ||
- | pin front = PIN(C, 0); | ||
- | pin frontleft | ||
- | pin frontright = PIN(C, 2); | ||
- | |||
- | // | ||
- | // Põhiprogramm | ||
- | // | ||
- | int main(void) | ||
- | { | ||
- | // Mootorite 0 ja 1 algseadistamine | ||
- | dcmotor_init(0); | ||
- | dcmotor_init(1); | ||
- | |||
- | // Andurite viigud sisendiks | ||
- | pin_setup_input_with_pullup(front); | ||
- | pin_setup_input_with_pullup(frontleft); | ||
- | pin_setup_input_with_pullup(frontright); | ||
- | |||
- | // Lõputu tsükkel | ||
- | while (true) | ||
- | { | ||
- | // Mootorite päripäeva käivitamine | ||
- | dcmotor_drive(0, | ||
- | dcmotor_drive(1, | ||
- | | ||
- | // Keskmise anduri signaali kontroll | ||
- | if (pin_get_value(front)) | ||
- | { | ||
- | // Mootorite reverseerimine | ||
- | dcmotor_drive(0, | ||
- | dcmotor_drive(1, | ||
- | |||
- | // Paus 1 sekund | ||
- | sw_delay_ms(1000); | ||
- | |||
- | // Vasaku mootori päripäeva käivitamine | ||
- | dcmotor_drive(0, | ||
- | |||
- | // Paus 2 sekundit | ||
- | sw_delay_ms(2000); | ||
- | } | ||
- | |||
- | // Vasaku anduri signaali kontroll | ||
- | else if (pin_get_value(frontleft)) | ||
- | { | ||
- | // Parema mootori reverseerimine | ||
- | dcmotor_drive(1, | ||
- | |||
- | // Paus 2 sekundit | ||
- | sw_delay_ms(2000); | ||
- | } | ||
- | |||
- | // Parema anduri signaali kontroll | ||
- | else if (pin_get_value(frontright)) | ||
- | { | ||
- | // Vasaku mootori reverseerimine | ||
- | dcmotor_drive(0, | ||
- | |||
- | // Paus 2 sekundit | ||
- | sw_delay_ms(2000); | ||
- | } | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === Valmislahendus === | ||
- | |||
- | Projekti raames valminud robotplatvorm on valmistatud üldjoontes plastikust, välja arvatud mootori kinnitused, mis on valmistatud alumiiniumprofiilist. Elektroonikamoodulid on paigutatud üksteise peale, aku on lahtiselt kahe plaadi vahel. Põrkerauad on valmistatud trükkplaadist ja värvitud mustaks. Roboti pealmine plaat on täiesti sile, võimaldades sinna kinnitada erinevaid soovitud seadmeid. Projekti raames paigaldati robotplatvormile lihtne radar, mis koosnes väikesest RC servomootorist ja infrapunaandurist. Teise lahendusena paigaldati platvormile intelligentne kaameramoodul masinnägemise ülesannete lahendamiseks. Mõlemad variandid on näidatud allolevatel piltidel. Kolmandaks seadmeks katsetati standardmanipulaatorit, | ||
- | |||
- | [{{ : | ||
- | [{{ : | ||
- | |||
- | ~~PB~~ | ||
- | |||
- | === Majanduskalkulatsioon === | ||
- | |||
- | Majanduslik kalkulatsioon hõlmab endas komponentide maksumust ja roboti detailide valmistamise ning koostamise kulusid. | ||
- | |||
- | Komponentide maksumuse tabel | ||
- | |||
- | ^Komponent^Mark^Kogus^Hind^Maksumus^ | ||
- | |Mootor|M LE149.6.43|2|500.-|1000.-| | ||
- | |Mikrokontroller|uC ATmega128|1|900.-|900.-| | ||
- | |Mootorite juhtplaat|Actuator Board v1.2|1|700.-|700.-| | ||
- | |Toiteplaat|TP|1|500.-|500.-| | ||
- | |Joonejälgimise andurid|LFS QRD1114|8|30.-|240.-| | ||
- | |Puuteandurid|TS Microswitch|8|25.-|200.-| | ||
- | |Kere plaat|ABS |4|50.-|200.-| | ||
- | |Trükiplaadi toorik| |2|50.-|100.-| | ||
- | |Mootorikinnituse profiil|Al-L |2|10.-|20.-| | ||
- | |Ratas|60/ | ||
- | |Aku|NI-MH 9,6 V|1|350.-|350.-| | ||
- | |Erinevad kaablid| |10|20.-|200.-| | ||
- | |Mutrid-poldid| |1|50.-|50.-| | ||
- | |Muud tarvikud| |1|100.-|100.-| | ||
- | ^ Kokku ^ ^ ^ ^ 4620.- ^ | ||
- | |||
- | Hinnanguline tööjõu- ja tootmiskulu üksikeksemplari korral. | ||
- | |||
- | ^Töö^Aeg (h)^Hind^Maksumus^ | ||
- | |Konstruktsioonidetailide freesimine|1|300.-|300.-| | ||
- | |Trükiplaatide (põrkerauad) freesimine|0, | ||
- | |Roboti konstruktsiooni koostamine|0, | ||
- | |Põrkeraudade koostamine (komponentide jootmine)|1|300.-|300.-| | ||
- | |Programmeerimine|5|300.-|1500.-| | ||
- | |Dokumentatsiooni koostamine|3|250.-|750.-| | ||
- | ^Kokku^ 11 ^ ^ 3225.- ^ | ||
- | |||
- | Roboti hinnanguline maksumus kokku **7845.-** | ||
- | |||
- | Arvutatud roboti maksumus on siiski hinnanguline, | ||
- | |||
- | === Projektijuhtimine === | ||
- | |||
- | Mehhatroonikasüsteem (Robot) on loodud meeskonnatööna ja kindla ajakava ning eelarvega, omades seega enamuse olulisi projekti tunnuseid. Projektijuhtimise seisukohalt olid olulised tegevused: aja planeerimine, | ||
- | |||
- | [{{ : | ||
- | |||
- | === Kokkuvõte ja järeldused === | ||
- | |||
- | Majanduslik kalkulatsioon näitas meile, et roboti tootmishind on üsna kõrge, eriti kui tegemist on ainueksemplariga, | ||
- | |||
- | Töö lõpus selgus tõsiasi, et roboti korralikuks töötamiseks on vaja oluliselt rohkem aega planeerida testimisele, | ||
- | |||
- | Kokkuvõteks arvame, et projekt oli väga huvitav ja hariv ning andis aimu integreeritud süsteemide projekteerimisest ja valmistamisest. | ||
- | |||
- | === Viited ja kasutatud materjalid === | ||
- | |||
- | - Kodulabori juhendmaterjal http:// | ||
- | - ATmega128 andmeleht | ||
- | - Dudziak, R., Köhn, C., Sell, R., Integrated Systems & Design, TUT Press, 2008 | ||
- | - Friendenthal, | ||
- | - Perens, A. Projektijuhtimine, | ||
- | - Bräunl, T. Embedded Robotics, Springer-Verlag, | ||
- | ====== Mis edasi? ====== | ||
- | |||
- | Kui oled jõudnud selle raamatuga lõpule, on sul juba päris palju praktilisi oskusi nii programmeerimise kui ka erinevate seadmete kasutamise osas. Kui oled näiteid ja harjutusi kasutanud valikuliselt, | ||
- | |||
- | Kui jääd hätta, küsi abi. See raamat ei ole lõplik ja areneb edasi elektroonilises versioonis. Raamat on üks osa robootika õppimise kontseptsioonist, | ||
- | |||
- | **Õpetajale: | ||
- | |||
- | {{ : | ||
- | |||
- | Veebikeskkond asub aadressil \\ | ||
- | http:// | ||
- | |||
- | ====== MÄRKUSED ====== | ||
- | |||
- | |||
- | ~~PB~~ | ||
- | |||
- | {{: | ||
- | {{: | ||
- | info@ittgroup.ee | ||
- | |||
- | Mikrokontrollerite arendusplaadid, | ||
- | KÕIK VAJALIK HOBIROBOOTIKAKS e-poest http:// | ||
- | |||
- | Arduino, Mikrovega, Devantech Ltd (Robot Electronics) ametlik esindaja Eestis. | ||
- | |||