Taster Auslesen, Verständnisproblem, Wo muss der Code hin?

Hallo ihr Lieben, Hab ja schonmal eine Frage zu Tastern gestellt. Mittlerweile funktioniert es, aber ich habe eine Frage:

Wenn ich den Taster einmal drücke möchte ich die Funktion Simulation() starten. Wenn ich ihn zweimal in einem bestimmten Zeitraum drücke möchte ich die Funktion Menu() aufrufen.

Folgenden Code habe ich bereits. Vielleicht könnt ihr daran ja anknüpfen, oder jemand hat eine ganz andere Idee um o.g. Funktionsweise in Code umzuwandeln.

Variablen:

int tasterStatus;
int letzterTasterStatus = LOW;
long letzteEntprellZeit = 0;
long entprellVerzoegerung = 50;

Abfrage:

  int lesen = digitalRead(taster);
  if (lesen != letzterTasterStatus)
  {
    letzteEntprellZeit = millis();
    if (tasterStatus == HIGH) {
    Simulation();
    }
  }
  if ((millis() - letzteEntprellZeit) > entprellVerzoegerung)
  {
    tasterStatus = lesen;
  }
  letzterTasterStatus = lesen;
}

Im Moment komme ich wenn ich einmal den Taster drücke, zu Simulation(). Wie funktioniert das dann, wenn ich in Menu() will?

LG TimeMen

Hallo,
mache es doch mit einem Zähler

int Zähler;


  int lesen = digitalRead(taster);
  if (lesen != letzterTasterStatus)
  {
    letzteEntprellZeit = millis();
    if (tasterStatus == HIGH) {
    Zähler = 1;
    }
  }
  if ((millis() - letzteEntprellZeit) > entprellVerzoegerung)
  {
    tasterStatus = lesen;
Zähler = 2;
  }
  letzterTasterStatus = lesen;
}

if (Zähler == 1)
{
Simulation();
}
if (Zähler == 2)
{
Menu();
Zähler = 0;
}

Gruß und Spaß
Andreas

Hallo, das ging fix! Wie lange wäre dann der maximale Abstand zwischen den beiden Tastendrücken?

der maximale Abstand zwischen den beiden Tastendrücken

Mit unsigned long Variablen und millis() kriegst du gut 49 Tage hin.

Ob das Verfahren so funktioniert, hängt davon ab, ob Simulation() blockierend geschrieben wurde oder nicht.

Bei ersten Tastendruck springt er sofort in Simulation, ich fürchte den nächsten Tastendruck wird er nicht abfragen.

Man könnte aber auch eine gewisse Zeit warten, ob der Taster nochmal gedrückt wird, und dann erst die Funktionen aufrufen.

z.B. so:

const int TASTENPIN = 3;
const int TASTERWARTEZEIT = 1000;  // wie lange wird auf 2. Tastendruck gewartet
unsigned long t_Tastendruck;              // Zeitpunkt, wann der Taster zum ersten Mal gedrückt wurde.
byte zaehler;

void setup(){
//....
};

void loop() {
  if (tastendruck()){
    if (zaehler == 0){              // erster Tastendruck
      t_Tastendruck = millis();     // wann wurde die Taste zum ersten Mal gedrückt?
      zaehler = 1;
    }
    else zaehler = 2;                 // weiterer Tastendruck    
  }

  if (millis() - t_Tastendruck > TASTERWARTEZEIT) {   // Warten, ob Taster 2mal gedrückt wird.
    if      (zaehler == 1) {
       Simulation();
       zaehler = 0;
    }
    else if (zaehler == 2){
      Menu();
      zaehler = 0;
    }
  }    
} // end loop()

/*******************************************************************
 * Funktion tastendruck()
 * *****************************************************************
 * liest einen Taster ein.
 * Wurde dieser gedrückt, (Wechsel nicht gedrückt => gedrückt)
 * so wird true zurückgegeben
 ******************************************************************/
bool tastendruck(){
  static unsigned long letzteEntprellZeit;
  static bool letzterTasterStatus;
  if (millis() - letzteEntprellZeit < 50) return false; // erst nach 50ms wieder lesen.
  letzteEntprellZeit = millis();
  bool lesen = !digitalRead(TASTENPIN);              // Taster auf GND; Gedrückt: lesen = HIGH
  if (lesen && !letzterTasterStatus){              // Bei Änderung von LOW auf HIGH (Taster wurde gedrückt)
    letzterTasterStatus = lesen;
    return true;
  }
  else return false;  
} // end Funktion Tastendruck

Hallo Gunther,

Hab deinen Code jetzt mal verwendet, und dementsprechend ausgeführt. Für Simulation() und Menu() habe ich einfach verschiedene Blinksignale eingeführt.

Als ich den Code das erste Mal ausgeführt habe, und den Knopf einmal gedrückt habe, ist er sofort ins Menu() gegangen. Dann habe ich den Arduino resettet, und dann ist er automatisch in Simulation() gegangen. Keine Chance per doppeltem Knopfdruck ins Menu() zu gelangen.

LG TimeMen

Da hast du recht, ich hatte in der Funktion Tastendruck() den Zweig zum Rücksetzen der Variablen letzterTasterStatus vergessen. Das kommt davon, wenn man in der Arbeit mal schnell einen Code tippt, ohne ihn testen zu können.

