Ošetření spínacích kontaktů

aneb klávesnice, rotační enkodéry, jazýčková relé, mikrospínače, nárazové spínače, snímače náklonu a vibrací

Obecně nejčastějším způsobem ovládání aplikací systému Arduino s okolním světem jsou tlačítka, klávesnice (membránové, kapacitní nebo s mikrospínači), rotační enkodéry (rotation encoders, inkrementální otočné ovladače) a řada dalších spínačů, pracujících na mechanickém principu.

Přestože na první pohled by neměl být až takový problém zjistit, zda je nějaký kontakt sepnut či ne, nějaká úskalí tam přece jen jsou… A o tom je tento článek.

Zjištění stavu sepnuto / vypnuto

Z pohledu komunikace s procesory systému Arduino lze všechna uvedená zařízení rozdělit na dvě skupiny:

  • na aktivní vstupní moduly s vlastními elektronickými obvody, které při aktivaci spínače poskytují na výstupu ošetřené a definované logické signály „0“ nebo „1“;
  • a na spínače bez vlastní elektroniky, jejichž výstupní signál je nutno nějakým způsobem ošetřit.

Komunikace s moduly s vlastní elektronikou obvykle nečiní potíže – na výstupu modulu je po aktivaci spínače či čidla po danou dobu přítomen stabilní signál o definované logické úrovni, který lze přímo připojit na vstupní piny procesorového modulu a vyhodnotit běžnou čtecí operací v rámci standardního běhu programu.

V případě komunikace se spínacími moduly bez vlastní elektroniky modulů je ale potřeba splnit několik podmínek:

  • přivést na ten vývod (pin, konektor) spínače, který není spojen se vstupním pinem procesoru, napětí o definované úrovni, které bude po sepnutí kontaktů spínače či tlačítka přivedeno na vstupní pin procesoru;
  • zajistit, aby při rozepnutém kontaktu spínače bylo na vstupním pinu procesoru napětí odpovídající opačné logické úrovni;
  • vhodným způsobem ošetřit zákmity, ke kterým po sepnutí nevyhnutelně dochází v každém mechanickém spínacím prvku;
  • a konečně, je-li to vhodné, zajistit vhodným způsobem zpracování krátkých impulzů, ke kterým dojde po aktivaci spínače či tlačítka na dobu kratší, než je trvání jednoho cyklu funkce loop();

První dvě podmínky lze splnit tak, že kontakt spínače, který není spojen se vstupním pinem procesoru, propojíme s nulovým zemním potenciálem GND, zatímco druhý kontakt, přivedený na vstup procesoru, je přes omezovací rezistor připojen na napájecí napětí +5V. Je-li spínač rozepnut, je na vstupu procesoru omezovacím rezistorem udržováno napětí, které odpovídá logické úrovni „1“; po sepnutí kontaktů spínače je pak vstupní pin uzemněn, což odpovídá logické úrovni „0“ (tlačítko do „0“). Velikost rezistoru je vhodné zvolit tak, aby jím po sepnutí kontaktů spínače (a tedy po spojení druhého konce odporu s nulovým potenciálem) netekl příliš velký proud, který by zbytečně zatěžoval napájecí obvody, zahříval omezovací rezistor a poškozoval kontakty spínacího prvku. Na druhou stranu musí velikost omezovacího odporu s rezervou zajistit přítomnost napětí logické úrovně „1“, pokud omezovacím odporem protéká proud do vstupního pinu procesoru a na odporu tak vzniká úbytek napětí.

Podle specifikací procesoru ATmega328P je (při napájecím napětí +5 V) jako logická úroveň „1“ vyhodnocena napěťová úroveň 3,0 V a výše. Vstupní proud kteréhokoli pinu procesoru je podle specifikací +/- 1 µA, hodnotu omezovacího odporu tedy volíme tak, aby při proudu 1 µA na odporu vznikl úbytek napětí menší, než 2 V (pak bude na vstupním pinu procesoru napětí právě 3,0 V); tomu odpovídá hodnota odporu 2 MΩ. V praxi se ovšem volí hodnoty odporu řádově nižší, obvykle v rozmezí desítek kiloohmů (10 kΩ, 22 kΩ, 33 kΩ), které při minimálním protékajícím proudu zajistí i dostatečnou odolnost proti případnému rušení; hodnotu odporu v řádu stovek kiloohmů (150 – 330 kΩ) pak volíme v případě požadavku na minimální odběr zařízení (např. u solárního napájení), a i to pouze za situace, kdy je vstupní pin pod omezovacím odporem udržován na nulovém potenciálu (a kdy jím tedy protéká větší proud) po významně dlouhou dobu.

