A bemenet arra alkalmas, hogy HIGH (kb. 5V) és LOW (kb. 0V)feszültségszinteket különböztessen meg az Arduino. Ha egy bemenetet a GND (föld) kivezetéshez kapcsolsz egy vezetékkel, és beolvasod a bemenet állapotát, akkor LOW (bináris számként kifejezve 0, vagy logikai értékkel kifejezve false azaz hamis) értéket fog beolvasni a chip. Ha a vezeték darabot az 5V-os tápfeszültségre kötöd, akkor a bemenet állapota HIGH (bináris 1, vagy logikai true azaz igaz) lesz. Ne zavarjon, hogy HIGH, 1, 5V, true, igaz jelzőket használok. Mind ugyanazt jelenti: a bemeneten közel tápfeszültség van. Ez a magas (HIGH) feszültség állapot, amit a digitális értékek között az „1” képvisel, logikai áramkörökben pedig azt mondjuk rá true. Ne hagyd magad megzavarni, csak azért írok mindig mást, mert ettől úgy tűnik mintha értenék hozzá!
Mi van akkor, ha nem kötöd sehová a bemenetet, csak lóg a levegőben. Ekkor bizonytalan lesz a bemenet állapota. Lehetséges, hogy az egyik beolvasás HIGH, míg a másik LOW értéket fog visszaadni. Ezért sok esetben a bemenetre egy úgynevezett felhúzó ellenállást kötnek. A felhúzó ellenállás értéke lehet kb. 10 Kohm, míg egyik vége a bemenethez, másik végét az 5V kivezetésre kötik. Ha pl. egy kapcsoló állapotát kell lekérdezni a bemeneten, akkor a kapcsoló egyik kivezetése a bemenet, másik a GND.
Az ábra innen származik: https://www.instructables.com/id/Understanding-the-Pull-up-Resistor-With-Arduino/) Itt a felhúzó ellenállás 4.7Kohm, ez is jó. Ha a kapcsoló nincs bekapcsolva (jobb oldali ábra), akkor a bemeneten HIGH szintet olvasunk be, hiszen a felhúzó ellenállás 5V-al köti össze. Ha megnyomjuk a nyomógombot (bal oldali ábra), akkor LOW szintet kapunk, hiszen a kapcsoló egy rövidzár a GND felé, és ilyenkor ez az erősebb. A felhúzó ellenálláson 5V/4,7Kohm=~1mA áram folyik amíg nyomod a gombot, de ez senki nem zavar, kicsit nagyobb az áramkör fogyasztása.
Viszont van egy jó hírem, a felhúzó ellenállást eleve beleépítették az ATmega328 chip-be. Mivel nincs rá mindig szükség, ki és bekapcsolhatóvá tették. Tehát ha egy bemenetre nyomógombot akarsz tenni, akkor állítsd a kivezetést bemenetre, és kapcsold be a felhúzó ellenállást. A belső felhúzó ellenállás magyarázó ábrája a tavir.hu weboldalról származik:
Fontos megfigyelni, hogy a kapcsoló bekapcsolt állapota esetén a bemeneten LOW szint van. Tehát a bemeneti 0V (LOW) szint az aktív, ez jelzi az eseményt. Ez nem baj, csak általában pont fordítva szoktak jelezni az érzékelők. Pl. egy mozgásérzékelő akkor ad HIGH szintet, ha mozgást érzékel. Semmi gond, csak tudjunk róla. Egyébként elvileg lehetne fordítva is, miszerint a föld felé teszünk „lehúzó” ellenállást, és a kapcsoló a 5V-ra húzza fel a bemenetet. Ekkor a nyomógomb megnyomásának eseményét a HIGH szint jelezné a bemeneten. Nem tudom miért, de nem így szokták! Talán az lehet az ok, hogy az ATmega chip-ekbe „felhúzó” ellenállást építenek, és nem „lehúzó” ellenállást.
Lássuk végre, hogyan is kell bemenetet csinálni és lekérdezni azt! Még annyit érdemes tudni, hogy az Arduino IDE C programját két fő részre osztották. Van egy “SETUP” rész, ami csak egyszer fut le, és van egy “LOOP” rész, ami viszont ciklikusan, végtelen ideig újraindul az első utasítástól kezdve, ha befejeződött az utolsó utasítás végrehajtása. A kivezetések működésének definiálását a setup-ban szokták megcsinálni, de nem kötelező ott, a loop-ban is lehet. Sőt, akár működés közben is átállíthatod a kimenetet bemenetre, vagy vissza, de ezzel óvatosan kell bánni, és nehezen találok rá okot, hogy miért is kellene ilyet tenni.
Arduino C-ben a bemenetek beállítása és lekérdezése:
(C-ben a “//” két perjel mögötti szöveg a megjegyzés, amit magadnak irogatsz, nem a program része)
pinMode(x,INPUT); //az x kivezetés bemenet
digitalWrite(x,HIGH) //az x kivezetés belső felhúzó ellenállásának bekapcsolása
digitalWrite(x,LOW) //az x kivezetés belső felhúzó ellenállásának kikapcsolása
digitalRead(x) //az x kivezetés aktuális értékének beolvasása
Ez itt alább már egy működőképes programrészlet (Ha bemásolod az Arduino IDE felületére, akkor ez egy lefordítható és Arduino-ba tölthető kód. Ez most még nem egy teljes program, hiányoznak fontos részek):
pinMode(13,INPUT); //a chip 19-es láb (Ardunio-n digital pin 13) bemenet
digitalWrite(13,HIGH); //a 19-es lábon (Arduino 13 digital pin) a belső felhúzó ellenállás bekapcsolva
ertek=digitalRead(13); //az ertek nevű változóba beolvassuk a bemenet állapotát
BASCOM-ban a bemenetek beállítása és lekérdezése:
(BASCOM-ban a megjegyzéseket, kommenteket a ‘ jel után írhatod)
Config pinx=Input ’az x port minden kivezetését bemenetnek állítjuk
Config Pinx.y=Input ’x port y kivezetése bemenet lesz
Felhúzó ellenállás bekapcsolása:
Portx.y=1 ’x port y kivezetésén a felhúzó ellenállás bekapcsolása
portx.y=0 ’x port y kivezetésén a felhúzó ellenállás kikapcsolása
Egy működőképes példaprogram részlet:
portb=&B00000010 ‘a második bitre 1-et írunk ezzel bekapcsoljuk
‘a belső felhúzó ellenállást. Feltételeztem, hogy
‘csak a második kivezetés bemenet, a többi kimenet
vagy:
portb.2=1
Az alábbi példaprogram ugyanazt csinálja mint a fenti C példaprogram:
config PortB.5 INPUT ’a chip 19-es láb (PB5, Ardunio-n digital pin 13) legyen bemenet
portB.5=1 ’a 19-es lábon a belső felhúzó ellenállás bekapcsolva
A=pinb.5 ’A változóba beolvassa a bemenet állapotát
Van még néhány fontos tudnivaló:
- Az átlagos nyomógombok nem adnak határozott jelet. Amikor megnyomod a nyomógombot, két fémdarab ér egymáshoz, és kapcsoláskor kicsit pattognak egymáson. Vagyis a kapcsoló egy darabig hol kapcsol, hol meg nem. Ezt a jelenséget “prell”-nek hívják. Az otthoni villanykapcsolón nem veszed észre, mert a jelenség néhány századmásodpercen belül lezajlik. A vezérlő viszont olyan gyors, hogy ezeket a bizonytalan hol be, hol ki állapotokat észreveszi. Ha pl. a gombnyomások számát akarod megszámolni, akkor egy gombnyomásra 4-5-öt is számolni fog a program. A prell szoftveresen megszüntethető. Egyszerű a dolog, hiszen az első kontaktusnál már tudjuk, hogy megnyomtuk a gombot, és egy ideig nem szabad figyelembe venni, hogy mi történik. Gyakorlatban ez a várakozási idő kb. 50msec. A prellmentesítéssel elég sokat foglalkoztam, mert folyton nehézségeket okoz. A forráskódok menüben találsz egy külön oldalt amiben összefoglaltam tapasztalataimat és készítettem a lehetséges megoldásokra mintapéldákat.
Nemrégiben hozzájutottam egy logikai analizátorhoz. Azzal is megvizsgáltam a prell jelenségét. Ha érdekel, akkor itt találsz információt a logikai analizátorok használatáról, és a leírás legvégén olvashatod a prell jelenségével kapcsolatos tapasztalataimat. Szép ábrákat láthatsz a valós prell jelenségről, és nem kell hozzá megismerni az analizátor működését.
A nyomógombokat sokféle módon lehet használni. Készítettem egy mintapéldát, segéd programot, ami nem csak prellmentesít, hanem különféle nyomógomb üzemmódokat valósít meg. Pl. egy megnyomás bekapcsol egy kimenetet, egy másik meg lekapcsolja. Olyan működést is meg lehet valósítani, hogy a nyomva tartás idejére bekapcsolva tartja a kimenetet. Időzíteni is lehet, ha elengedted a nyomógombot, akkor egy ideig még bekapcsolva marad a kimenete stb. Remélem másnak is hasznos. - A nyomógomb és az Arduino kivezetés közötti vezetékdarab hossza nem elhanyagolható. Próbapanelen 10-20 cm távolságnál még semmi baj nincs. Azonban egy lakás méretében gondolkodva már komoly gondok lehetnek. Egy 10-20 méteres vezeték zajokat és zavarokat szed össze. Pl. beindul a hűtőgép, és a vezetékben akár 5-10V feszültség impulzus szalad át, mert a vezetékek egy szakaszon egymás mellett futnak a falban. Ez akár tönkre is teheti az Arduino-t, így ez ellen védekezni kell. Egyik lehetséges megoldás az optikai leválasztás. Ekkor a kapcsoló és az Arduino közé beteszünk egy led-ből és fototranzisztorból épített leválasztó modult. A kapcsoló feszültséget ad a led-nek, az világítani kezd, mire a fototranzisztor a megvilágítás hatására lehúzza az áramkör kimenetét a 0V-ra (földre). Én egyszerűbb megoldást választottam a lakásunkban. Beforrasztottam a kapcsoló kontaktusai közé egy 10 mikroF kondenzátort. Ez a kondenzátor zavarszőrű hatást fejt ki. Folyamatosan 5V értékre töltődik a felhúzó ellenálláson keresztül, és a vezetékben keletkező zavarjelek energiája nem olyan nagy, hogy lényegi változás történjen a feszültségén. A nyomógomb rövidre zárja a kondenzátort, és a feszültség 0V-ra csökken. A kondenzátorban tárolt energia a kapcsolón keresztül távozik, így a kapcsolóban rövid ideig jelentős áram folyik. A falra szerelt 5-10A áramra tervezett fali kapcsolónak ez azonban meg sem kottyan. Ha kikapcsoljuk a kapcsolót, akkor a kondi a felhúzó ellenálláson keresztül újra feltöltődik az 5V feszültségre. Ezt én nem bíztam az ATmega328-ba beépített felhúzó ellenállásra, külső 1 Kohm felhúzó ellenállást alkalmaztam. A bemeneteket zener diódával is lehet védeni, erről most többet nem mesélnék, mert megy az idő!
- A bemenetek HIGH illetve LOW érzékelése bemeneti feszültség függő. Ahhoz, hogy LOW értéket érzékeljen a mikrovezérlő, nem kell pontosan 0V-ot kapcsolni. Kb 0V és 0,5V között LOW szintet fog érzékelni, míg kb 2,5V felett HIGH értéket. Elvileg a chip adatlapjában 4,5V-tól garantálják a HIGH érzékelést, de a gyakorlatban ez már sokkal kisebb feszültségnél bekövetkezik. Pl. több érzékelőnek a kimenete 3,3V kimenő feszültséget állít elő. Ez közvetlenül rá lehet kötni egy bemenetre, és jól fog működni. A megadott feszültségszintek 5V tápfeszültség esetén értendők. Az ATmega328 chip működik 2,7V és 5V közötti bármilyen tápfeszültséggel. Pl. ha 3,3 V-ról működteted, akkor a kimenet LOW szintje 0V a HIGH viszont 3,3V. Ez ugyebár teljesen egyértelmű. A bemenet esetében már kevésbe egyértelmű a dolog. A LOW szint továbbra is 0 közeli érték a HIGH szint viszont maximum 3,3V vagy egy kicsit kisebb. Hogy pontosan mennyi, az minden bizonnyal kiderül az adatlapból, de nem voltam rá kíváncsi, mert az Arduino 5V-ról működik.
- Mint az előbb említettem, az ATmega328 chip 2,7V és 5,5V tápfeszültség esetén működik. A kereskedelemben kapható kiegészítő modulok jelentős része mindössze 3,3V feszültséggel működtethető. Figyelni kell a különböző tápfeszültséggel működtetett eszközök összekapcsolásakor, mert ez problémát okozhat. Főleg az okoz gondot, ha egy eszköz bemenetére nagyobb feszültséget kapcsolunk, mint a tápfeszültsége. Általában 0,5V-nál nagyobb túlfeszültség tönkreteszi az eszköz adott bemenetét!
Ha már le tudjuk kérdezni, hogy HIGH vagy LOW jelet kapcsoltunk egy kivezetésre, nézzük meg, hogyan csinálhatunk akár ugyanebből a kivezetésből kimenetet, ahol viszont az Arduino fogja megmondani, hogy milyen feszültség legyen. Kattints ide, ha ez is érdekel!
Amint elolvastad a kimenet beállításának tudnivalóit, érdemes lesz megtekintened egy működő példaprogramot a ki és bemenetek használatára.
A digitális be (és ki)menetek programozását az Arduino IDE által nyújtott függvényekkel nagyon egyszerű elvégezni. Azonban az így készített program esetlenként lassú és/vagy túl nagy méretű lehet. Ennek oka, hogy az előre megírt pinMode() és digitalRead() függvények mögött elég sok programsort helyeztek el az alkotók a mi kényelmünk érdekében. Ha nagyon gyors programra van szükség, akkor ezeket a függvényeket ki is hagyhatjuk, és közvetlenül hozzáférhetünk a vezérlő belső regisztereihez. Ez már egy kicsit mély víz, de nem túl bonyolult dolog. Többet tudhatsz meg erről itt!