LAKI PINGVINI<>
102017<><>

Arduino: Korisnički unos podataka

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).

Osim tastera (push buttons), često se sreću i prekidači (switches), čija je funkcija da konstantno drže protok struje u uključenom ili isključenom stanju. Postoji i svojevrsna kombinacija klasičnog tastera push tipa sa prekidačem (na ilustraciji, sa plavom kapicom) koja konstantno propušta struju dok se komponenta nalazi u poziciji „uključeno”, odnosno, fiksirana u položaju prema dole. Tasteri se obično realizuju sa dva reda kontaktnih nožica. Razlog postojanja dva reda jeste u tome što veći broj nožica omogućuje bolju stabilnost komponente na štampanoj ploči. U radu sa Arduinom najčešće ćemo koristiti tastere push tipa sa po četiri pina koja smo na ilustraciji označili slovima AB (ulaz) i CD (izlaz). Dovoljno je dovesti napon na samo jedan od ta dva pina, pošto su oni međusobno povezani.

Šta se dešava kada direktno povežemo taster na Arduino? Iako bismo očekivali da, u zavisnosti od toga da li je taster pritisnut ili ne, na ulazu mikrokontrolera imamo stanje logičke nule ili jedinice, dešava se da u stvari imamo nedefinisano stanje visoke impedanse kod koga se vrednost stalno nepredvidivo menja usled elektromagnetnog šuma. Tačnije, ovo stanje imamo samo kada taster nije pritisnut. Da bismo lakše shvatili o čemu se radi, pogledajmo sledeći primer:

void setup()

{

pinMode(2, INPUT); //ovde prikljucujemo taster

Serial.begin(9600);

}

void loop()

{

Serial.println(digitalRead(2));

delay(500);

}

Kôd čita ulaz na digitalnom pinu 2. Ukoliko pratimo pristigle podatke u prozoru terminala, videćemo da se oni sastoje od nasumičnih vrednosti nula i jedinica. Ako taster ili žicu koja vodi do pina mikrokontrolera, dodirnemo rukom ili ih izložimo nekom izvoru elektromagnetnog zračenja, videćemo da dolazi do promena u očitanim podacima. Da bi se ovo izbeglo, potrebno je dodati otpornik na jedan od sledećih načina:

U pitanju je tehnika koja se vrlo često koristi u radu sa integrisanim kolima kada je potrebno da jasno postavimo pin u stanje inicijalne logičke nule ili jedinice. Gornji primer pokazuje vezu preko pull-up otpornika (povezuje se na Vcc liniju). Sve dok taster nije pritisnut, pin Arduina dobija napon koji odgovara vrednosti HIGH, dok nakon pritiska na taster dolazi do oticanja struje prema uzemljenju, a vrednost na posmatranom pinu pada na LOW. Dakle, kada imamo stanje LOW, to je znak da je taster pritisnut, dok HIGH znači da nije. Drugi primer je vrlo sličan, samo što sada pin dobija napon LOW dok taster nije pritisnut. Nakon pritiska dolazi do preusmeravanja struje od izvora 5V prema pinu Arduina i on dobija vrednost HIGH. Pull-down otpornici se uvek povezuju preko GND linije. Generalno, u praksi je moguće koristiti oba načina povezivanja, ali moramo obratiti pažnju na jedan važan detalj. Zbog uštede električne energije koristimo pull-up način ukoliko je taster retko u stanju kontakta (najčešći slučaj), dok se pull-down preferira tamo gde je taster/prekidač najveći deo vremena uključen.

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);

Treba imati na umu da zbog pada napona uzrokovanog korišćenjem LE diode na pinu 13, ulazni napon iznosi 1,7 volti, umesto standardnih pet volti. U radu sa tasterima srećemo se sa još jednim problemom koji se naziva „odskok” (engl. bounce), a koji se manifestuje kao višestruka promena logičkih stanja u kratkom vremenskom periodu. Pošto su u pitanju uređaji sa pokretnim delovima, prilikom pritiska na taster dolazi do sićušnih oscilacija koje se manifestuju gubljenjem kontakta i njegovim ponovnim uspostavljanjem, a čije vreme se meri mikrosekundama. Iako korisnik ne primećuje razliku, na osciloskopu je ta anomalija jasno vidljiva. Problemi mogu da nastanu kada, recimo, brojimo koliko je puta taster pritisnut, pa umesto jedne promene napona imamo više njih, što znači da je taster pritisnut više puta.

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.

Da bismo zaokružili priču o tasterima i prekidačima, pomenućemo i interesantnu varijantu ulaznih uređaja koji se nazivaju DIP (dual in-line package) prekidačima. Reč je, najčešće, o plastičnim kutijicama koje sa donje strane imaju pinove kojima se fiksiraju na štampanu ploču i na sebi sadrže veći broj malih prekidača, uglavnom od dva do deset. Njihova funkcija je jedino ograničena maštom kreatora, a najčešće se koriste kao džamperi za podešavanje uređaja. Sa cenom od 50 centi i malim dimenzijama, mogu odlično da posluže u mnogim projektima.

