2010-06-12
Az elektronikában komoly probléma a kapcsolók pergésmentesítése. Miről is van szó? Ha egy falikapcsolót felkapcsolunk, kigyullad a csillár, lekapcsoljuk elalszik, és kész. Mi is történik valójában? Ha jobban utánagondolunk, a kapcsolók működtetésekor egy kattanást hallunk. Ez természetes. Két fém érintkezőt összezárjuk, az egyik átbillen, hozzáütődik a másik érintkezőnek, mielőtt stabilan összezáródnának, kicsit pattognak egymáson. És ez baj, mert a lámpákkal ellentétben a digitális áramkörök, másodpercenként több millió impulzust is képesek megszámlálni. Egy rosszul kivitelezett berendezés, egy gombnyomást képes tíznek is értelmezni. Ezt a jelenséget nevezzük a kapcsolók pergésének, vagy prell-nek.
Valahogy így néz ki a kapcsoló nyelvének az útja. Látható, hogy érintkezik, megszakad, érintkezik... számos impulzust ad. Az idők során számos megoldás született. Érdekes, hogy régebben inkább harware-s, míg újabban software-s megoldásokat alkalmazunk. Régen drága volt a gépidő, a processzor, megcsinálták hardware-ból. Ma meg szinte ingyen van, és a legjobb az lenne, ha minnél kevesebb alkatrész, optimális esetben még kapcsolók sem kellenének a berendezésbe:).
Rögtön az elején, nézzük a tökéletes kapcsolást, a tutit, az atombiztost. Sajnos átkapcsoló kell hozzá, két NAND kapu, ellenállások. Ez elég sok alkatrész egy gombhoz. A két kapuáramkör egy RS tárolót alkot. Alap esetben (a rajz szerint) a felső kapu egyik lábát a kapcsoló L-be húzza, vagyis a NAND kapu kimenetén H lesz. Az alsó kapu egyik bemenetét a felső kapu kimente hajtja meg, a másik láb meg az ellenállással szintén fel van húzva H-ba, vagyis a kimenete L lesz, amit megkap a felső kapu másik bemenete. Ez így stabil. Ha elkezdjük a kapcsolót átváltani, a nyelv út közben egyik érintkezőhöz sem csatlakozik, így a felső kapu egyik bemenet H-ba kerül, de a másik bemenete továbbra is L-t kap az alsó kaputól, tehát a tároló állapota nem változik. Amikor a nyelv hozzáér az alsó érintkezőhöz, az alsó kapu bemenete L-t kap, a kimenete H-ba vált, a felső kapu mindkét bementetén H lesz, a kimentet átmegy L-be, vagyis átbillen a tároló, és megint stabil állapotba kerül. Ez a kapcsolás csak akkor hibázna, ha sikerülne olyan rossz kapcsolót találnunk, aminek a nyelve átkapcsolás közben oda vissza ugrál a két érintkező között :).
A következő kapcsolás tulajdonképpen úgy működik, hogy a kapcsoló kimentét egy R-C taggal szűrjük, és szűrt jelet egy Schimdt triggerrel figyeljük.
Nem teljesen jó a grafikon, (pont inverz, mert eredetileg nem ehhez a kapcsoláshoz készítettem) de a lényeg látszik rajta. A kapcsoló működtetésével a kondenzátort feltöltjük/kisütjük. A Schimdt triggernek az az érdekessége, hogy egy alacsonyabb feszültség szintnél billen le, és egy nagyobb feszültség szinten billen fel. Az R-C tagot úgy kell méretezni, hogy a kapcsoló pergése ne tudjon nagyobb ugrásokat kelteni, mint a Schimdt trigger hiszterézise, ez biztosítja a pergésmentességet. Még mindig sok az alkatrész :).
Nézzünk egy minimalista megközelítést. Tipikusan így néz ki, ha egy mikroproceszoros vagy mikrovezérlős áramkörben kapcsolókat alkalmazunk. Mikrovezérlőknél programból határozhatjuk meg, hogy egy láb kimenet vagy bemenet legyen, esetleg analóg láb, de gyakori, hogy belső felhúzó ellenállást is választhatunk, vagyis ekkor még a felhúzó ellenállásokat is elhagyhatjuk! De mitől nem fog ez peregni? Ez abszolút peregni fog, a software-nek kell kitalálnia, hogy most lenyomtuk a gombot, vagy mi van? Én ez a folyamatábra szerint szoktam a bilentyűzetet kezelni. Általában szoktam csinálni egy 100Hz-es megszakítást, amibe bele lehet tenni az idő mérést/figyelést, és a billenytűzet kezelést.
A rutinhoz használok két statikus változót, az egyikben az utolsó lenyomott gomb kódját tárolom el, a másikban, hogy mióta nem változott a lenyomott gomb. Tulajdonképpen egy külön kis rutin szokott gondoskodni a billentyűk lekérdezéséről, és az állapotuknak megfelelő kód visszaadásáról. Ha nincs lenyomott billentyű, akkor 0-t szoktam visszaadni. Nekem, ha nagyon gyors vagyok, másodpercenként 5-6x sikerül egy billentyűt lenyomnom. Állítólag a világ leggyorsabb gépírónője olyan 10 leütés/másodperc sebességgel képes gépelni (értelmesen!). Ezekből az adatokból, meg hogy a gomb lenyomásakor látszólag azonnal történjen valami, úgy okoskodtam, hogy a kapcsoló megnyugvására elég lesz, ha 0,03 másodpercet várok, vagyis ha három perióduson keresztűl nem változik a billentyűzet állapota, akkor az le van nyomva. Ekkor vagy letárolom egy külső változóba a billentyűzet által adott kódot (amit majd a főprogram megtalál), vagy közvetlenül elindítom azt a rutint, ami a gombnak megfelelő műveletet végrehajtja. Ezzel vigyázni kell, nehogy kifussunk a megszakítás 0,01 másodperces keretéből! Inkább használjuk a kód átadását egy változón keresztűl. Egy gomb lenyomásra, akármilyen hosszú is, ez a rutin csak egyszer adja át a vezérlő kódot. Ezt úgy biztosítottam, hogy csak akkor adja ki a vezérlőkódot, ha a számláló éppen 3-on áll. Ha tovább van nyomva a gomb, a számlálóban csak tízig számolok, így akadályozva meg a körbefordulást.
Billyentyűzetek ismerik az auto-repeat funkciót, ami azt jelenti, ha hosszan nyomva tartjuk a gombot, akkor egy idő után, meghatározott időközönként ismét megkapjuk a leütött kódot. Ezt a rutint is tovább lehet így fejleszteni. Mondjuk azt, hogy fél másodperces nyomvatartás után, másodpercenként 5x ismételjen. Ehhez úgy kell módosítani a számlálást, hogy 50-ig menjen, adjon ki egy vezérlő kódot, és vonjon le a számlálóból 20-t. Ekkor 30-tól újra indul a számolás, és 20 periódus után megint kiad egy vezérlő kódot, és előre áll 30-ra....
Sok sikerélményt, és jó fejlesztést mindenkinek!