Die erste Grundlage ist der Taster selber: Abfragen und entprellen.
Ich habe mit dem Auswerten des Tastendrucks angefangen. Das Programm erledigt später mehr, als nur auf die Taste zu warten, weshalb ich mich dafür entschieden habe, die Erfassung via Interrupt zu machen.
Die Grundlagen dazu habe ich schon in dem Beitrag Externer Interrupt am Arduino Nano beschrieben.
Wer damit anfängt Tasten am Arduinio oder generell am Mikrocontroller abzufragen, wird schnell entdecken, dass ein Tastendruck als viele kleine Signale in der Software ankommen, die Taste prellt. Das Verhalten ist normal und auch mit hochwertigen Tasten nicht zu verhindern.
Jetzt greift die Software ein und gibt dem Taster etwas Zeit sich zu „beruhigen“. Je nach Qualität reichen ein paar Millisekunden.
In meinem Versuchsaufbau verwende ich eine 08/15 Billigtaste vom Chinamann und habe schon bei älteren Projekten festgestellt, dass diese heftig prellt und mit der Einsatzdauer immer schlechter wird. Auf der sicheren Seite bin ich wenn ich der Software eine Zeitraum für einen Tastendruck von 150ms vorgebe.
Damit die Schaltung mit möglichst wenigen Bauteilen auskommt nutze ich den internen Pullup im Atmega.
/*
Projekt WinLock / Teil Tastenabfrage
Sperren des PC via Hotbutton
2022 by Alexander Jungchen
GNU GPL-3
*/
// Anschlüsse für die Status LED und den Taster
#define LED_PIN 10
#define BUTTON_PIN 7
// Zum Abfragen der Taste
volatile boolean drueckStatus = LOW;
volatile unsigned long letzterInterruptTimer = 0;
volatile unsigned long interruptTimer;
// Die LED soll bei jedem Tastendruck ihren Status (an/aus) wechseln.
// LOW, damit beim ersten Tastendruck die LED angeht.
boolean ledStatus = LOW;
void setup() {
pinMode(LED_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP); // INPUT_PULLUP, um den externen Widerstand zu sparen.
digitalWrite(LED_PIN, drueckStatus);
// Interrupt zum Entprellen der Taste deklarieren.
attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), HotButton, RISING );
}
void loop() {
// Jeder Tastendruck "dreht" die Anzeige um. Aus an wird aus und umgekehrt.
if (drueckStatus == HIGH) {
ledStatus = !ledStatus;
digitalWrite(LED_PIN, ledStatus);
drueckStatus = LOW;
}
}
void HotButton() {
interruptTimer = millis();
// Den LED Status ändern, wenn Taste ausgeprellt hat. 150ms sollten reichen
if (interruptTimer - letzterInterruptTimer > 50) {
drueckStatus = HIGH;
}
letzterInterruptTimer = interruptTimer;
}