Zum Hauptinhalt springen

Einen Taster mit Arduino abfragen

Ein Taster ist ein elektrisches Bauteil, welches einen Stromkreis schließen und unterbrechen kann. Mit ihm ist es möglich, auf einfachste Weise mit dem Arduino zu interagieren, dem Arduino zum Beispiel den Befehl zu geben, eine LED ein- oder auszuschalten.

Eine LED mit Taster steuern

In diesem Abschnitt wird erklärt,

  • mit welcher Schaltung ein Taster korrekt an den Arduino angeschlossen wird,
  • mit welchem Arduino-Befehl der Zustand des Tasters abgefragt werden kann
  • und wie diese Information genutzt wird, um zum Beispiel eine LED zu schalten.

Einen Taster mit dem Arduino verbinden

Taster ohne Pullup-Widerstand

Die einfachste Möglichkeit, einen Taster anzuschließen, wäre, ihn direkt mit einer Spannungsquelle (Vcc) und einem Arduino-Pin zu verbinden (Abb. links). Ein digitaler Arduino-Pin, welcher als Input konfiguriert ist, weist einen sehr hohen Innenwiderstand (100 MΩ\approx 100 \text{ M}\Omega) auf. Wird der Taster nun gedrückt, so würde die gesamte Spannung am Eingangspin abfallen. In unserem Beispiel also ca. 5V am Pin 3.

Ist der Taster jedoch offen, so wäre das Potential am Eingangspin unbestimmt oder auch schwebend (engl.: floating) und nicht, wie man annehmen könnte, null. In Abhängigkeit von der Umgebung (z.B. eine Hand, die sich der Schaltung nähert) ändert sich die anliegende Spannung, und der Zustand des Pins ist unvorhersehbar (HIGH oder LOW).

Um das zu ändern, müsste der Pin außerdem mit der Masse verbunden werden. In der rechten Abbildung ist genau das geschehen, nur mit dem Unterschied, dass der Taster zwischen dem Pin und der Masse liegt. Ist der Taster offen, wäre alles in Ordnung (am Pin liegen dann Vcc = 5V). Problematisch wird es aber, wenn der Taster gedrückt wird. Dann entsteht ein Kurzschluss zwischen Vcc und GND, was unbedingt vermieden werden sollte.

Taster mit Pullup-Widerstand verbinden

Pullup-Widerstand an einem Taster

Zum Verhindern eines Kurzschlusses beim Schließen des Tasters wird zwischen Vcc und dem Taster ein Widerstand eingefügt. Ist der Taster offen, wird die Eingangsspannung des Pins auf die angeschlossene Spannung Vcc hochgezogen, ohne dass es einen Kurzschluss gibt. Daher auch der Name Pullup-Widerstand. Ist der Taster geschlossen, so ist der Pin direkt mit der Masse verbunden und die Spannung beträgt 0V.

Geeignete Werte für einen Pullup-Widerstand sind Rpull=10kΩ 50kΩR_\text{pull} = 10\, k\Omega\ \cdots 50\, k\Omega.

pinMode(pin,INPUT)

Damit der Arduino weiß, dass der mit dem Taster (und dem Pullup-Widerstand) verbundene Pin als Eingang betrieben wird, muss dies dem Arduino mit dem Befehl pinMode(pin,INPUT) mitgeteilt werden. Der Befehl konfiguriert den angegeben pin als Eingang (INPUT).

#define PIN_TASTER 3  
pinMode(PIN_TASTER, INPUT); // Pin als Eingang

Die Konfiguration mit pinMode() sollte immer in der void setup() Funktion durchgeführt werden.

Interner Pull-Up Widerstand

Alternativ zu einem externen Pullup-Widerstand, der extra in die Schaltung eingefügt werden muss, gibt es beim Arduino auch die Möglichkeit, einen internen Pullup-Widerstand zu verwenden. Jeder Eingangspin des Arduinos besitzt einen zuschaltbaren Pullup-Widerstand, der vom Benutzer aktiviert werden kann. Ist der interne Pullup-Widerstand wie in der folgenden Abbildung aktiviert, kann ein Taster über die Masse (GND) direkt mit einem Eingangspin des Arduinos verbunden werden. Ein zusätzlicher externer Pullup-Widerstand wird dann nicht mehr benötigt.

