1.2 - Taster entprellen

 
tasterintro 1.2
 
Ein Taster ist die einfachste Art um mit dem Arduino zu interagieren und gleichzeitig auch ein schönes Einstiegsbeispiel um in die Welt des Arduinos hinein zu schnuppern. 
Das betätigen eines Tasters kann auch so seine Probleme mit sich bringen. Genau gesagt, das schnelle mehrfache schalten des Tasters bei einem einzigen Druck darauf. Dieses Phänomen ist mechanischer Natur und wird  Prellen oder Nachprellen genannt.
Ich versuche euch das mal mit einem Beispiel zu erklären. 
Wenn man mit dem Arduino z.B. die Variable "Druckzähler" erstellt, die bei 0 startet und bei jedem druck auf den Taster um +1 addiert werden soll, wird das mit einem einfachen Taster Code nicht funktionieren. Der Arduino fragt den Tasterstatus (High oder Low) zig mal pro Sekunde ab und da sich der Status des Tasters durch einfaches Betätigen mehrfach ändert, wird die Variable nicht nur um +1 hochgesetzt, sondern z.B. von 0 auf 6. Jetzt haben wir das Problem, das unser Zähler nicht funktioniert.
 
 
achtungDieses Problem spielt bei einfachen Aufgaben wie eine LED leuchten lassen meistens keine Rolle, deshalb ist das entprellen auch nicht immer nötig.
 

 

Auf diesem Oszilloskop sieht man das Prellen des Tasters bei einem einzelnen Druck sehr gut.
Tastenprellen
         Quelle:Wikipedia
 
 
 
Im Normalfall kann man dieses Problem durch das einfügen eines kurzen delays nach der Abfrage des Tasterstatus umgangen werden.
 
if (tasterStatus == HIGH)
  {
    druckZaehler++;     
    delay(300);
  }

 
Allerdings funktioniert das bei zeitkritischen Funktionen oder parallelen Abfragen nicht, da so der komplette Ablauf des Programms um z.B. 300ms gestoppt wird und so alle Eingaben oder Ereignisse in dieser Zeit ignoriert werden. Für solche Anwendungsfälle ist dieses Beispiel gedacht.
 
 
 
 

Teileliste

 
 
 
 

Anschlussplan

 
anschlussplan 1.1     schaltplan 1.1     Taster schematisch
  
 
 
 

Code

 

// Konstanten
const int tasterPin = 2;          // Pin Nummer des Tasters
const int ledPin =  3;            // Pin Nummer der LED des Arduinos

// Variablen
int tasterStatus = LOW;           // aktuelles Signal vom Eingangspin
int tasterGedrueckt = 0;          // abfragen ob Taster gedrückt war
int lichtmodus = 0;               // festlegen der verschiedenen Lichtprogramme
int ledStatus = LOW;              // aktueller Zusatnd der LED
int entprellZeit = 200;           // Zeit für Entprellung, anpassen!

unsigned long tasterZeit = 0;     // Zeit beim drücken des Tasters
unsigned long ledMillis = 0;      // Zeit für den Blinkrythmus der LED


void setup()
{
  pinMode(ledPin, OUTPUT);      // LED Pin wird als Ausgang gesetzt
  pinMode(tasterPin, INPUT);    // Taster Pin wird als Eingang gesetzt
}


