====== Projekt 3 Alfabeetiline LCD ====== Ühendada Arduino plaadiga LCD laiendusplaat. Laiendusplaat toimib Arduino peal ainult ühte pidi. Õige ühenduse korral on kõik laiendusplaadi jalad Arduino plaadiga kontaktis ja plaadi serv on Arduino plaadi USB pesa poolt üle ääre. ===== Näide #3.1 LCD ekraanile kirjutamine ===== Ekraanile kirjutamiseks vajalikud tähemärgid on LCD draiveri mälus juba olemas ja nende kuvamiseks on vaja saata ASCII tabelile vastav number. Lihtsuse mõttes teeb teek "LiquidCrystal" selle töö juba kasutaja eest ära ja ekraanile kirjutamine ei ole keerulisem kui jadaporti teksti kirjutamine. Lisaks LCD-le kirjutamisele tuleb aeg-ajalt muuta ka kursori asukohta, mida saab teha //setCursor(veerg, rida)// käsuga.\\ Näiteprogramm alustab ekraani seadistamisega. Määrame ära ühendusviigud ja ekraani suuruse, mis on tarvilik ekraani korrektseks funktsioneerimiseks. Järgnevalt trükime ekraanile tervitusteksti, mis jääb püsivalt ülemisele reale alles. Teisele reale liigume käsuga //setCursor// ning kirjutame sinna programmi töötamise aja sekundites. Kuna pärast tähemärkidele kirjutamist liigub kursor automaatselt edasi, siis tuleb pärast igat tsükli läbimist ka kursori positsioon uuesti algusesse liigutada. Kui käesolevale tähemärgile ekraanil on juba midagi trükitud, siis uue tähemärgi samale kohale trükkimisel kustutatakse eelnev tähemärk automaatselt ära.\\ Täpsemalt teegi "LiquidCrystal" toetatud käskudest leiab siit: https://www.arduino.cc/en/Reference/LiquidCrystal /* Nimetus: Näide #3.1 Kirjeldus: LCD ekraanile kirjutamine */ // Vajaliku teegi kaasamine #include // LCD objekti tekitamine ja ühendusviikude määramine. // NB! Need viigud võivad olla erinevatel LCD laiendusplaatidel erinevad LiquidCrystal lcd(8, 9, 4, 5, 6, 7); void setup() { // LCD ridade ja veergude määramine vastavalt riistvarale lcd.begin(16, 2); // Ekraani tervitusteksti kuvamine lcd.print("Tere Tallinn!"); } void loop() { // Kursori asukohta muutmine: esimene veerg(tähis 0) ja teine rida (tähis 1) lcd.setCursor(0, 1); // Ekraani loenduri väärtuse kuvamine lcd.print(millis()/1000); } ===== Näide #3.2 Erikujuliste tähemärkide kuvamine LCD ekraanil ===== Käesoleva LCD draiver võimaldab lisaks ASCII tabeli tähemärkidele lisada ka erikujulisi tähemärke. Tähemärgi lisamiseks on vaja tekitada ühe tähemärgi pikslite arvule vastav massiiv. Selle massiiviga määratakse ära tähemärgi aktiivsed pikslid. Pärast tähemärgi ekraani draiveri mällu laadimist käsuga //createChar(id_nr, massiiv)//, on see püsivalt ekraani mälus, kuni see kirjutatakse kasutaja poolt üle uue tähemärgiga. Tähemärk säilib mälus ka pärast toite lahti ühendamist. Tähemärgi kuvamine toimub käsuga //write(tähemärgi_nr)//. Näiteprogrammis sulgudes olev //uint8_t// on vajalik muutuja tüübi konverteerimiseks ekraanile sobilikuks. Kuna draiveri mälu on piiratud, siis maksimaalselt saab tekitada 8 erikujulist tähemärki. /* Nimetus: Näide #3.2 Kirjeldus: Erikujuliste tähemärkide tekitamine ja kuvamine LCD ekraanil */ // Vajaliku teegi kaasamine #include // LCD objekti tekitamine ja ühendusviikude määramine LiquidCrystal lcd(8, 9, 4, 5, 6, 7); /* Massiiv erikujulise tähemärgi tekitamiseks, "0b" numbrite ees ütleb kompilaatorile, et tegemist on kahendsüsteemis arvuga. Kahendsüsteemi arvude kasutamisel tekib parem arusaam kuvatavate pikslite asukohtadest. */ byte customChar[8] = { 0b11111, 0b00000, 0b01010, 0b00000, 0b10001, 0b01110, 0b00000, 0b11111 }; void setup() { // Tekitab uue erikujulise tähemärgi draiveri mällu kohale 0 lcd.createChar(0, customChar); // LCD ridade ja veergude määramine vastavalt riistvarale lcd.begin(16, 2); // Draiveri mälus kohal 0 oleva erikujulise tähemärgi kuvamine ekraanile lcd.write((uint8_t)0); } void loop() { /* Tsüklis ei tehta midagi kogu tegevus on sooritatud juba //setup// funktsioonis */ } ===== Näide #3.3 LCD laiendusplaadi nuppude lugemine ===== Järgnevas näites võtame kasutusele LCD laiendusplaadil olevad nupud. Programmi tööpõhimõtte mõistmiseks on soovitav tutvuda nuppude ühendusskeemiga 6. peatüki alguses. Nimelt kasutame nuppude lugemiseks eelnevast peatükist tuttavat //analogRead// käsku. Iga nupu vajutamisel saame erineva analoogväärtuse, mida kasutame ära, et tuvastada vajutatud nupp. Mitme nupu samaaegsel vajutamisel programm eelistab väiksema väärtusega nuppu.\\ Programm alustab sarnaselt eelnevatele näidetele LCD seadistustega. Loetavuse parendamiseks tekitame konstandid iga nupu jaoks. Peatsükli (loop) koodi ridade arvu vähendamiseks loome uue funktsiooni nimega //kontrolliNuppe//. Kutsume seda välja võimalikult tihedalt, et ükski nupu vajutus ei jääks mikrokontrolleril märkamata. Kui ühtegi nuppu pole vajutatud, siis tagastab funktsioon alati konstandi "nuppNone". See tuleneb, sellest, et tavaolekus on analoogsisendi peal //pull-up// takisti ja seetõttu on analoogsisendi väärtus suurem kui 790. Tuvastanud nupu vajutuse, kuvab programm saadud analoogsisendi väärtuse ekraanile. Lisaks on programmi lisatud käsk //clear//, mis on vajalik, et uue väärtuse kuvamisel ei jääks ükski number vanast väärtusest ekraanile näha. Vastasel juhul näiteks väärtuse 783 üle kirjutamisel väärtusega 50 jääks eelmisest väärtusest kolmanda positsiooni number 3 ikka veel ekraanile ja tekitab seetõttu arusaama nagu oleks tegelik väärtus 503. /* Nimetus: Näide #3.3 Kirjeldus: LCD laiendusplaadi nuppude lugemine */ // Vajaliku teegi kaasamine #include // LCD objekti tekitamine ja ühendusviikude määramine LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // Nupude konstandi defineerimine const int nuppRIGHT = 0; const int nuppUP = 1; const int nuppDOWN = 2; const int nuppLEFT = 3; const int nuppSELECT = 4; const int nuppNONE = 5; /* Globaalsed muutujad */ // Vajutatud nupu muutuja konstandi salvestamine int vajutatudNupp; // Aanaloogsisendi muutuja väärtuse salvestamine int nupuSisend; void setup() { // LCD ridade ja veergude määramine vastavalt riistvarale lcd.begin(16, 2); // Ekraani info kuvamine lcd.print("ADC: "); // Ekraani analoogsisendi A0 väärtuse kuvamine lcd.print(analogRead(A0)); } void loop() { /* Kutsub välja funktsiooni kontrolliNuppe ja salvestab tagastatud väärtuse muutujasse */ vajutatudNupp = kontrolliNuppe(); // Kontrollib kas mõni nupp on alla vajutatud if(vajutatudNupp < nuppNONE) { lcd.clear(); // Puhastab ekraani ja liigutab kursori tagasi algasendisse lcd.print("ADC: "); // Teksti kuvamine ekraanil lcd.print(nupuSisend); // Muutuja väärtuse kuvamine ekraanil delay(500); // Lühike viide, et ekraanil väärtust liiga kiirelt ei uuendataks } } // Funktsioon võtab analoogsisendi väärtuse ja võrdleb olemasolevate väärtustega. // Tagastab arvu vahemikus 0 kuni 5 vastavalt defineeritud konstandile int kontrolliNuppe() { // Salvestab muutujasse analoogväärtuse viigult A0 nupuSisend = analogRead(A0); if (nupuSisend < 50) return nuppRIGHT; if (nupuSisend < 195) return nuppUP; if (nupuSisend < 380) return nuppDOWN; if (nupuSisend < 555) return nuppLEFT; if (nupuSisend < 790) return nuppSELECT; // Kui ühtegi nuppu pole vajutatud, siis tagastatakse "nuppNONE" return nuppNONE; } ===== Harjutused ===== === Harjutus #3.1 === Muuta näiteprogrammi nii, et mõlemale reale tekkiv tekst oleks võimalikult keskele joondatud. === Harjutus #3.2 === Koostada animatsioon LCD ekraanil, kasutades ise genereeritud tähemärke. Tähemärkide massiivide tekitamiseks kasutada generaatorit, mille leiab siit: [[https://omerk.github.io/lcdchargen/|]] === Harjutus #3.3 === Muuta näiteprogrammi nii, et nupud "RIGHT", "LEFT", "UP" ja "DOWN" muudavad kuvatava teksti asukohta LCD ekraanil. Tulemusena peaks nupu vajutamisel tekst liikuma nurka vastavalt vajutatud nupu suunale. Nt. Nupu "DOWN" vajutamisel liigub tekst alumisele reale ja nupu "RIGHT" vajutamisel paremasse äärde.