Knapaflæsning og prelbekæmpelse
En mikrokontroller læser en knap som en digital indgang med to niveauer: HIGH eller LOW. En løs indgang må ikke efterlades elektrisk ubestemt; den kan opfange støj og skifte tilfældigt.
Tilslutning med intern pull-up
Den enkle løsning er at aktivere controllerens interne pull-up og forbinde knappen mellem GPIO og GND:
- Knap åben: pull-up holder indgangen HIGH.
- Knap trykket: knappen forbinder indgangen til GND, så den bliver LOW.
- Denne kobling kaldes aktiv-lav: LOW betyder trykket.
Kontaktprel
En mekanisk kontakt lukker ikke nødvendigvis rent én gang. Kontaktfladerne kan ramme hinanden flere gange i løbet af få millisekunder, så GPIO-indgangen hurtigt skifter HIGH/LOW, før den falder til ro. Programmet kan derfor komme til at tælle ét tryk som flere.
Prelbekæmpelse (debounce) kan laves i hardware eller software. Hardware kan fx bruge et RC-filter sammen med en Schmitt-trigger-indgang eller en dedikeret debounce-kreds. Software kan vente, til indgangen har været stabil længe nok, før en ny tilstand accepteres. Nedenfor vises softwaremetoden; et typisk startpunkt er 20–30 ms, men tiden afhænger af knappen og anvendelsen.
Kontrollér databladet for den konkrete 74HC14-variant: forsyningsspænding og tilladt logikniveau afhænger af komponentfamilien. Indgangen må ikke automatisk antages at være 3,3 V-tolerant.
Registrering ved tilstandsskift
Et tryk og et slip kan registreres som hver sin kant, altså som en ændring mellem HIGH og LOW. Med koblingen ovenfor og INPUT_PULLUP er indgangen aktiv-lav:
- Tryk: HIGH → LOW, en faldende kant (
FALLING). - Slip: LOW → HIGH, en stigende kant (
RISING). CHANGEbetyder begge kanter og kan derfor bruges til både tryk og slip.
millis()-eksemplet nedenfor opdager skift ved at sammenligne den nye stabile aflæsning med den tidligere. Det accepterer først kanten efter debounce-perioden og rapporterer derfor ét tryk eller slip, selv om kontakten har prellet.
Man kan også bruge GPIO-interrupts med attachInterrupt() og vælge FALLING, RISING eller CHANGE. Et interrupt på et råt knapsignal kan dog udløses flere gange af kontaktprel; filtrér signalet i hardware først, eller lad interruptet sætte et flag, som programmet debounce-behandler uden for interrupt-rutinen.
Hardware kan altså hjælpe: RC-filteret og Schmitt-triggeren vist ovenfor former prel til en ren digital overgang. Mikrokontrolleren kan derefter registrere den med almindelig polling eller et interrupt. En separat pulskreds er kun nødvendig, hvis kredsløbet også skal levere en kort puls i stedet for et stabilt HIGH/LOW-niveau.
Ikke-blokerende debounce med millis()
Her registreres en tilstand først, når den rå aflæsning har været uændret i debounce-perioden. Koden bruger ikke delay(), så resten af programmets loop kan fortsætte.
const byte buttonPin = 2;
const unsigned long debounceMs = 25;
int rawState = HIGH;
int stableState = HIGH;
unsigned long lastChangeMs = 0;
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
Serial.begin(9600);
}
void loop() {
int reading = digitalRead(buttonPin);
if (reading != rawState) {
rawState = reading;
lastChangeMs = millis();
}
if ((millis() - lastChangeMs >= debounceMs) && reading != stableState) {
stableState = reading;
if (stableState == LOW) {
Serial.println("Trykket");
} else {
Serial.println("Sluppet");
}
}
// Resten af programmet kan fortsætte her uden delay().
}
Vigtige detaljer
- Med
INPUT_PULLUPbetyder HIGH normalt åben og LOW trykket. Det er omvendt af en kobling med pull-down. - Vælg en debounce-periode, der passer til kontakten; for lang periode gør betjeningen langsom, for kort kan lade resterende prel passere.
- Hardware-debounce filtrerer signalet før GPIO-indgangen; software-debounce filtrerer de aflæste skift i programmet. Metoderne kan også kombineres.
- Debounce er ikke nødvendigvis nok mod kraftig elektrisk støj på lange ledninger. Brug passende ledningsføring og et dimensioneret hardwarefilter i støjende miljøer.
- For flere knapper skal hver knap have sin egen rå og stabile tilstand samt tidsmåling.
Kilder
- Arduino: Digital Pins – digitale indgange og INPUT_PULLUP.
- Arduino: Debounce on a Pushbutton – eksempel på kontaktprel og tidsbaseret filtrering.