Interner Pullup-Widerstand beim Arduino

Mit dem Befehl pinMode() und dem Parameter INPUT_PULLUP wird der interne Pullup-Widerstand für den angegebenen Pin aktiviert.

/* INTERNEN Pullup-Widerstand aktivieren */
#define PIN_TASTER 3
pinMode(PIN_TASTER, INPUT_PULLUP); // Eingang mit Pullup-Widerstand konfigurieren
caution

Ein Taster sollte immer mit einem Pullup- oder Pulldown-Widerstand verwendet werden, da der Spannungszustand des Taster-Pins sonst nicht stabil ist und der Zustand des Eingangspins sich zufällig ändern kann.

Aufgaben
  1. Was passiert, wenn ein Taster direkt (also ohne Pullup-Widerstand) mit dem Arduino verbunden wird.
  2. Ein Taster ist mit einem Pullup-Widerstand mit dem Arduino verbunden. Welches Level (HIGH oder LOW) liegt am Arduino an, wenn der Taster offen bzw. geschlossen ist? Erläutern Sie Ihre Antwort.
  3. In der Abbildung ist ein Pull-Down-Widerstand dargestellt. Analysieren Sie, welchen Zustand (Spannung) der angeschlossene Pin aufweist, wenn der Taster a) geschlossen und b) geöffnet ist. (Begründung nicht vergessen.)Pulldown-Widerstand beim Taster

Tasterzustand auslesen

Nachdem der Taster entweder mit einem externen oder einem internen Pull-Up-Widerstand angeschlossen wurde, kann der Zustand des Tasters, also ob er offen oder geschlossen ist, mit der Funktion digitalRead() ausgelesen werden:

digitalRead(pin)

Liest den digitalen Zustand eines Pins ein und gibt entsprechend der Spannung am Pin als Rückgabewert LOW (0) oder HIGH (1) zurück.

bool zustandTaster = digitalRead(PIN_TASTER); // Tasterzustand einlesen

Programm zum Auslesen des Tasterzustands (interner Pullup-Widerstand)

In dem folgenden ersten Beispielprogram für einen Taster, wird der Taster mit einem internen Pullup-Widerstand betrieben, weshalb der Taster einfach nur über Masse (GND) mit dem Arduinopin (hier Pin 3) verbunden wird. Das der interne Pullup-Widerstand aktiviert verwendet werden soll, muss dem Arduino mit dem Befehl pinMode(PIN_TASTER, INPUT_PULLUP) mitgeteilt werden.

Taster mit internem Pullupwiderstand verbunden

Das folgende Programm liest in der loop()-Funktion regelmäßig den Zustand des Tasterpins aus und sendet den Zustand des Tasters zum seriellen Monitor.

https://wokwi.com/arduino/projects/319082549116666451
/* Einfaches Beispiel zum Einlesen des Tasterzustandes */

# define PIN_TASTER 3 // Pin Taster

void setup() {
Serial.begin(115200);
pinMode(PIN_TASTER, INPUT_PULLUP); // Eingang mit Pullup-Widerstand
}
void loop() {
bool zustandTaster = digitalRead(PIN_TASTER); // Tasterzustand einlesen

Serial.print("Zustand Taster: ");
Serial.println(zustandTaster);
}
Aufgaben
  1. Bauen Sie eine Schaltung mit einem Taster (interner Pullup-Widerstand) und einer LED auf. Ändern Sie das Programm so, dass die angeschlossene LED solange leuchtet, wie der Taster nicht gedrückt ist. Ist der Taster gedrückt, soll die angeschlossene LED ausgehen. Verwenden Sie keine if-else-Verzweigung.

Die if Verzweigung - Eine bedingte Anweisung

Hat man den Status eines Tasters eingelesen, möchte man in aller Regel den weiteren Programmablauf vom Tasterzustand abhängig machen. Hierfür eignet sich die if Verzweigung als bedingte Anweisung.

drawing

Nach dem Schlüsselwort if folgt in Klammern eine Bedingung. Diese Bedingung kann zum Beispiel ein Vergleich zahl==1 oder zahl>1 sein. Ist die Bedingung wahr, also true, dann wird der in geschweiften Klammern { ... } stehende Code ausgeführt.