So gehts:

const int TASTENPIN = 3;
const int TASTERWARTEZEIT = 1000;  // wie lange wird auf 2. Tastendruck gewartet
unsigned long t_Tastendruck;              // Zeitpunkt, wann der Taster zum ersten Mal gedrückt wurde.
byte zaehler;

void setup(){
  pinMode(TASTENPIN, INPUT_PULLUP);
  Serial.begin(115200);
//....
};

void loop() {
  if (tastendruck()){
    if (zaehler == 0){              // erster Tastendruck
      t_Tastendruck = millis();     // wann wurde die Taste zum ersten Mal gedrückt?
      zaehler = 1;
    }
    else zaehler = 2;                 // weiterer Tastendruck   
  }

  if (millis() - t_Tastendruck > TASTERWARTEZEIT) {   // Warten, ob Taster 2mal gedrückt wird.
    if      (zaehler == 1) {
       Simulation();
       zaehler = 0;
    }
    else if (zaehler == 2){
      Menu();
      zaehler = 0;
    }
  }   
} // end loop()

/*******************************************************************
 * Funktion tastendruck()
 * *****************************************************************
 * liest einen Taster ein.
 * Wurde dieser gedrückt, (Wechsel nicht gedrückt => gedrückt)
 * so wird true zurückgegeben
 ******************************************************************/
bool tastendruck(){
  static unsigned long letzteEntprellZeit;
  static bool letzterTasterStatus;
  if (millis() - letzteEntprellZeit < 50) return false; // erst nach 50ms wieder lesen.
  letzteEntprellZeit = millis();
  bool lesen = !digitalRead(TASTENPIN);              // Taster auf GND; Gedrückt: lesen = HIGH
  if (lesen && !letzterTasterStatus){              // Bei Änderung von LOW auf HIGH (Taster wurde gedrückt)
    letzterTasterStatus = lesen;
    return true;
  }
  if (!lesen && letzterTasterStatus){              // Bei Änderung von HIGH auf LOW (Taster wurde losgelassen)
    letzterTasterStatus = lesen;                   // letzterTasterStatus zurücksetzen    
  }
  else return false; 
} // end Funktion Tastendruck


void Simulation(){
  Serial.println("Einmal:  Simulation");
  };
void Menu(){  
  Serial.println("Zweimal: Menu");
  };

guntherb:
Da hast du recht, ich hatte in der Funktion Tastendruck() den Zweig zum Rücksetzen der Variablen letzterTasterStatus vergessen. Das kommt davon, wenn man in der Arbeit mal schnell einen Code tippt, ohne ihn testen zu können.

So gehts:

const int TASTENPIN = 3;

const int TASTERWARTEZEIT = 1000;  // wie lange wird auf 2. Tastendruck gewartet
unsigned long t_Tastendruck;              // Zeitpunkt, wann der Taster zum ersten Mal gedrückt wurde.
byte zaehler;

void setup(){
  pinMode(TASTENPIN, INPUT_PULLUP);
  Serial.begin(115200);
//…
};

void loop() {
  if (tastendruck()){
    if (zaehler == 0){              // erster Tastendruck
      t_Tastendruck = millis();    // wann wurde die Taste zum ersten Mal gedrückt?
      zaehler = 1;
    }
    else zaehler = 2;                // weiterer Tastendruck 
  }

if (millis() - t_Tastendruck > TASTERWARTEZEIT) {  // Warten, ob Taster 2mal gedrückt wird.
    if      (zaehler == 1) {
      Simulation();
      zaehler = 0;
    }
    else if (zaehler == 2){
      Menu();
      zaehler = 0;
    }
  } 
} // end loop()

/*******************************************************************

  • Funktion tastendruck()

  • liest einen Taster ein.
  • Wurde dieser gedrückt, (Wechsel nicht gedrückt => gedrückt)
  • so wird true zurückgegeben
    ******************************************************************/
    bool tastendruck(){
      static unsigned long letzteEntprellZeit;
      static bool letzterTasterStatus;
      if (millis() - letzteEntprellZeit < 50) return false; // erst nach 50ms wieder lesen.
      letzteEntprellZeit = millis();
      bool lesen = !digitalRead(TASTENPIN);              // Taster auf GND; Gedrückt: lesen = HIGH
      if (lesen && !letzterTasterStatus){              // Bei Änderung von LOW auf HIGH (Taster wurde gedrückt)
        letzterTasterStatus = lesen;
        return true;
      }
      if (!lesen && letzterTasterStatus){              // Bei Änderung von HIGH auf LOW (Taster wurde losgelassen)
        letzterTasterStatus = lesen;                  // letzterTasterStatus zurücksetzen   
      }
      else return false;
    } // end Funktion Tastendruck

void Simulation(){
  Serial.println(“Einmal:  Simulation”);
  };
void Menu(){ 
  Serial.println(“Zweimal: Menu”);
  };

Aber wichtiger wäre es für dich, zu verstehen wie das funktioniert.
Und: die oben beschriebene Struktur genügt zwar deinen Anforderungen, aber: Solange die Funktionen Simulation oder Menu ausgeführt werden, wird keine Taste abgefragt.