Zapojení tlačítek
Zapojení tlačítek

U mikrokontrolérů řady Atmel ATmega můžeme jako omezovací odpor ve většině případů použít tzv. pull-up rezistor, který je vestavěn přímo v procesoru. Po jeho programovém zapnutí (vstupní pin musíme konfigurovat jako INPUT_PULLUP) je vstupní pin propojen s napájecím napětím +5 V přes odpor, jehož velikost se pohybuje v rozmezí 20 – 50 kΩ,.

Obecně lze použít i opačné zapojení, kdy je na vstupní pin procesoru po sepnutí spínače přivedena hodnota „1“, zatímco v klidovém stavu je vstupní pin udržován na nulovém potenciálu omezovacím rezistorem, který je spojen se zemí (tlačítko do „1“). Protože však v tomto případě nelze využít pull-up rezistor vestavěný v mikrokontroléru (tam lze připojit pouze rezistor připojený na Vcc), musíme push-down rezistor připojený na zem doplnit sami; proto je tento případ komplikovanější a méně častý.

Zákmity (bouncing)

Zákmity (bouncing)
Zákmity (bouncing)

Dalším problémem, který bývá nutné řešit, je výskyt zákmitů (bouncing) po stisku tlačítka. Po stisknutí i uvolnění tlačítka, ale i jakéhokoli jiného mechanického kontaktu, membránových tlačítek, mikrospínačů, jazýčkových kontaktů a pod., nedojde okamžitě k trvalému sepnutí či rozepnutí kontaktů, ale zpočátku, po dobu jednotek až desítek milisekund, dochází k tzv. zákmitům, kdy je obvod kontaktem opakovaně spínán a rozepínán. Pokud tlačítko slouží k rozsvícení světla nebo aktivaci bzučáku, můžeme tyto počáteční zákmity ignorovat, dříve nebo později se kontakty „uklidní“ a výstup se spolehlivě sepne (vědomě pomíjím elektromagnetické rušení, které bývá těmito zákmity vyvoláno). Pokud ale potřebujeme vyhodnotit např. počet stisků daného tlačítka, je odstranění zákmitů nezbytností.

Debouncing
Debouncing

Nejjednodušším řešením je jednoduchý RC obvod, který se skládá z filtračního kondenzátoru a nabíjecího nebo vybíjecího rezistoru. Pro příklad uvažujeme řešení, kdy je vstupní pin „IN“ procesoru ATmega328P udržován na úrovni „1“ vestavěným pull-up rezistorem, a kdy je po stisku tlačítka na tento vstup přivedeno napětí v logické úrovni „0“ z jiného výstupního pinu procesoru „OUT“ (situace, kdy druhý kontakt tlačítka není přímo uzemněn, ale je na úrovni „0“ udržován jiným výstupním pinem procesoru, je běžná v případě snímání stavu několika tlačítek zapojených do matice – viz dále v textu).

Ze specifikací uvedených v datasheetu pro napájecí napětí +5V vyplývá, že maximální velikost napětí pro logickou hodnotu „0“ na vstupním pinu je +1,5 V. Pro napětí na výstupním pinu je pro logickou úroveň „0“ naopak garantováno výstupní napětí menší než +0,9 V, při omezení proudu pod hodnotu 5 mA pak toto zaručené napětí klesne pod +0,2 V.