Potenciometri

Potenciometri su uređaji kojima se menja vrednost otpora pomeranjem pokretnog dela, koji je obično rotacionog tipa ili u obliku slajdera. Drugim rečima, u pitanju su promenjivi otpornici čija se vrednost definiše akcijom korisnika. Dva glavna tipa su: logaritamski (označeni slovom A ispred vrednosti) i linearni (slovo B).

Uzmimo, na primer, potenciometar od deset kilooma. Kada se nalazi na minimumu, generiše otpor od nula oma, dok na maksimumu postiže svoju nominalnu vrednost od deset kilooma. Za očitavanje je potrebno da se potenciometar priključi na neki od analognih ulaza Arduina, gde će se promene otpora manifestovati promenom napona u analogno-digitalnom konverteru mikrokontrolera. Sve se to dešava u skladu sa Omovim zakonom, pa ćemo najveći napon imati kada je potenciometar na minimumu, a najmanji kada ga postavimo u krajnju poziciju. Arduino prepoznaje 1024 (210) stanja na A/D ulazu, što u prevodu znači da se prepoznaju promene napona u koracima od 0,00488V (5 mV).

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

Stariji čitaoci se verovatno sećaju računara Sinclair ZX 80 i ZX 81, koji su početkom osamdesetih bili poznati po veoma niskoj ceni, crno-beloj grafici, memoriji od samo jednog kilobajta i senzorskoj tastaturi koja je mnoge korisnike izvodila iz takta, pošto se često dešavalo da računar pri unosu podataka ne detektuje pritisak tastera. Istina, senzorski tasteri i tastature ne spadaju u najudobnije ulazne uređaje, ali vrlo često mogu da budu veoma elegantno rešenje za unos manjeg obima podataka. Senzorski paneli mogu da se pronađu u različitim oblicima i sa različitim brojem tastera. Najčešće sadrže brojeve i nekoliko pratećih funkcijskih tastera, ali je moguće kupiti i modele sa samo nekoliko tastera, kao i one na kojima je smeštena celokupna engleska azbuka. To su uređaji jednostavne konstrukcije, pa im je u skladu sa tim cena veoma povoljna. Mi smo za demonstraciju koristili panel od šesnaest tastera, čija se cena kreće u rangu od veoma prihvatljivih 50 centi.

Princip rada je veoma jednostavan. Svi tasteri se nalaze na preseku po jednog reda i kolone. Naš zadatak je da ustanovimo koji od njih je pritisnut. To radimo tako što svaki red postavljamo u stanje logičke nule i zatim proveravamo stanje na kolonama. Pritisak tastera dovodi do prenosa logičke nule na kolonu sa pritisnutim tasterom, i kada očitamo da se na toj liniji pojavila logička nula, znamo da je taster pritisnut. Na primer, ukoliko je pritisnut taster 7, imaćemo na linijama 3 i 5 stanje logičke nule, što jasno identifikuje poziciju tastera.

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(" ");

}

}

 
Dvodimenzionalna promenjiva taster definiše koji znak će biti prikazan kada se identifikuje klik na određenom preseku redova i kolona. Pošto koristimo tastaturu sa 16 tastera, matrica će imati veličinu 4 × 4 znaka. U slučaju da imamo tastaturu bez tastera ABCD, tada bismo definisali matricu veličine 4 × 3 znaka. Za program je apsolutno nevažno koji znak će biti prikazan na kojem mestu, pa je umesto vrednosti koje odgovaraju natpisima na tastaturi moguće upotrebiti bilo koji znak, recimo, omogućiti prikaz heksadecimalnih brojeva.

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

Tastature sa PS/2 konektorom danas se retko koriste, ali se relativno lako mogu naći na starim računarima. Ono što je za nas veoma zanimljivo jeste činjenica da se takve tastature na vrlo jednostavan način mogu priključiti na Arduino i maksimalno olakšati unos podataka. Šestopinske konektore ženskog tipa moguće je naručiti preko interneta (oko 50 centi) ili ih možemo skinuti sa neke stare neispravne matične ploče. Moguće je kupiti gotove module za priključivanje PS/2 tastature po ceni od jedan do jedan i po evro, što smatramo sasvim prihvatljivim.

Gledano sa prednje strane, konektori imaju sledeće kontakte za lemljenje na ploču:

