3.11. Pergésmentesítés¶
A kapcsolót tökéletes nyitott vagy zárt érintkezőként szokás ábrázolni, ám egy valódi kapcsoló érintkezői nem váltanak tisztán a két állapot között. Pattognak – néhány ezredmásodpercen belül sokszor zárnak és bontanak elektromos kapcsolatot, mielőtt megállapodnának. A lábat olvasó GPIO bemenet ezt élek sorozataként látja; egy figyelmetlen lekérdező hurok egyetlen tényleges megnyomásra több „megnyomást” számol, egy megszakításkezelő pedig egyetlen megnyomásra többször fut le.
Egy pattogó kapcsoló a megállapodás előtt gyors átmenetek sorozatát hozza létre.¶
A pergésmentesítés a pattogás kiszűrésének gyakorlata, hogy minden fizikai megnyomás egyetlen eseményként jelenjen meg. Két megközelítés oldja meg ezt – a szoftveres (egy időzítési szabály a firmware-ben) vagy a hardveres (egy kis szűrő a vezetéken). Ezek nem zárják ki egymást.
3.11.1. Szoftveres pergésmentesítés¶
A lényeg, hogy megjegyezzük, mikor változott utoljára a bemenet, és elutasítsuk a további változásokat ezen időbélyeg rövid időablakán belül. Az érintkezőpattogás jellemzően 10 ms alatt tart; egy valódi megnyomás 50–100 ms-ig; egy 30–50 ms-os időablak minden pattogást elkap anélkül, hogy a valódi megnyomásokat blokkolná.
Egy lekérdező hurokban olvasd be a lábat, hasonlítsd össze az utolsó stabil értékkel, és csak akkor fogadj el változást, ha a pergésmentesítési időablak letelt:
import time
from machine import Pin
button = Pin("P0", Pin.IN, Pin.PULL_UP)
last_state = 1
last_change = 0
DEBOUNCE_MS = 50
while True:
now = time.ticks_ms()
state = button.value()
if state != last_state and time.ticks_diff(now, last_change) > DEBOUNCE_MS:
last_change = now
last_state = state
if state == 0:
do_action()
time.sleep_ms(10)
Megszakítás-vezérelt olvasásnál alkalmazd ugyanazt az időzítési szabályt a kezelőn belül, majd a valódi megnyomást add át a fő kontextusnak a micropython.schedule() segítségével (lásd GPIO bemenet):
import time
import micropython
from machine import Pin
button = Pin("P0", Pin.IN, Pin.PULL_UP)
last_irq = 0
DEBOUNCE_MS = 50
def handle_press(pin):
do_action()
def on_press(pin):
global last_irq
now = time.ticks_ms()
if time.ticks_diff(now, last_irq) < DEBOUNCE_MS:
return
last_irq = now
micropython.schedule(handle_press, pin)
button.irq(handler=on_press, trigger=Pin.IRQ_FALLING)
Az ISR időbélyeg alapján szűri a pattogásokat és sorba állítja a visszahívást; a handle_press a fő kontextusban fut, ahol a memóriafoglalás és a lassú I/O biztonságos.
3.11.2. Hardveres pergésmentesítés¶
A hardveres pergésmentesítés elektromosan szűri ki a pattogást, még mielőtt az elérné a lábat. A szokásos eszköz egy kondenzátor.
A kondenzátor egy kétkivezetéses alkatrész, amely elektromos töltést tárol. Fizikailag két, egymástól rövid távolságra tartott vezető lemez, amelyeket egy szigetelő (a dielektrikum) választ el.
Egy síkkondenzátor: két vezető, amelyeket egy szigetelő réteg választ el.¶
Ha feszültséget kapcsolunk a kapcsaira, az egyenlő nagyságú és ellentétes előjelű töltéseket hajt a két lemezre; az összefüggés a következő
Q = C × V
ahol a Q a tárolt töltés (coulombban), a V a kondenzátoron eső feszültség, a C pedig a kapacitása (faradban). A kapacitást az eszköz felépítése rögzíti; nagyobb kapacitás azonos feszültségen több tárolt töltést jelent.
A következmény: egy kondenzátor nem tudja azonnal megváltoztatni a feszültségét. A be- vagy kiáramló töltésnek át kell haladnia az útban lévő ellenálláson, és ez az ellenállás határozza meg, milyen gyorsan változhat a feszültség.
3.11.2.1. RC időállandó¶
Egy kondenzátor ellenálláson keresztüli feltöltése sima, exponenciális emelkedést eredményez a tápfeszültség felé, nem pedig ugrást. Ennek az emelkedésnek a jellemző ideje az RC időállandó:
τ = R × C
Egy τ elteltével a kondenzátor a tápfeszültség körülbelül 63 %-át éri el. 5 τ után már több mint 99 %-nál tart – gyakorlati szempontból „teljesen feltöltött”.
Egy kondenzátor exponenciális görbe mentén töltődik. A τ = RC az az idő, amely alatt eléri a végső feszültség 63 %-át.¶
Az ellenálláson keresztüli kisütés a tükörképet követi: a feszültség exponenciálisan csökken a kezdeti értékéről nulla felé, egy τ elteltével a kiindulási feszültség 37 %-ára, 5 τ után pedig 1 % alá esik.
Egy kondenzátor exponenciális lecsengés mentén sül ki. A τ = RC az az idő, amely alatt a kiindulási feszültség 37 %-ára esik.¶
3.11.2.2. A pergésmentesítő áramkör¶
Egy bemeneti láb és a föld közé kötött, soros ellenálláson keresztül táplált kondenzátor aluláteresztő szűrőt alkot. A gyors tüskéknek nincs idejük feltölteni vagy kisütni a kondenzátort ezen az ellenálláson keresztül; a láb közel marad ahhoz a feszültséghez, amelyen a tüske előtt volt. A lassú változások – egy szándékos megnyomás – feltöltik vagy kisütik a kondenzátort, és az olvasott érték követi azt.
Az R1 felhúzza a kapcsoló magas oldalát Vcc-re, így egy nyers, pattogó kapcsolójelet hoz létre. Az R2 és a C ezután aluláteresztő szűrővel szűri ezt a jelet a lábra:
Hardveres pergésmentesítés: az R2 és a C aluláteresztő szűrővel szűri a nyers kapcsolójelet, mielőtt az elérné a lábat.¶
Tipikus értékek: R1 = 10 kΩ (felhúzó), R2 = 10 kΩ (soros), C = 100 nF.
Amikor a kapcsoló nyitott, az áram a Vcc → R1 → R2 → kondenzátor (sorba kapcsolva) útvonalon folyik, és Vcc-re tölti a kondenzátort τ_charge = (R1 + R2) × C = 2 ms időállandóval.
Amikor a kapcsoló zár, a kapcsoló csomópontja a földre szorul, és a kondenzátor egyedül az R2 ellenálláson keresztül ürül erre a földre τ_discharge = R2 × C = 1 ms időállandóval.
Mindkét él RC-szűrt. Mivel a kondenzátor a saját csomópontján ül, az R2 után a kapcsoló felől nézve, tisztán leng a Vcc (nyitott) és 0 V (zárt) között – egyik esetben sem kell áramnak átfolynia az R1 ellenálláson állandósult állapotban.
3.11.3. Választás közöttük¶
A szoftveres az alapértelmezett. Nem kerül alkatrészbe, a küszöbérték könnyen hangolható, és bármelyik lábon működik, amelyet a CPU olvas.
A hardveres akkor éri meg az alkatrészeket, amikor a pattogás valami máshoz jut el, nem a CPU lekérdező kódjához – egy megszakításhoz, amely nem szabad, hogy kétszer lépjen működésbe, egy hardveres számlálóhoz, vagy egy saját szűrővel nem rendelkező perifériához.
A szoftveres és a hardveres pergésmentesítés békésen meg is fér egymás mellett: egy kis RC szűrő elnyomja a legrosszabb tüskéket, egy szoftveres pergésmentesítési időablak pedig lefedi a maradékot.