Po prvním stisknutí tlačítka Tl1 je tedy napětí filtračního kondenzátoru C1 vybito na hodnotu napětí na výstupním pinu „OUT“, tedy cca na +0,2 V. Pokud se poté kontakt tlačítka opět mžikově uvolní, a to i opakovaně, nezvýší se napětí na vstupu „IN“ okamžitě na úroveň „1“ (jak by se stalo bez přítomnosti filtračního kondenzátoru C1), ale z počáteční hodnoty +0,2 V se zvyšuje postupně tak, jak se kondenzátor nabíjí přes pull-up rezistor ze zdroje Vcc. Smyslem filtračního RC obvodu je tedy po definovanou dobu odfiltrovat zákmity kontaktů tlačítka.

Časový interval mezi zákmity po stisku tlačítka se pohybuje v řádu jednotek ms, nejvýše do cca 5 ms. Hodnoty součástek obvodu, který bude filtrovat zákmity tlačítek, je proto vhodné navrhnout tak, aby se po mžikovém zákmitu tlačítka napětí na filtračním kondenzátoru C1 po tuto dobu udrželo na úrovni logické „0“, tedy pod +1,5 V. Velikost pull-up rezistoru je dána specifikacemi procesoru ATmega328P (uvažujeme 50 kΩ), hodnota napětí Vc na filtračním kondenzátoru při nabíjení ze zdroje Vcc je dána rovnicí Vc = Vcc-(Vcc x exp(-t/(R x C))).

Z této rovnice vyplývá, že při hodnotě pull-up rezistoru 50 kΩ, počátečním napětí +0,2 V, napájecím napětí +5,0 V a hodnotě filtračního kondenzátoru 220 nF (keramický kondenzátor 220nF / 50V je běžná položka v haléřové hodnotě) dosáhne výstupní napětí hodnoty 1,5 V po uplynutí 3,5 ms, což je v případě běžného kontaktu ideální stav. Pro odlišné hodnoty součástek lze tento časový interval spočítat on-line kalkulačkou na adrese ladyada.net/library/rccalc.html .

Rotační enkodér

Modul rotačního enkodéru
Modul rotačního enkodéru

Odlišný přístup je nutno použít v případě použití tzv. otočného inkrementálního ovladače (rotačního enkodéru). Rotační enkodéry, nebo také inkrementální otočné ovladače (rotary encoder), jsou „nekonečné“ obousměrné otočné přepínače, se kterými se setkáte například na kuchyňských spotřebičích (trouby, mikrovlnky), autorádiích nebo pokojových termostatech. V aplikacích platformy Arduino jej lze velmi dobře použít například k pohybu v menu Vašeho programu. Typický rotační enkodér má 10 nebo 20 kroků na otočení o 360° a většinou je vybaven i tlačítkem, které slouží k potvrzení Vaší volby.

Výstupní signál enkodéru
Výstupní signál enkodéru

Při otáčení ovladače enkodéru jsou na jeho výstupech dva číslicové signály, navzájem posunuté o čtvrtinu fáze, přičemž podle směru posunutí fáze lze určit směr otáčení (s dalšími podrobnostmi odkazuji na článek o programovém řešení obsluhy rotačního enkodéru, který také naleznete na tomto webu).

Zatímco typická doba stisku tlačítka se pohybuje v řádu sekund, tedy v době zcela postačující na to, aby bylo stisknutí tlačítka vyhodnoceno v rámci běžného běhu programu, v případě rotačního enkodéru je frekvence spínání kontaktů mnohem vyšší. Rychlé otočení ovladače enkodéru o 360° může trvat i pouhé 2 desetiny vteřiny (odzkoušeno); za tuto dobu dojde u typického enkodéru ke 2 x 40 přechodům výstupního signálu z „0“ na „1“ a zpět, přičemž každý z těchto přechodů je nutno vyhodnotit. Z uvedeného vyplývají 3 zásadní skutečnosti:

  • doba 5 ms (empiricky stanovený minimální časový interval mezi dvěma změnami výstupního signálu) již nedovoluje vyhodnocení pohybu rotačního enkodéru v rámci běžného běhu programu a je nutno využít tzv. přerušení (interrupt);
  • použití přerušení vyvolaného změnou signálu klade zvýšené nároky na odstranění zákmitů – v opačném případě by každý zákmit ovládacího signálu vyvolal další přerušení;
  • Připojení rotačního enkodéru
    Připojení rotačního enkodéru

    a konečně, v uvedeném případě je nutno časovou konstantu RC členu zkrátit. Je-li minimální doba mezi dvěma následujícími přerušeními cca 5 ms, je třeba uvažovat s časovou konstantou filtračního členu v rozmezí 0,5 – 1 ms, čemuž (při použití pull-up rezistoru) odpovídají hodnoty filtračního kondenzátoru 33 nF, 47 nF či 68 nF. Nižší hodnoty zaručí funkci obvodu i při velmi rychlém otočení enkodéru za cenu nižší spolehlivosti, vyšší hodnota je vhodná pro běžné situace.

