This is an old revision of the document!
TTU Summer School programming
https://www.arduino.cc/en/Tutorial/DigitalPins.
/* Nimetus: Näide #1.1 Kirjeldus: Nuppu all hoides LED põleb */ /* Konstandid */ // Viik kuhu on ühendatud nupp const int nupp = A0; // Viik kuhu on ühendatud LED const int led = 13; /* Globaalsed muutujad */ // Nupu muutuja oleku salvestamine ja selle algväärtustamine int nupuOlek = 0; void setup() { // LED viigu väljundi seadistamine pinMode(led, OUTPUT); // Nupu viigu sisendi seadistamine ja sisemise "pull-up" takisti aktiveermine pinMode(nupp, INPUT_PULLUP); } void loop() { // Nupu muutuja hetkeväärtuse salvestamine nupuOlek = digitalRead(nupp); // Kui nupp on alla vajutatud, siis seadistame LED viigu kõrgeks ehk LED süttib if (nupuOlek == LOW) { digitalWrite(led, HIGH); } // Muul juhul seadistame LED viigu madalaks ehk LED ei põle else { digitalWrite(led, LOW); } }
/* Nimetus: Näide #1.2 Kirjeldus: Nupule vajutades süttib LED 1 sekundiks */ // Algus identne näitega #1.1 (kommenteeritud koodi vaata sealt) const int nupp = A0; const int led = 13; int nupuOlek = 0; void setup() { pinMode(led, OUTPUT); pinMode(nupp, INPUT_PULLUP); } void loop() { // Nupu muutuja hetkeväärtuse salvestamine nupuOlek = digitalRead(nupp); /* Kui nupp on alla vajutatud, siis seadistame LED viigu kõrgeks ehk LED süttib, programm seisab 1 sekund ja pärast seda seatakse viik tagasi madalaks */ if (nupuOlek == LOW) { digitalWrite(led, HIGH); delay(1000); // 1000 millisekundit ehk 1 sekund } digitalWrite(led, LOW); }
/* Nimetus: Näide #1.3 Kirjeldus: Nupule vajutades muudab LED oma olekut püsivalt */ // Algus identne näitega #1.1 (kommenteeritud koodi vaata sealt) const int nupp = A0; const int led = 13; int nupuOlek = 0; void setup() { pinMode(led, OUTPUT); pinMode(nupp, INPUT_PULLUP); } void loop() { // Programm ei tee midagi kuni vajutatakse nuppu if (digitalRead(nupp) == LOW) { // Lüliti kontaktide värelemise (debounce) efekti mõju vähendamiseks väike viide delay(50); while (digitalRead(nupp) == LOW) { //Tsükkel hoiab programmi kinni kuni nupu viigu olek muutub kõrgeks } /* LED viigu olek inverteeritakse ehk seatakse vastupidiseks kasutades hetkeväärtust */ digitalWrite(led, !digitalRead(led)); // Lüliti kontaktide värelemise (debounce) efekti mõju vähendamiseks väike viide delay(50); } }
Modifitseerida näiteprogrammi nii, et nupule vajutades vilgub LED kolm korda.
Modifitseerida näiteprogrammi nii, et nupule vajutades hakkab LED konstantselt vilkuma 1 sekundilise intervalliga ja teine nupule vajutus lõpetab vilkumise.
Modifitseerida näiteprogrammi nii, et nupule vajutades LED vilgub nii mitu korda, kui on nuppu programmi töötamise jooksul kokku vajutatud. Pärast igat vajutust suureneb vilkumiste arv ühe võrra.
/* Nimetus: Näide #2.1 Kirjeldus: Potentsiomeetri pööramisel üle nivoo süttib LED */ // Viik kuhu on ühendatud potentsiomeeter const int pote = A1; // Viik kuhu on ühendatud LED const int led = 13; // Potentsiomeetri muutuja väärtuse salvestamine ja selle algväärtustamine int poteOlek = 0; void setup() { /* Mikrokontrolleri viigud on tavaolekus sisendid ja seega ei pea potentsiomeetri sisendit eraldi seadistama */ pinMode(led, OUTPUT); // Seadistame LED viigu väljundiks } void loop() { // Viigu muutuja hetkeväärtuse salvestamine poteOlek = digitalRead(pote); // Kui sisendviik on kõrge, siis seame LED viigu kõrgeks if(poteOlek > 0) { digitalWrite(led, HIGH); } // Muul juhul seame led viigu madalaks else { digitalWrite(led, LOW); } }
/* Nimetus: Näide #2.2 Kirjeldus: LED-i vilkumise sagedus sõltub potentsiomeetri asendist */ // Algus identne näitega #2.1 (kommenteeritud koodi vaata sealt) const int pote = A1; const int led = 13; int poteOlek = 0; void setup() { pinMode(led, OUTPUT); } void loop() { // Potentsiomeetri muutuja hetkeväärtuse salvestamine poteOlek = analogRead(pote); // LED viigu oleku kõrgeks seadmine digitalWrite(led, HIGH); // Viite tekitamine, mille pikkus on võrdne potentsiomeetri sisendi väärtusega delay(poteOlek); // LED viigu oleku madalaks seadmine digitalWrite(led, LOW); // Viite tekitamine, mille pikkus on võrdne potentsiomeetri sisendi väärtusega delay(poteOlek); }
/* Nimetus: Näide #2.3 Kirjeldus: LED-i ereduse juhtimine potentsiomeetri asendi järgi */ // Algus identne näitega #2.1 (kommenteeritud koodi vaata sealt) const int pote = A1; const int led = 13; int poteOlek = 0; void setup() { pinMode(led, OUTPUT); } void loop() { // Potentsiomeetri muutuja hetkeväärtuse salvestamine poteOlek = analogRead(pote); /* Kui potentsiomeetri väärtus on suurem kui 0, siis seame LED viigu kõrgeks, seejärel programm ootab potentsiomeetri väärtusega võrdse arvu mikrosekundeid */ if (poteOlek > 0) { digitalWrite(led, HIGH); delayMicroseconds(poteOlek); } // Seame LED viigu madalasse olekusse digitalWrite(led, LOW); // Programm ootab ülejäänud arvu mikrosekundeid perioodist delayMicroseconds(1023 - poteOlek); }
Modifitseerida näitekoodi nii, et LED läheb põlema viigu kõrgest olekust madalasse olekusse minekul. Potentsiomeetri kogu pöördenurk vastab pingevahemikule 0-5 V. Leida ligilähedane pinge väärtus, mille juures Arduino sisend muutub madalast olekust kõrgesse olekusse ja vastupidi. Kas esineb hüsterees lülitumiste vahel? Tulemuse saamiseks võib kasutada potentsiomeetri nurka või jadapordi monitori.
Modifitseerida näiteprogrammi nii, et potentsiomeetri keskpunktist (väärtus ~512) ühele poole reguleeritakse LED-i põlemas oleku viidet ja teisele poole kustus oleku viidet. Viite pikkuse reguleerimisel peab maksimaalne viite väärtus olema keskpunkti lähedal ja minimaalne lõpp-punktides. Fikseeritud viite pikkus peab olema 512 millisekundit. Seejuures reguleeritav viite pikkus peab jääma vahemikku 0 kuni 511. Tulemusena peaks ühes potentsiomeetri äärmuses LED olema püsivalt põlemas ja teises püsivalt kustus ning keskel võrdselt põlemas ja kustus.
Modifitseerida näiteprogrammi nii, et LED põleb ainult potentsiomeetri pööramise ajal. LED-i põlemise eredus sõltub potentsiomeetri pööramise kiirusest.
https://www.arduino.cc/en/Reference/LiquidCrystal
/* Nimetus: Näide #3.1 Kirjeldus: LCD ekraanile kirjutamine */ // Vajaliku teegi kaasamine #include <LiquidCrystal.h> // 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); }
/* Nimetus: Näide #3.2 Kirjeldus: Erikujuliste tähemärkide tekitamine ja kuvamine LCD ekraanil */ // Vajaliku teegi kaasamine #include <LiquidCrystal.h> // 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 */ }
/* Nimetus: Näide #3.3 Kirjeldus: LCD laiendusplaadi nuppude lugemine */ // Vajaliku teegi kaasamine #include <LiquidCrystal.h> // 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; }
Muuta näiteprogrammi nii, et mõlemale reale tekkiv tekst oleks võimalikult keskele joondatud.
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/
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.
https://www.arduino.cc/en/guide/libraries#toc4
/* Nimetus: Näide #4.2 Kirjeldus: LCD laiendusplaadi kasutamine kaugus- ja lähedusanduritega */ // Vajalike teekide kaasamine // LCD ekraani funktsioone sisaldav teek #include <LiquidCrystal.h> // Ultrahelianduri funktsioone sisaldav teek #include <NewPing.h> // Andurite ühendusviikude määramine const int ultraheliKaugusandur_TRIGGER = A2; const int ultraheliKaugusandur_ECHO = A3; const int infrapunaLahedusandur = A4; /* Globaalsed muutujad ja konstandid */ const int ultraheliKaugusandur_maksimumKaugus = 200; int ultraheliKaugus, infrapunaNaebObjekti; // LCD objekti tekitamine ja ühendusviikude määramine LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // Ultraheli kaugusanduri objekti tekitamine koos viikude ühendamisega NewPing sonar(ultraheliKaugusandur_TRIGGER, ultraheliKaugusandur_ECHO, ultraheliKaugusandur_maksimumKaugus); void setup() { // LCD ridade ja veergude määramine vastavalt riistvarale lcd.begin(16, 2); // Selgitavate tekstide kuvamine ekraanil lcd.print("Kaugus:"); lcd.setCursor(0, 1); lcd.print("Naeb:"); } void loop() { // Ultrahelianduriga kaguse mõõtmine sentimeetrites ja muutujasse salvestamine ultraheliKaugus = sonar.ping_cm(); // Lähedusanduri väärtuse lugemine ja muutujasse salvestamine infrapunaNaebObjekti = digitalRead(infrapunaLahedusandur); // Kursori esimesele reale ja tähemärgile 9 nihutamine lcd.setCursor(9, 0); // Ekraani kaugusanduri mõõdetud kauguse kuvamine lcd.print(ultraheliKaugus); /* Trükime üle järgnevad kolm tähemärki tühikutega, et vana lugemi väärtus ei jääks ekraanil näha */ lcd.print(" "); // Kursori teisele reale ja tähemärgile 9 nihutamine lcd.setCursor(9, 1); // Kui infrapunalähedusanduri väljund on kõrge, siis kirjuta ekraanile "ei" if(infrapunaNaebObjekti == 1) lcd.print("ei "); // Kui infrapunalähedusanduri väljund on madal, siis kirjuta ekraanile "jah" else lcd.print("jah"); // Väike viide, et tekst ekraanil oleks loetavam delay(500); }
Modifitseerida näiteprogrammi nii, et potentsiomeetriga määratakse temperatuuri nivoo, mis salvestatakse nupuga programmi mällu ja selle nivoo ületamisel käivitatakse täiturmehhanism (milleks on LED).
Lisaülesanne: Kombineerida LED-i heleduse programm ja eelnev temperatuuri lugemise programm, kus LED-i heledus sõltub sellest, kui palju nivootemperatuuri ületati (1 kraad: heledus 25 %, 2 kraadi: heledus 50 %, 3 kraadi: heledus 75 % ja 5 kraadi: heledus 100%
Modifitseerida näiteprogrammi vastavalt vajadusele, et selgitada välja kumb anduritest reageerib kauguse muutusele kiiremini. Võimalusel kontrollida tulemust veebist.
/* Nimetus: Näide #5.1 Kirjeldus: Alalisvoolumootor ja H-sild */ // Mootori viikude määramine juhtmooduli juhtimiseks. // Mootori liikumissuund sõltub ka mootori ühendamise polaarsusest. const int vasak_A = 10; // juhtmooduli viik A-1A const int vasak_B = 12; // juhtmooduli viik A-1B const int parem_A = 11; // juhtmooduli viik B-1A const int parem_B = 13; // juhtmooduli viik B-2A void setup() { // Mootori juhtviikude väljundiks seadistamine pinMode(vasak_A,OUTPUT); pinMode(vasak_B,OUTPUT); pinMode(parem_A,OUTPUT); pinMode(parem_B,OUTPUT); mootorid(0,0); // Mootori algne peatamine delay(2000); // Viide, et robot laua pealt kohe plehku ei paneks } void loop() { mootorid(1,1); // Robot sõidab otse delay(2000); // Viide - robot säilitab viite pikkuse liikumise mootorid(-1,1); // Robot keerab vasakule delay(500); // Viide - robot säilitab viite pikkuse liikumise } // Funktsioon mootori liikumissuundade määramiseks void mootorid(int vasak, int parem) { // Vasak mootor if(vasak == 1) { // Vasak mootor edasi digitalWrite(vasak_A,HIGH); digitalWrite(vasak_B,LOW); } else if(vasak == -1) { // Vasak mootor tagasi digitalWrite(vasak_A,LOW); digitalWrite(vasak_B,HIGH); } else { // Vasak mootor seisma digitalWrite(vasak_A,LOW); digitalWrite(vasak_B,LOW); } // Parem mootor if(parem == 1) { // Parem mootor edasi digitalWrite(parem_A,HIGH); digitalWrite(parem_B,LOW); } else if(parem == -1) { // Parem mootor tagasi digitalWrite(parem_A,LOW); digitalWrite(parem_B,HIGH); } else { // Parem mootor seisma digitalWrite(parem_A,LOW); digitalWrite(parem_B,LOW); } }
/* Nimetus: Näide #5.2 Alalisvoolumootori kiiruse reguleerimine Kirjeldus: Programm demonstreerib alalisvoolumootori kiiruse juhtimist L9110 mootori juhtmooduli näitel. */ // Mootori viikude määramine juhtmooduli juhtimiseks // Mootori liikumissuund sõltub ka mootori ühendamise polaarsusest const int vasak_A = 10; // juhtmooduli viik A-1A const int vasak_B = 12; // juhtmooduli viik A-1B const int parem_A = 11; // juhtmooduli viik B-1A const int parem_B = 13; // juhtmooduli viik B-2B void setup() { // Mootori juhtviikude väljundiks seadistamine pinMode(vasak_A,OUTPUT); pinMode(vasak_B,OUTPUT); pinMode(parem_A,OUTPUT); pinMode(parem_B,OUTPUT); mootorid(0,0); // Mootori algne peatamine delay(2000); // Viide, et robot laua pealt kohe plehku ei paneks } void loop() { mootorid(100,100); // Robot sõidab otse aeglaselt delay(2000); // Viide - robot säilitab viite pikkuse liikumise mootorid(100,255); // Robot keerab sujuvalt vasakule delay(2000); // Viide - robot säilitab viite pikkuse liikumise mootorid(-255,-255); // Robot tagurdab kiiresti delay(2000); // Viide - robot säilitab viite pikkuse liikumise mootorid(-255,-100); // Robot tagurdab sujuvalt paremale delay(2000); // Viide - robot säilitab viite pikkuse liikumise mootorid(150,-150); // Robot keerab kohapeal paremale delay(2000); // Viide - robot säilitab viite pikkuse liikumise } // Funktsioon mootori liikumissuuna ja kiiruse määramiseks void mootorid(int vasak, int parem) { // Vasak mootor if(vasak > 0 && vasak <= 255) { // Vasak mootor otse analogWrite(vasak_A,vasak); digitalWrite(vasak_B,LOW); } else if(vasak < 0 && vasak >= -255) { // Vasak mootor tagurpidi analogWrite(vasak_A,255+vasak); digitalWrite(vasak_B,HIGH); } else { // Vasak mootor seisma digitalWrite(vasak_A,LOW); digitalWrite(vasak_B,LOW); } // Parem mootor if(parem > 0 && parem <= 255) { // Parem mootor otse analogWrite(parem_A,parem); digitalWrite(parem_B,LOW); } else if(parem < 0 && parem >= -255) { // Parem mootor tagurpidi analogWrite(parem_A,255+parem); digitalWrite(parem_B,HIGH); } else { // Parem mootor seisma digitalWrite(parem_A,LOW); digitalWrite(parem_B,LOW); } }
Modifitseerida näiteprogrammi nii, et robot sõidab kaheksa kujulist trajektoori.
Modifitseerida näiteprogrammi nii, et robot teeb iseseisvalt paralleelparkimist ette määratud kohta.