void loop()
{
  // Lesen des tasterPin
  tasterStatus = digitalRead(tasterPin);

  // Wenn der Taster gedrückt ist...
  if (tasterStatus == HIGH) 
  {
    tasterZeit = millis();      // aktualisiere tasterZeit
    tasterGedrueckt = 1;        // speichert, dass Taster gedrückt wurde
  } 

  // Wenn die gewählte entprellZeit vergangen ist und der Taster gedrückt war...
  if ((millis() - tasterZeit > entprellZeit) && tasterGedrueckt == 1)
    {
      lichtmodus++;             // lichtmodus wird um +1 erhöht
      tasterGedrueckt = 0;      // setzt gedrückten Taster zurück
    }
 
  
  //*************************************Leuchtprogramme**************************************
  
  // Wenn Lichtmodus 0 ist, blinke im 1000ms Rythmus
  if (lichtmodus == 0)
  {
    // Wenn 1000ms vergangen sind...
    if (millis() - ledMillis > 1000)
    {
      ledStatus = !ledStatus;             // kehre den letzten LED Zustand um (z.B LOW -> HIGH)
      digitalWrite(ledPin, ledStatus);    // Ausgabe am LED Pin
      ledMillis = millis();               // beginne die Zeitzählung von vorne
    }
  }

  // Wenn Lichtmodus 1 ist, blinke im 500ms Rythmus
  else if (lichtmodus == 1)
  {
    // Wenn 500ms vergangen sind...
    if (millis() - ledMillis > 500)
    {
      ledStatus = !ledStatus;             // kehre den letzten LED Zustand um (z.B LOW -> HIGH)
      digitalWrite(ledPin, ledStatus);    // Ausgabe am LED Pin
      ledMillis = millis();               // beginne die Zeitzählung von vorne
    }
  }

  // Wenn Lichtmodus 2 ist, blinke im 250ms Rythmus
  else if (lichtmodus == 2)
  {
    // Wenn 250ms vergangen sind...
    if (millis() - ledMillis > 250)
    {
      ledStatus = !ledStatus;             // kehre den letzten LED Zustand um (z.B LOW -> HIGH)
      digitalWrite(ledPin, ledStatus);    // Ausgabe am LED Pin
      ledMillis = millis();               // beginne die Zeitzählung von vorne
    }
  }

  // Wenn Lichtmodus 3 ist, leuchte durchgehend
  else if (lichtmodus == 3)
  {
    digitalWrite(ledPin, HIGH);           // LED leuchtet
  }
  
  // Wenn Lichtmodus 4 ist, LED aus
  else if (lichtmodus == 4)
  {
    digitalWrite(ledPin, LOW);            // LED ist aus
  }

  // Wenn der Lichtmodus auf 5 sprngt, setzte ihn wieder zurück auf 0 um von vorne zu beginnen
  else
  {
    lichtmodus = 0;
  }
}

 
Nach dem setzen der Konstanten und Variablen werden im setup noch die Ein- und Ausgänge deklariert.
Im loop angekommen wird als erstes der tasterPin ausgelesen, und das Ergebnis in der Variable tasterStatus gespeichert. Als nächstes wir mit einer if Abfrage geprüft, ob der Taster gedrückt wurde. Wenn ja, wird die aktuelle Zeit in der Variable tasterZeit gespeichert und die Variable tasterGedrueckt wird auf 1 gesetzt um zu registrieren, dass der Taster gerade gedrückt wurde.
In der nächsten if Abfrage, müssen zwei Bedingungen erfüllt sein, um die Aktion auszulösen. Erstens millis() - tasterZeit muss größer als 200 sein und ( && ) die Variable tasterGedrueckt muss 1 sein. Ist das der Falle, wird lichtmodus um +1 hochgezählt und tasterGedrueckt wieder auf 0 zurückgesetzt, damit die aktuelle if Abfrage erst wieder ausgeköst werden kann, wenn der Taster gedrückt wurde (die erste Bedingung bleibt ja weiterhin wahr). Damit wäre schon einmal der Teil des entprellens erklärt, fehlen nur noch die Lichtmodi.
 
Nun werden der lichtmodus, den wir vorher gewählt haben abgefragt.
Wenn lichtmodus 0 ist, wird mit if abgefragt ob 1000ms vergangen sind. Wenn ja wird zuerst der letzte Zustand der LED (LOW oder HIGH) umgekehrt um ein blinken der LED zu ermöglichen. Dann muss dieser Zustand per digitalWrite an die LED ausgegeben werden. Zuguter letzt wird die aktuelle Zeit in die Variable ledMillis gespeichert, um den nächsten Blinkzyklus zu ermöglichen.
Wenn lichtmodus 1 oder 2 ist, läuft es genauso wie gerade eben, nur das der Blinkzyklus 500ms bzw. 250ms sind.
Wenn lichtmodus 3 ist, leuchtet die LED per digitalWrite HIGH Befehl die LED durchgehend und bei lichtmodus 4 ist die LED aus.
Zu Schluss muss noch dafür gesorgt werden, dass der lichtmodus wieder auf 0 zurückspringt wenn er 5 oder größer wird, damit man die Leuchtprogramme wieder von vorne durchschalten kann.
 
 
 
 
Das war es auch schon  fertig
 
 
 
 
downloadbutton arduino
 
 
 
 
 
 
 
 

Seitennavigation
 
arrow button prev               arrow button up                           

Einen Kommentar verfassen

Als Gast kommentieren

0
  • Gast - Frank

    Hallo
    Klasse Arbeit,
    Ist es irgendwie möglich den Sketch so um zu schreiben das wenn ich den Taster betätige die LED nicht blinkt sondern dauerhaft für eine eine gewisse Zeit X leuchtet, danach automatisch ausgeht. bzw den dauerhaften Zustand mit erneuten drücken des Tastes aufhebt und die LED ausgeht.
    Und beim erneuten drücken des Tasters geht der Timer "X" wieder von vorne los. Und die LED leuchtet wieder.

    Ich krieg das einfach nicht hin.

  • Gast - Valerius

    Hallo
    Fielen Dank für deine Mühe. Hat mir jetzt sehr weiter geholfen.

  • Gast - Teslatic

    Vielen Dank für die Mühe. Ein nicht entprellter Taster hätte mich beinahe in den Wahnsinn getrieben.

  • Gern geschehen :)

  • vielen dank für diese wunderbare arbeit!