A jak bylo uvedeno výše, s podrobnostmi ohledně programového řešení odkazuji na detailní článek změřený na obsluhu rotačního enkodéru, který naleznete na tomto webu.

Maticové a odporové zapojení klávesnice

Maticová klávesnice 4x4
Maticová klávesnice 4×4

Pokud potřebujete vyhodnotit sepnutí několika spínacích prvků, máte k dispozici dvě odlišná řešení:

  • buď výstup každého kontaktu připojit na jiný vstupní pin procesoru a postupně vyhodnocovat stav jednoho kontaktu za druhým;
  • nebo všechny kontakty zapojit do tzv. matice, kdy jsou všechny spínací prvky zapojeny z jedné strany k několika výstupním pinům procesoru a z druhé strany k jiným vstupním pinům procesoru tak, aby kombinace výstupního a vstupního pinu byla pro každý spínací prvek odlišná.

První řešení je velmi jednoduché jak z pohledu zapojení, tak struktury programu. V kterémkoli okamžiku stačí postupně vyhodnotit stav všech spínacích prvků.

Připojení klávesnice 3x4
Připojení klávesnice 3×4

Druhé řešení je o něco málo složitější, nicméně významným způsobem omezuje počet vstupních a výstupních vodičů procesoru, nutných k vyhodnocení většího počtu tlačítek. Zatímco v prvním případě je k vyhodnocení stavu 12 tlačítek či spínačů potřeba 12 vstupních vodičů, v případě maticového zapojení pak postačí vodičů 7 – 4 výstupní a 3 vstupní. Pro 16 tlačítek pak oproti 16 vstupům při lineárním zapojení postačí 4 výstupní a 4 vstupní piny. Při vyhodnocování je pak přiveden signál logické úrovně „0“ postupně na všechny sloupce matice a pro každý sloupec je vyhodnocen stav tlačítek ve všech řádcích. I zde je pochopitelně třeba vstupní piny přepnout do módu INPUT_PULLUP.

Odporové zapojení tlačítek
Odporové zapojení tlačítek

Pokud nemáte k dispozici již ani omezený počet vstupních a výstupních pinů pro připojení maticové klávesnice, lze použít zapojení tlačítek do odporového řetězce. Toto řešení vyžaduje vyšší počet součástek, avšak vystačí si s jediným analogovým vstupem. Po stisku některého z tlačítek dojde k uzemnění příslušného odporového děliče a tím k poklesu napětí na analogovém vstupu z původních +5,0 V na napětí, které odpovídá stisku některého z tlačítek. V uvedeném schématu je takto vyhodnocováno 5 tlačítek, jejichž stisknutí generuje na analogovém vstupu napětí (s malou tolerancí) 4,0 V / 3,0 V / 2,0 V / 1,0 V, resp. 0 V. Počet tlačítek je teoreticky omezen jen rozlišením A/D převodníku (10 bitů), tedy až na několik set tlačítek :) praktický limit je ovšem dán limitovaným počtem hodnot odporů v klasické odporové řadě E12 na přibližně 10 tlačítek.

Odporové zapojení tlačítek s přerušením
Odporové zapojení tlačítek s přerušením

Je-li po stisku tlačítka nutno generovat okamžitou odezvu, je možno přes diody sloučit kontakty tlačítek na druhý vstup procesoru, který se sestupnou hranou vyvolá přerušení programu.

Leave a Reply