![]() | ![]() |
![]() |
| ![]() |
| |||||||||||||||||
Interakcija korisnika sa Arduino platformom Do sada nismo poklanjali naročitu pažnju jednoj važnoj oblasti koja se odnosi na procesiranje informacija unesenih od strane korisnika, pa ćemo situaciju pokušati da popravimo ovim pregledom. Tasteri i prekidači Svi znamo da se razne vrste tastera veoma često koriste u sklopu elektronskih uređaja. Iako vizuelno mogu mnogo da se razlikuju, princip rada im je jednostavan i sličan. Funkcija tastera je da na intervenciju korisnika o(ne)mogući protok struje iz jednog dela komponente u drugu, slično funkcionisanju visećeg mosta. Nije moguć prelazak sa jedne na drugu obalu reke, sve do momenta dok most nije spušten. Treba pomenuti da postoji i poseban (ređe korišćen) tip tastera koji radi suprotno, odnosno, na izvršeni pritisak zaustavlja protok struje, dok u standardnom stanju struja kontinuirano teče. Takvi tasteri se označavaju kao NC (normally closed), dok su standardni označeni kao NO (normally open).
void setup() { pinMode(2, INPUT); //ovde prikljucujemo taster Serial.begin(9600); } void loop() { Serial.println(digitalRead(2)); delay(500); }
U radu sa naponom od 5V (Arduino Uno), najčešće vrednosti korišćenog otpornika su 4,7 i 10 kilooma. Moguće je izbeći korišćenje eksternih otpornika, aktiviranjem onih koji su ugrađeni u sam mikrokontroler. Naime, svi ulazni pinovi čipa Atmega328P u sebi sadrže sićušne otpornike veličine 20 kilooma, koje je moguće aktivirati na dva načina: pinMode(pin, INPUT); digitalWrite(pin, HIGH); ili pinMode(pin, INPUT_PULLUP);
I ovde je moguće koristiti pristup sa korišćenjem biblioteke i bez nje. S obzirom na odlične praktično potvrđene rezultate rada, ovde pokazujemo primer pravilnog očitavanja tastera uz pomoć biblioteke Debounce2, koju preuzimamo sa goo.gl/7H99go, gde se nalazi i spisak podržanih funkcija. #include <Bounce2.h> Bounce d_taster = Bounce(); //Instanciranje objekta void setup() { pinMode(2,INPUT_PULLUP); //ukljucujemo ugradjeni otpornik pinMode(13,OUTPUT); //LED na pinu 13 d_taster.attach(2); //pratimo taster na portu 2 d_taster.interval(5); //interval (ms) } void loop() { d_taster.update(); //apdejtujemo stanje int stanje = d_taster.read(); //uzmi novu vrednost if ( stanje == LOW) { //taster pritisnut? digitalWrite(13, HIGH ); //upali LED } else { digitalWrite(13, LOW ); //LED ugasen } } Postoji mogućnost da istovremeno koristimo više tastera preko jednog analognog ulaza na Arduinu i to tako što svaki taster povežemo sa otpornikom iste vrednosti, a sve otpornike zatim međusobno povežemo serijski, dok sve izlaze šaljemo na analogni pin. U zavisnosti od toga koji taster je pritisnut, menja se i vrednost otpora koji će uzrokovati različit nivo napona na analognom pinu. Loša strana ovakvog vezivanja je to da istovremeno može biti očitan samo jedan taster. Ako želimo simultano očitavanje više njih, potrebno je da koristimo različite otpornike kojima je vrednost bar dvostruko veća od prethodnika u vezi. Zbog ograničenosti prostora, ovu temu ostavljamo za neki drugi put.
Potenciometri
float alfa = 0.6; //koeficijent ublazavanja (0-1) int EMA = 0; //inicijalizacija EMA int stara = 0; //prethodna vrednost EMA void setup(){ Serial.begin(9600); EMA = analogRead(A3); //EMA pocetna vrednost } void loop(){ int vrednost = analogRead(A3); if (vrednost != stara){ //doslo do promene? EMA = (alfa*vrednost) + ((1-alfa)*EMA); Serial.println(EMA); stara = vrednost; //pamti promenu delay(20); } } Kod za demonstraciju korišćenja je bio veoma jednostavan, pa smo odlučili da ga malo zakomplikujemo uvođenjem mehanizma za filtriranje podataka, koji je zasnovan na korišćenju funkcije eksponencijalne pokretne prosečne vrednosti (Exponential Moving Average). Iako zvuči prilično „matematički”, stvar je sasvim prosta i cela logika je sadržana u sledećoj liniji koda: EMA = (alfa*vrednost) + ((1-alfa)*EMA); Što je ekvivalentno formuli: EMAt= a*pt + (1- a)*EMAt-1 Alfa je konstanta koja može imati vrednost od 0 do 1 i predstavlja intenzitet filtera, pt predstavlja trenutnu vrednost A/D konvertera, dok je EMAt-1 vrednost EMA za prethodni period merenja. Filtriranjem se umnogome otklanja šum koji se javlja u radu sa elektronskim komponentama. Postoji više načina za računanje pokretne srednje vrednosti, a EMA spada među one koji se najviše koriste. Karakteristika EMA je da nikada ne dobija vrednost nula i da daje prednost novijim rezultatima merenja u odnosu na one starije. Senzorska tastatura
const char taster[4][4]{ {’1’, ’2’, ’3’, ’A’}, {’4’, ’5’, ’6’, ’B’}, {’7’, ’8’, ’9’, ’C’}, {’*’, ’0’, ’#’, ’D’} }; int red[4] {11, 10, 9, 8}; //linije 1,2,3,4 (izlaz) int kol[4] {7, 6, 5, 4}; //linije 5,6,7,8 (ulaz) void setup() { Serial.begin(9600); pinMode (11, OUTPUT); //red 1 (linija 1) pinMode (10, OUTPUT); pinMode (9, OUTPUT); pinMode (8, OUTPUT); //red 4 (linija 4) pinMode (7, INPUT); //kolona 1 (linija 5) pinMode (6, INPUT); pinMode (5, INPUT); pinMode (4, INPUT); //kolona 4 (linija 8) digitalWrite(7, HIGH); //input pinovi, digitalWrite(6, HIGH); //stanje logicko 1 digitalWrite(5, HIGH); digitalWrite(4, HIGH); } void loop() { for (int r = 0; r <= 3; r++) //4 reda { //saljemo LOW na red r digitalWrite(red[r], LOW); for (int k = 0; k <= 3; k++) //4 kolone { //proveri da li je ta kolona LOW? if (digitalRead(kol[k]) == LOW) { //jeste, ispisi pritisnuti taster Serial.print(taster[r][k]); Serial.print(" "); } } //taster nije pritisnut //vracamo red na logicku jedinicu digitalWrite(red[r], HIGH); } } Kao što to u Arduino svetu često biva, korisnicima na raspolaganju stoje biblioteke koje uveliko pojednostavljuju programiranje. U ovom slučaju to je biblioteka Keypad, koju je moguće učitati preko menadžera biblioteka Arduino IDE. #include <Keypad.h> Const char taster[4][4] = { {’1’,’2’,’3’,’A’}, {’4’,’5’,’6’,’B’}, {’7’,’8’,’9’,’C’}, {’*’,’0’,’#’,’D’} }; byte red[4] = {11, 10, 9, 8}; //linije 1,2,3,4 byte kol[4] = {7, 6, 5, 4}; //linije 5,6,7,8 Keypad senz = Keypad(makeKeymap(taster), red, kol, 4, 4); void setup(){ Serial.begin(9600); } void loop(){ char znak = senz.getKey(); if (znak){ Serial.print(znak); //salji na serijski port Serial.print(" "); } }
Sledeće dve varijable red i kol definišu pinove Arduina koje ćemo koristiti za povezivanje sa redovima i kolonama tastature. U sledećem redu kreiramo konstruktor senz sa parametrima koji definišu pinove za redove i kolone, kao i dimenzije matrice. Kao parametar se prosleđuje i raspored tastera. Vrednost koja odgovara pritisnutom tasteru dobija se sa metodom getKey. U našem primeru samo ispisujemo taj znak, a moguće je uz pomoć petlje switch proveravati koji je taster pritisnut i na osnovu toga preduzimati željenu radnju. Neko se može zapitati, zašto da pišemo komplikovani program bez biblioteke, kada je sa bibliotekom sve moguće odraditi brže i elegantnije. Odgovor glasi: varijanta sa bibliotekom zauzima 900 bajtova memorije više, što je važan parametar kada se radi sa mikrokontrolerima. Inače, biblioteka Keypad ima dosta zanimljiv skup funkcija koje omogućavaju pisanje vrlo fleksibilnog koda, kao i mogućnost korišćenja više tastatura odjednom. Desktop tastatura
#include <PS2Keyboard.h> PS2Keyboard kb; //kb je instanca klase PS2Keyboard void setup() { kb.begin(4, 3); //DATA na pin 4, CLK na pin 3 Serial.begin(9600); } void loop() { if (kb.available()) { //otkucan novi znak? char znak = kb.read(); //da, citamo ga //provera dela specijalnih karaktera if (znak == PS2_ENTER) { Serial.println(); } else if (znak == PS2_DELETE) { Serial.print("[DEL]"); } else if (znak == PS2_LEFTARROW) { Serial.print("[<--]"); } else if (znak == PS2_RIGHTARROW) { Serial.print("[-->]"); } else { //znak je slovo, ispisi ga Serial.print(znak); } } } Kao što smo videli mnogo puta do sada, rad sa Arduinom je izuzetno jednostavan, što potvrđuje i ovaj skeč. Konstruktor klase u bloku setup() prima parametre koji ukazuju na pinove Arduina korišćene za povezivanje tastature. Sa programskom petljom loop() pratimo pojavljivanje novog karaktera u baferu tastature. Ukoliko on postoji, prvo proveravamo da li pripada grupi specijalnih karaktera. To su karakteri koji se na ekranu ne prikazuju kao tekst, već obavljaju neku funkciju. Recimo, Enter počinje sa ispisom u novom redu, Delete briše poslednji znak i tako dalje. U našem primeru ne postoji kod koji bi odgovarajuće reagovao na ponašanje tih kodova (osim za Enter), već jednostavno ispisuje tekst koji nam govori da su ti tasteri pritisnuti. Na završetku koda, ukoliko novi karakter ne spada u grupu specijalnih znakova, smatramo da je u pitanju alfanumerički karakter i ispisujemo ga. Igor S. RUŽIĆ |
| |||||||||||||||||||
![]() |
![]() | |
![]() | ![]() |
Home / Novi broj | Arhiva • Opšte teme | Internet | Test drive | Test run | PD kutak | CeDeteka | WWW vodič • Svet igara Svet kompjutera Copyright © 1984-2018. Politika a.d. • Redakcija | Kontakt | Saradnja | Oglasi | Pretplata • Help • English | |
SKWeb 3.22 |