2014-03-04 verschiedene Software Lösungen

Absatz:

keinBild

Links:

verwandte Themen:

Lets discuss the problems: If you are into detecting high speed things and need interrupts to react on something, this is not your solution. It won’t work. Don’t use it. Period.

Beispiel mit Interrupt

// Tasten Interrupt mit Entprellung
//
// Matthias Busse Version 1.0 vom 26.10.2014

int LED=13;
volatile unsigned long alteZeit=0, entprellZeit=20;

void setup() {
  pinMode(LED, OUTPUT);    // LED Pin
  pinMode(2, INPUT);       // Pin 2 ist INT0
  digitalWrite(2, HIGH);   // interner Pull up Widerstand auf 5V
  attachInterrupt(0, interruptRoutine, LOW);
  // Pin 2 (INT 0) geht auf 0V (LOW) dann interruptRoutine aufrufen
}

void loop() {
  delay(1000);             // Dauerschleife
}

void interruptRoutine() {
  if((millis() - alteZeit) > entprellZeit) { 
    // innerhalb der entprellZeit nichts machen
    digitalWrite(LED, !digitalRead(LED)); // LED umschalten
    alteZeit = millis(); // letzte Schaltzeit merken      
  }
}

Beispiel 2

 
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 lmodus 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 lmodus, den wir vorher gewählt haben abgefragt. Wenn lmodus 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 lmodus 1 oder 2 ist, läuft es genauso wie gerade eben, nur das der Blinkzyklus 500ms bzw. 250ms sind. Wenn lmodus 3 ist, leuchtet die LED per digitalWrite HIGH Befehl die LED durchgehend und bei >lmodus 4 ist die LED aus. Zu Schluss muss noch dafür gesorgt werden, dass der lmodus wieder auf 0 zurückspringt wenn er 5 oder größer wird, damit man die Leuchtprogramme wieder von vorne durchschalten kann.

// 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 lmodus = 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)
    {
      lmodus++;             // lmodus wird um +1 erhöht
      tasterGedrueckt = 0;      // setzt gedrückten Taster zurück
    }
 
  
  //*************************************lmodusprogramme**************************************
  
  // Wenn lmodus 0 ist, blinke im 1000ms Rythmus
  if (lmodus == 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 lmodus 1 ist, blinke im 500ms Rythmus
  else if (lmodus == 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 lmodus 2 ist, blinke im 250ms Rythmus
  else if (lmodus == 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 lmodus 3 ist, leuchte durchgehend
  else if (lmodus == 3)
  {
    digitalWrite(ledPin, HIGH);           // LED leuchtet
  }
  
  // Wenn lmodus 4 ist, LED aus
  else if (lmodus == 4)
  {
    digitalWrite(ledPin, LOW);            // LED ist aus
  }

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

Auszug Kern


  tasterStatus = digitalRead(tasterPin);
  if (tasterStatus == HIGH) {
    tasterZeit = millis();      // aktualisiere tasterZeit
    tasterGedrueckt = 1;        // speichert, dass Taster gedrückt wurde
  } 
  if ((millis() - tasterZeit > entprellZeit) && tasterGedrueckt == 1){
    lmodus++;                 // Aktion ausführen
    tasterGedrueckt = 0;      // setzt gedrückten Taster zurück
  }

3 Tasten auslesen
3 Tasten werden einseitig an GND geschaltet und die andere Seite kommt an A0, A1 und A2.
Die Analogeingänge werden als Eingang geschaltet und mit digitalWrite(A0,HIGH); wird der interne
Pullup Widerstand von 20kOhm zu +5V eingeschaltet. Dann wird immer 5V oder der Digitalwert 1023
gelesen. Nur wenn der Taster gedrückt ist, wird 0V oder der digitale Wert 0 gelesen.

Meine Schwelle lege ich auf 500, darunter ist die Taste gedrückt, darüber nicht.


// 3 Taster einlesen und die LED verschieden oft blinken lassen
//
// Matthias Busse Version 1.0 vom 17.10.2014

int LED=13, festgedrueckt=150, t=200;;

void setup() {
  pinMode(LED, OUTPUT);       // LED Ausgang
  pinMode(A0,INPUT);          // Taste 0 
  digitalWrite(A0,HIGH);      // interner pullup Widerstand
  pinMode(A1,INPUT);          // Taste 1
  digitalWrite(A1,HIGH); 
  pinMode(A2,INPUT);          // Taste 2
  digitalWrite(A2,HIGH); 
}

void loop() {
  if(readButton(0)) blink(2); // bei Taste 0 2x blinken
  if(readButton(1)) blink(3); // bei Taste 1 3x blinken
  if(readButton(2)) blink(4); // bei Taste 2 4x blinken
}

int readButton(int pin) {     // Taste einlesen
  if(analogRead(pin) < 500) { // Analog Eingang abfragen
    delay(festgedrueckt);            
    if(analogRead(pin) < 500)
      return 1;               // war gedrückt
  }
  return 0;                   // war nicht gedrückt
}
  
void blink(int anz) {         // LED x-mal blinken lassen
  for(int i=0; i < anz; i++) {
    digitalWrite(LED, HIGH);  // LED an
    delay(t);                 // warten
    digitalWrite(LED, LOW);   // LED aus
    delay(t);    
  }
}