Kao što vidimo, od šest kontakata koristi se četiri, dva za napajanje (Vcc i GND), jedan za sinhronizaciju prenosa (CLK) i jedan za prenos podataka (DATA). Postoji nekoliko biblioteka koje podržavaju rad sa PS/2 tastaturom, ali je najpoznatija ona pod nazivom PS2Keyboard (goo.gl/MjsjD8). Tu je i zanimljiva varijacija na temu pod nazivom PS2KeyAdvanced (goo.gl/ZUAU6X) koja, osim manjeg zauzeća memorije, omogućava i pojednostavljen ispis na priključenom LCD ekranu. Obe varijante je moguće preuzeti preko ugrađenog menadžera biblioteka.

U radu sa Arduinom UNO, na raspolaganju imamo samo dva pina sa mogućnošću generisanja spoljašnjeg hardverskog prekida (interrupt) i oni su smešteni na pozicijama D2 i D3 (digitalni pinovi 2 i 3). Drugi Arduino modeli imaju veći izbor, pa tako MEGA 2560 omogućava priključivanje na pinove 2, 3, 18, 19, 20 i 21. Obavezno je priključiti CLK signal na neki od tih pinova, pošto u suprotnom tastatura neće funkcionisati. Pin za prenos podataka (DATA) možemo izabrati proizvoljno.

#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Ć

 
Nitrux 1.0.3
WallpaperDownloader 2.8
Checkmate 2.4.0
Arduino: Korisnički unos podataka
Šta mislite o ovom tekstu?
Štitovi Arduina (1): Proto Shield

Dodatna literatura

Knjiga „Arduino Uno – 45 projekata za početnike i stručnjake”, autora Berta Van Dama, u naslovu ističe da ima nameru da nam izloži četrdeset pet projekata koji bi bili interesantni, kako početnicima, tako i onima sa više iskustva (stručnjaci su ovde ipak prejaka reč). Autor započinje sa laganim uvodom u platformu Arduino, gde navodi samo osnovne informacije o komponentama i svojstvima uređaja. Sasvim dovoljno za one koji su sa temom od ranije „na ti”, ali bi početnicima ipak dobro došlo više detalja.
Kroz naredna poglavlja krećemo se od jednostavnijih do vrlo složenih i zanimljivih projekata koji će pokriti sve bitne oblasti upotrebe SBC računara uz mnoštvo praktičnih primera.
Karakteristično je da autor sve vreme čitaocima daje potrebne informacije, ali to čini na neopterećujući način. Isti se utisak stiče i kod uvođenja čitaoca u svet Arduino programiranja. To se dešava nenametljivo i sa razumljivim primerima koda, koji su pri tom dosta siromašno komentarisani, i to na engleskom jeziku. Kod nas još uvek ne postoji dovoljno literature iz ove oblasti na srpskom jeziku, tako da će ova knjiga biti vredan izvor informacija za sve one koji žele da nauče kako se radi sa platformom Arduino.
Veliki deo publike ne zna da je naziv Raspberry Pi izabran u skladu sa starom tradicijom da računar bude imenovan po nekoj voćki, dok je „Pi” trebalo da ukazuje na integrisani Python interpreter. Taj programski jezik nije izabran slučajno, jer je reč o platformi koja se nameće kao sjajan izbor kada je u pitanju edukacija, pošto kombinuje lakoću sintakse i velike mogućnosti koje dolaze sa brojnim bibliotekama napisanim za Python.
U prvom poglavlju knjige „Raspberry Pi kuvar za Python programere” srećemo se sa veoma praktičnim uvodom u rad sa računarom Raspberry Pi. Od ovog poglavlja će najviše koristi imati oni koji se tek susreću sa ovom hardverskom platformom. U nastavku nas autor priprema za programiranje objašnjavajući kako da konfigurišemo editor Geany i kako da instaliramo modul Tkinter, koji služi za kreiranje GUI aplikacija. Konstantnim tempom prelazi se od primera jednostavnih programa do pravljenja video igre, a jedno poglavlje se bavi pitanjima 3D grafike. Izučava se i upotreba GPIO porta kao specifičnost hardvera Raspberry Pi, kao i pitanja I2C interfejsa i vezivanja sa senzorima. Do kraja se obrađuje upotreba modula kamere, kreiranje stop-motion animacije i realizuje čitanje QR koda, dok je narednih pedesetak stranica namenjeno projektu kreiranja robota.
Iako je nešto starijeg datuma, reč je o lepom vodiču za praktičnu primenu programskog jezika Python.
Home / Novi brojArhiva • Opšte temeInternetTest driveTest runPD kutakCeDetekaWWW vodič • Svet igara
Svet kompjutera Copyright © 1984-2018. Politika a.d. • RedakcijaKontaktSaradnjaOglasiPretplata • Help • English
SKWeb 3.22
Opšte teme
Internet
Test Drive
Test Run
PD kutak
CeDeteka
WWW vodič
Svet igara



Naslovna stranaPrethodni brojeviOpšte informacijeKontaktOglašavanjePomoćInfo in English

Svet kompjutera