int zahl = 6;

if( zahl > 6 )
{
Serial.println("Die Zahl ist größer als 6.");
}

if ... else if ... else

Oft kommt es aber vor, dass in einem Programm viele verschiedene Verzweigungen benötigt werden, wobei für jede einzelne Verzweigung eine Bedingung benötigt wird. Hierfür stehen die Schlüsselwörter else if und else zur Verfügung.

drawing

Ist die Bedingung einer if Anweisung nicht erfüllt, so wird als nächstes überprüft, ob eine else if Anweisung gegeben ist und ob deren Bedingung erfüllt ist. In einer if Verzweigung können beliebig viele else if Anweisungen angegeben werden, welche alle nacheinander abgearbeitet werden.

Mit dem abschließenden Schlüsselwort else können Anweisungen für den Fall angegeben werden, dass keine der bei if oder else if angegebenen Bedingungen wahr ist.

int zahl = 6;

if( zahl < 6 )
{
Serial.println("Die Zahl ist kleiner als 6.");
}
// Bedingung können mit && als logisches UND verknüpft werden
else if( (zahl >= 6) && (zahl <= 10))
{
Serial.println("Die Zahl liegt zwischen 6 und 10.");
}
else // ohne Bedingung
{
Serial.println("Die Zahl ist größer als 10.");
}
caution

Sobald eine Bedingung in einer if ... else if Verzweigung erfüllt ist, wird der zugehörige Code ausgeführt. Weitere, noch nicht überprüfte Bedingungen werden ignoriert und nicht mehr überprüft.

Taster-Beispiel mit externem Pullup-Widerstand und if ... else Verzweigung

Im folgenden Beispiel soll exemplarisch der Zustand eines Tasters vom Arduino ausgelesen und mit einer if ... else Verzweigung drauf reagiert werden. Ist der Taster gedrückt, soll eine angeschlossene LED aufleuchten, ist er nicht gedrückt, soll nichts passieren.

drawing
https://wokwi.com/arduino/projects/319152604722496082
// Einfaches Beispiel zum Einlesen des Tasterzustandes 
// Taster benötigt einen externen Pullup-Widerstand.

# define PIN_LED 3 // Pin LED
# define PIN_TASTER 8 // Pin Taster

void setup() {
pinMode(PIN_LED, OUTPUT); // Pin als Ausgang definieren
pinMode(PIN_TASTER, INPUT); // Pin als Eingang definieren (externer Pullup-Wid.)
}
void loop() {
int zustandTaster = digitalRead(PIN_TASTER); // Tasterzustand einlesen

// Prüfen des Tasterzustandes:
if (zustandTaster == LOW) { //wenn gedrückt (LOW) ...
digitalWrite(PIN_LED, HIGH); // LED anschalten
} else { // sonst ...
digitalWrite(PIN_LED, LOW); // ansonsten LED ausschalten
}
}
Aufgaben
  1. Ändern sie das Beispielprogramm so, dass beim Drücken des Tasters eine angeschlossene LED blinkt (1 Sekunde an, 1 Sekunde aus). Verhält sich ihr Programm, wie Sie es erwarten?

  2. Ändern Sie die obige Beispielschaltung und nutzen Sie anstelle des externen, einen internen Pullup-Widerstand. Ändern Sie hierfür auch den Programmcode.

  3. Ändern Sie die obige Beispielschaltung (ohne Änderung im Programmcode) so, dass die LED beim Drücken des Tasters ausgeschaltet wird. Sie also leuchtet, wenn der Taster nicht gedrückt ist. Bauen sie die Schaltung auf und dokumentieren Sie diese z.B. mit Fritzing.

  4. Bauen Sie eine Schaltung mit zwei LEDs und zwei Tastern auf. Schreiben Sie anschließend ein Programm mit folgenden Eigenschaften:

    1. Die erst LED leuchtet, wenn der Taster 1 gedrückt ist.
    2. Die zweite LED leuchtet, wenn der Taster 2 gedrückt ist.
    3. Beide LEDs leuchten, wenn beide Taster gedrückt sind.
    4. Verwenden Sie nur eine if ... else if ... else if ... else Verzweigung.
  5. Schreiben Sie ein Programm, welches mit Serial.print() auf dem seriellen Monitor alle Zahlen von 0 bis 100 ausgibt. Als Ausnahme soll jedoch für jede Zahl, die durch 3 teilbar ist, Fizz und für jede Zahl, die durch 5 teilbar ist, Buzz ausgegeben werden. Wenn Ihr Programm funktioniert, erweitern Sie es so, dass es FizzBuzz ausgibt, wenn die Zahl durch 3 und 5 teilbar ist.

    Hinweis: Verwenden Sie den Modulo-Opertor % für die Division mit Rest.

