Arduino-Grundlagen: Taster abfragen
Wenn wir den Ablauf unseres Programms während der Laufzeit beeinflussen möchten, brauchen wir Eingabemöglichkeiten: ein Taster ist da die einfachste Lösung. Doch wer glaubt, einen Taster abzufragen, kann doch gar nicht so schwierig sein, der wird sein blaues Wunder erleben.
Der naive Ansatz
Sie kennen sicherlich noch die ganz einfache Schaltung aus einer Batterie, einem Taster und einer Glühlampe aus der Schule. Drückt man den Taster, wird der Stromkreis geschlossen und die Glühlampe leuchtet. Lässt man den Taster wieder los, ist der Stromkreis nicht mehr geschlossen und die Glühlampe leuchtet nicht mehr. Nun ja, bauen Sie doch einfach mal die nachfolgende Schaltung auf und laden Sie den Sketch auf Ihren Arduino hoch.
- Taster
- LED 5mm grün
- Widerstand 100 Ω
- Jumperkabel (5×)
Wenn Sie den Taster betätigen, schließt sich in der Tat der Stromkreis. Die am Taster anliegenden +5 V liegen bei gedrücktem Taster somit auch am digitalen Eingang des Arduino an, womit sich der Eingang auf HIGH befindet. Der Spaß beginnt, wenn man den Taster wieder loslässt. Wir erwarten LOW, doch tatsächlich ist kaum vorhersehbar, was passiert. Der Eingang kann auf HIGH bleiben, er kann auf LOW fallen oder er kann permanent zwischen LOW und HIGH hin- und herwechseln, was unsere LED zum Flackern bringt.
Der Grund dafür ist, dass wir bei geöffnetem Taster keine für ein LOW-Signal erforderliche Masse (0 V) anliegen haben, sondern der Eingang einfach offen ist. Da der Arduino schon auf winzige Ströme reagiert, reichen schon Spannungen aus, die zu den benachbarten Eingängen oder elektrischen Feldern in der Umgebung bestehen, um den Eingang auf HIGH zu schalten. Das Problem lässt sich einfach lösen, indem wir die mit dem Eingang des Arduinos verbundene Hälfte des Tasters auf Masse legen. Das ergibt bei ungedrücktem Taster ein perfektes LOW-Signal … und bei gedrücktem Taster einen Kurzschluss. Uups.
Der Pull-Down-Widerstand
Im Prinzip ist der Ansatz nicht schlecht, aber wir müssen noch einen kleinen Kniff einbauen, um einen Kurzschluss zu verhindern: wir setzen zwischen Masse und der Eingangsleitung einen hochohmigen Widerstand ein. Wird der Taster gedrückt, sorgt der Widerstand dafür, dass der Strom nicht zur Masse fließt und einen Kurzschluss erzeugt, sondern nur zum digitalen Eingang. Entsprechend liegen dort nun wieder +5 V an; der Eingang schaltet auf HIGH. Wird der Taster losgelassen, wird nun dagegen der Stromkreis vom digitalen Eingang über den Widerstand zur Masse geschlossen. Dass bedingt durch den Widerstand nur geringe Ströme fließen, ist dem Arduino, wie oben geschrieben, egal. Man sagt, der Widerstand zieht die Eingangsleitung nach unten auf Masse. Daher wird der Widerstand als Pull-Down-Widerstand bezeichnet.
Der genaue Wert des Pull-Down-Widerstands scheint eine Glaubensfrage zu sein, wenn man verschiedene Internetseiten vergleicht. Letztlich ist der Wert relativ beliebig. Er muss lediglich einerseits hochohmig genug sein, um keinen Kurzschluss zu erzeugen, andererseits nicht so hochohmig, dass die Stromstärke so stark begrenzt wird, dass der Arduino das LOW-Signal nicht mehr lesen kann. Ich habe bereits Werte von 1 kΩ bis 1 MΩ erfolgreich getestet, wahrscheilich funktionieren aber auch noch kleinere oder größere Werte. In der nachfolgenden Schaltung habe ich einen 100 kΩ-Widerstand verwendet, aber wenn Sie den gerade nicht zur Hand haben, tut es eben auch fast jeder andere Widerstand in Ihrer Sammlung.
- Taster
- LED 5mm grün
- Widerstand 100 kΩ
- Widerstand 100 Ω
- Jumperkabel (6×)
Der Pull-Up-Widerstand
Wer mag, kann das Prinzip auch umkehren. Verbindet man den Taster mit Masse anstatt mit +5 V und legt die Eingangsleitung über den Widerstand dafür auf +5 V anstatt auf Masse, liegen bei geöffnetem Taster jetzt die +5 V auf dem Eingang (HIGH). Schließt man den Taster, wird der Stromkreis zur Masse geschlossen und auf dem Eingang liegt ein LOW-Signal. Da der Widerstand in diesem Fall dafür zuständig ist, die Eingangsleitung von Masse auf +5 V hoch zu ziehen, nennt man den Widerstand hier Pull-Up-Widerstand. Natürlich lässt sich die Logik auch softwareseitig ändern. Daher ist es eher eine Geschmacksfrage, ob man sich für einen Pull-Down- oder Pull-Up-Widerstand entscheidet.
- Taster
- LED 5mm grün
- Widerstand 100 kΩ
- Widerstand 100 Ω
- Jumperkabel (6×)
Der interne Pull-Up-Widerstand
Da man letztlich bei jeder digitalen Eingabemöglichkeit mit einem solchen Widerstand arbeiten muss, besitzt der Arduino hardwareseitig bereits für jeden digitalen Eingang einen Pull-Up-Widerstand, den man softwareseitig aktivieren kann. Eine Ausnahme bildet der Pin 13: da hier boardseitig die Kontroll-LED angeschlossen ist, funktioniert der Pull-Up-Widerstand dort nicht korrekt.
Um den Pull-Up-Widerstand zu aktivieren, definiert man den Pin nicht als INPUT sondern als INPUT_PULLUP. Das war’s auch schon. Man muss nur noch bedenken, dass die Logik eines Pull-Up-Widerstands, wie oben geschrieben, vertauscht ist.
- Taster
- LED 5mm grün
- Widerstand 100 Ω
- Jumperkabel (4×)
Taster entprellen
Das direkte an- und ausschalten der LED funktioniert jetzt schon ganz gut. Häufig möchte man aber einen Taster zur dauerhaften Zustandsänderung nutzen. Also beispielsweise: einmal drücken, LED an, nochmal drücken, LED wieder aus. Klar, dazu brauchen wir nur eine globale Variable, die wir mit jedem Drücken des Tasters ändern. Weiterhin müssen wir bedenken, dass ein Tastendruck aus dem Drücken und dem anschließenden Loslassen besteht. Würden wir auf jedes LOW-Signal auf der Eingangsleitung reagieren, würde unsere LED während des Tastendrucks einige hundert- bis tausendmal ihren Zustand ändern. Auch das lässt sich mit einer globalen Variablen lösen. Probieren Sie doch den nachfolgenden Beispielsketch einmal aus, der mit dem internen Pull-Up-Widerstand arbeitet.
taster-abfragen-nicht-entprellt.ino
Sie werden vermutlich feststellen, dass der Taster seltsam unzuverlässig arbeitet. Manchmal reagiert der Taster wie gewünscht, manchmal scheint der Taster nicht zu reagieren, manchmal flackert die LED bei Tastendruck kurz. Was ist da los? Das Problem ist ein mechanisches. Unmittelbar bevor die Kontakte beim Drücken des Tasters vollständig geschlossen sind, gibt es einen kurzen Moment, indem die Kontakte so nah zueinander sind, dass sich immer wieder für einen winzigen Augenblick eine Spannung aufbaut und sofort darauf wieder einbricht. Das Gleiche passiert auch wieder beim Loslassen des Tasters. Während unser menschliches Auge zu träge ist, um das bei den vorherigen Beispielen wahrgenommen haben zu können, werden die Eingänge des Arduinos mit so hoher Frequenz abgefragt, dass es für den Arduino so scheint, als würde eine Person mit sehr zittrigen Händen auf den Taster drücken und damit gleich dutzendfache Zustandsänderungen mit einem Tastendruck verursachen.
Ein Taster sollte daher immer „entprellt“ werden. Es gibt dafür eine ganze Reihe von Ansätzen, die jedoch immer auf das Gleiche hinauslaufen: die Reaktion des Tasters träger zu gestalten. Man kann beispielsweise mit einem RS-Flipflop dafür sorgen, dass das erste LOW-Signal, was vom Taster kommt, kurzzeitig gefangen wird. Oder man nutzt einen Kondensator, der kurzzeitige Spannungsspitzen herausfiltert. Beim Arduino lohnen sich solche hardwareseitigen Entprellungen in aller Regel jedoch nicht, da es softwareseitig sehr einfach zu lösen ist. Warten. Richtig, nach dem ersten LOW-Signal warten wir einfach 10 Millisekunden (das ist meist völlig ausreichend), bevor wir unser Programm weiterlaufen lassen. So bekommt der Arduino vom Prellen des Tasters in der Zwischenzeit einfach nichts mehr mit.