3.11. Eliminacja drgań styków#
Przełącznik rysuje się jako idealny styk otwarty lub zamknięty, ale styki rzeczywistego przełącznika nie przeskakują czysto między tymi dwoma stanami. Drgają – zwierają i rozwierają kontakt elektryczny wiele razy w ciągu kilku milisekund, zanim się ustabilizują. Wejście GPIO odczytujące pin widzi to jako serię zboczy; nieostrożna pętla odpytująca zlicza kilka „naciśnięć” dla jednego rzeczywistego naciśnięcia, a obsługa przerwania uruchamia się kilka razy na jedno faktyczne naciśnięcie.
Drgający przełącznik wytwarza serię szybkich przejść, zanim się ustabilizuje.#
Eliminacja drgań styków to praktyka filtrowania drgań tak, aby każde fizyczne naciśnięcie rejestrowało się jako pojedyncze zdarzenie. Rozwiązują to dwa podejścia – programowe (reguła czasowa w oprogramowaniu układowym) lub sprzętowe (mały filtr na przewodzie). Nie wykluczają się one wzajemnie.
3.11.1. Programowa eliminacja drgań#
Idea polega na zapamiętaniu, kiedy wejście ostatnio się zmieniło, i odrzucaniu dalszych zmian w krótkim oknie czasowym od tego znacznika czasu. Drgania styków trwają zwykle poniżej 10 ms; rzeczywiste naciśnięcie zajmuje 50 – 100 ms; okno 30 – 50 ms wychwytuje wszystkie drgania, nie blokując rzeczywistych naciśnięć.
W pętli odpytującej odczytaj pin, porównaj go z ostatnią stabilną wartością i akceptuj zmianę dopiero po upływie okna eliminacji drgań:
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)
W przypadku odczytów sterowanych przerwaniami zastosuj tę samą regułę czasową wewnątrz obsługi, a następnie przekaż rzeczywiste naciśnięcie do głównego kontekstu za pomocą micropython.schedule() (zobacz Wejście GPIO):
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)
ISR filtruje drgania na podstawie znacznika czasu i kolejkuje wywołanie zwrotne; handle_press działa z powrotem w głównym kontekście, gdzie alokacja i wolne operacje I/O są bezpieczne.
3.11.2. Sprzętowa eliminacja drgań#
Sprzętowa eliminacja drgań filtruje drgania elektrycznie, zanim w ogóle dotrą one do pinu. Standardowym narzędziem jest kondensator.
Kondensator to dwuzaciskowy element przechowujący ładunek elektryczny. Fizycznie są to dwie przewodzące płytki utrzymywane w niewielkiej odległości od siebie, oddzielone izolatorem (dielektrykiem).
Kondensator płaski: dwa przewodniki rozdzielone warstwą izolacyjną.#
Przyłożenie napięcia do jego zacisków wymusza powstanie równych i przeciwnych ładunków na obu płytkach; zależność ta wynosi
Q = C × V
gdzie Q to zgromadzony ładunek (kulomby), V to napięcie na kondensatorze, a C to jego pojemność (farady). Pojemność jest ustalona przez konstrukcję elementu; większa pojemność oznacza więcej ładunku zgromadzonego przy tym samym napięciu.
Konsekwencja: kondensator nie może zmienić swojego napięcia natychmiast. Ładunek wpływający lub wypływający musi przejść przez jakąkolwiek rezystancję znajdującą się na drodze, a ta rezystancja określa, jak szybko może zmieniać się napięcie.
3.11.2.1. Stała czasowa RC#
Ładowanie kondensatora przez rezystor wytwarza gładki wykładniczy wzrost w kierunku napięcia zasilania, a nie skok. Charakterystycznym czasem tego wzrostu jest stała czasowa RC:
τ = R × C
Po jednym τ kondensator osiąga około 63 % napięcia zasilania. Po 5 τ przekracza 99 % – w praktyce jest „w pełni naładowany”.
Kondensator ładuje się wzdłuż krzywej wykładniczej. τ = RC to czas potrzebny do osiągnięcia 63 % napięcia końcowego.#
Rozładowanie przez rezystor przebiega jak lustrzane odbicie: napięcie spada wykładniczo od swojej wartości początkowej w kierunku zera, opadając do 37 % napięcia początkowego po jednym τ i poniżej 1 % po 5 τ.
Kondensator rozładowuje się wzdłuż wykładniczego zaniku. τ = RC to czas potrzebny do spadku do 37 % napięcia początkowego.#
3.11.2.2. Układ eliminacji drgań#
Kondensator między pinem wejściowym a masą, zasilany przez rezystor szeregowy, tworzy filtr dolnoprzepustowy. Szybkie impulsy nie mają czasu, by naładować lub rozładować kondensator przez ten rezystor; pin pozostaje bliski napięciu, na którym był przed impulsem. Powolne zmiany – celowe naciśnięcie – ładują lub rozładowują kondensator, a odczyt podąża za nimi.
R1 podciąga wysoką stronę przełącznika do Vcc, wytwarzając surowy sygnał przełącznika, który drga. R2 i C następnie filtrują dolnoprzepustowo ten sygnał do pinu:
Sprzętowa eliminacja drgań: R2 i C filtrują dolnoprzepustowo surowy sygnał przełącznika, zanim dotrze on do pinu.#
Typowe wartości: R1 = 10 kΩ (podciąganie), R2 = 10 kΩ (szeregowy), C = 100 nF.
Gdy przełącznik jest otwarty, prąd płynie Vcc → R1 → R2 → kondensator (szeregowo), ładując kondensator do Vcc ze stałą τ_charge = (R1 + R2) × C = 2 ms.
Gdy przełącznik się zamyka, węzeł przełącznika zostaje zwarty do masy, a kondensator rozładowuje się przez sam R2 do tej masy ze stałą τ_discharge = R2 × C = 1 ms.
Oba zbocza są filtrowane RC. Ponieważ kondensator znajduje się na własnym węźle, za R2 od strony przełącznika, przełącza się on czysto między Vcc (otwarty) a 0 V (zamknięty) – w stanie ustalonym w żadnym przypadku przez R1 nie musi płynąć prąd.
3.11.3. Wybór między nimi#
Rozwiązanie programowe jest domyślne. Nie kosztuje nic w komponentach, próg łatwo dostroić, a działa na każdym pinie, który odczytuje CPU.
Rozwiązanie sprzętowe jest warte poniesienia kosztu części, gdy drgania docierają do czegoś innego niż kod odpytujący CPU – do przerwania, które nie może zadziałać podwójnie, do sprzętowego licznika, do urządzenia peryferyjnego bez własnego filtra.
Programowa i sprzętowa eliminacja drgań również dobrze współistnieją: mały filtr RC tłumi najgorsze impulsy, a programowe okno eliminacji drgań pokrywa to, co pozostało.