Warten auf eine Tastereingabe mit der while-Schleife

Manchmal ist es ganz gut, wenn ein Programm solange pausiert, bis ein Taster gedrückt wird. Wird der ausgelesen Wert des Tasters als Bedingung für eine while-Schleife verwendet, kann genau das erreicht werden.

https://wokwi.com/arduino/projects/319081873886151252
// Mit einer while-Schleife auf eine Tastereingabe warten.

#define TASTER 11
void setup() {
pinMode(TASTER, INPUT_PULLUP);
Serial.begin(115200);
}

void loop() {
// Die while-Schleife wird beendet, wenn der Taster gedrückt wurde.
while(digitalRead(TASTER)){ }

Serial.println("Der Taster ist gedrückt.");
}

Ein Taster zum Umschalten

Wird mit einem Taster eine LED gesteuert, so sollte die LED beim ersten Drücken des Tasters angehen und beim zweiten Drücken wieder ausgehen. Anstatt also die LED einfach anzuschalten, wenn der Taster gedrückt ist, muss sich das System den Zustand der LED und des Tasters merken und entsprechend den Zustand der LED ändern.

In dem folgenden unvollständigen Programm wird der Zustand der LED mit der Variable statusLED gespeichert. Damit des Programm zusätzlich erkennen kann, ob der Taster gerade gedrückt wurde, es also eine Zustandsänderung des Tasters von nicht gedrückt (1) zu gedrückt (0) gibt, werden zwei zusätzliche boolsche Variablen statusTaster und statusTasterLetzter benötigt.

Zum Überprüfen, ob der Taster gerade gedrückt wurde, muss in der loop() Funktion der aktuelle Tasterzustand mit dem Tasterzustand beim letzten Aufruf von loop() verglichen werden. Hat sich der Zustand geändert, wird anschließend überprüft, ob der Taster aktuell gedrückt ist. Wenn dem so ist, kann dann die LED umgeschaltet werden.

// Unvollständiger Code für eine tastergesteuerte LED.

#define TASTER 3 // Taster-Pin mit Pull-UP Widerst. (LOW = gedrückt)
#define LED 13 // an Schaltung anpassen

bool statusLED = LOW; // aktueller Status der LED
bool statusTaster = HIGH; // aktueller Status des Taster
bool statusTasterLetzter = HIGH; // vorheriger Status des Tasters

void setup(){
// TASTER mit Pull-UP-Widerstand konfigurieren
// LED konfigurieren
}

void loop(){
statusTaster = digitalRead(TASTER); // Taster-Pin einlesen

// WENN (aktueller Tasterstatus anders ist als der letzte Tasterstatus)
// WENN (Taster gedrückt)
// Status der LED ändern (statusLED)

statusTasterLetzter = statusTaster; // aktualisieren des letzten Tasterstatus
digitalWrite(LED,statusLED);
}
Aufgaben
  1. Lesen Sie den unvollständigen Programmcode für eine umschaltbare LED sorgfältig durch und ergänzen Sie die fehlenden Programmteile. Sollte sich die LED nicht verhalten wie gewünscht, nutzen Sie die serielle Schnittstelle zum Debuggen.

  2. Fügen Sie in Ihr Programm eine Zählvariable ein, welche bei jedem Betätigen des Tasters um eins erhöht wird. Geben Sie den Wert der Zählvariable über die serielle Schnittstelle auf dem PC aus. Nutzen Sie für die serielle Schnittstelle eine hohe Baudrate (115.200 baud).

    Analysieren Sie das Verhalten der Zählvariablen.