Gleichzeitige Knopfabfrage über bestimmte Zeitdauer

Hallo,

in einem meiner Projekte wird über die aktuelle Bounce-Library (Version 1.6) der Status mehrerer Knöpfe abgefragt.

Dies funktioniert soweit (gekürzter Code weiter unten).

Nun möchte ich jedoch zusätzlich folgende Funktionalität implementieren:

“Wenn Knopf 1 und 2 gleichzeitig über einen Zeitraum von fünf Sekunden gedrückt gehalten werden soll X passieren.”

Hier steht zwar etwas bzgl. einer zeitdauerabhängigen Abfrage, doch leider kann ich damit noch nicht wirklich viel anfangen:

http://playground.arduino.cc/code/bounce

Insbesondere unsigned long duration(void) verstehe ich in diesem Zusammenhang nicht.

Vielleicht kann mir ja Einer auf die Sprünge helfen…?

Gruß Chris

#include <Bounce.h>

byte prellzeit = 10;                                          // Global festgelegte Entprellzeit für alle Knöpfe

byte Knopf_1 = 3;                                             // Knopf_1 ist am definierten Anschluss
boolean val_1;                                                // Bouncerrückgabewert für Knopf 1
boolean Knopf_1_State;                                        // Zustand Knopf 1
Bounce Knopf_1_Bouncer = Bounce( Knopf_1,prellzeit);          // Aktivierung der Entprellfunktion für Knopf 1

byte Knopf_2 = 4;                                             
boolean val_2;                                                   
boolean Knopf_2_State;
Bounce Knopf_2_Bouncer = Bounce( Knopf_2,prellzeit);

void setup()
{
  pinMode(Knopf_1, INPUT);
  pinMode(Knopf_2, INPUT);
}

void loop()
{

Knopf_1_Bouncer.update ( );                                  // Abfrage des "Knopf_1_Bouncer"-Wertes.

val_1 = Knopf_1_Bouncer.read();                              // Bouncerrückgabewert für Knopf_1 wird in "val_1" gespeichert

if (val_1 != Knopf_1_State)                                  // Nur dann (<-!), wenn sich der eingelesene Bouncerrückgabewert (also "val_1") gegenüber "Knopf_1_State" geändert hat.. 
{                          
  if (val_1 == HIGH)                                         // ..und dieser nun "HIGH" ist..
  {                                                          // ..soll "etwas" passieren
  }
}
Knopf_1_State = val_1;

Knopf_2_Bouncer.update ( );

val_2 = Knopf_2_Bouncer.read();

if (val_2 != Knopf_2_State)
{                          
  if (val_2 == HIGH)        
  {
  }
}
Knopf_2_State = val_2;

}

Vielleicht hilf dir mein Code-Schnipsel weiter. http://forum.arduino.cc/index.php?topic=191821.msg1417660#msg1417660 Hatte ich heute Mittag in einem anderen Fred gepostet. Damit kannst du abfragen wie lange der Tastendruck dauert. Geht so wie es da steht zwar nur mit einem Taster, ließe sich aber sicherlich entsprechend leicht umstricken.

Wenn Du Knopf 1 und 2 nicht getrennt auswerten musst, dann schalte sie doch einfach in Reihe und Werte dadurch immer beide zusammen aus.

Chris72622: in einem meiner Projekte wird über die aktuelle Bounce-Library (Version 1.6) der Status mehrerer Knöpfe abgefragt.

Dies funktioniert soweit (gekürzter Code weiter unten).

Nun möchte ich jedoch [u]zusätzlich[/u] folgende Funktionalität implementieren:

Tja, so ist das mit dem Programmieren mit Hilfe von Libraries: Libraries sind hilfreich, wenn sie genau die Funktionen bereitstellen, die man braucht. Und Libraries kannst Du vergessen, wenn sie dafür eigentlich gar nicht gemacht sind.

Ich programmiere mir Dinge, die ich benötige, ja lieber schnell selbst. Z.B. kommt es bei dem Fall "zwei Tasten gleichzeitig für längere Zeit" überhaupt nicht aufs Tastenprellen an. Ob da am Anfang der eine oder andere Knopf für eine halbe Millisekunde prellt, was macht das für einen Unterschied, wenn man am Ende auf eine Zeit von 5 Sekunden prüfen möchte?

#define KNOPF1 3
#define KNOPF2 4

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(KNOPF1,INPUT_PULLUP);
  pinMode(KNOPF2,INPUT_PULLUP);
}


boolean DoubleDown5Seconds()
{
  static boolean lastState=0;
  byte state=0;
  static unsigned long bothdownSince=0;
  if (!digitalRead(KNOPF1)) bitSet(state,0); // bit0 in state setzen
  if (!digitalRead(KNOPF2)) bitSet(state,1); // bit1 in state setzen
  if (state==0b11 && state!=lastState)
     bothdownSince=millis();
  else if (state==0b11 && lastState==0b11 && millis()-bothdownSince>=5000)
    return(true);
  lastState=state;
  return false;
}  


void loop() {
  // put your main code here, to run repeatedly: 
  if (DoubleDown5Seconds()) Serial.println("DoubleDown");
}

Die Funktion ist für den Anschluß der Buttons ohne externe PullDown-Widerstände geschrieben und aktiviert die internen PullUps. Falls Du in Deiner Schaltung externe PullDown-Widerstände hast, müßtest Du den Code ändern auf die Verwendung ohne die internenen PullUps, und zwar im setup:

  pinMode(KNOPF1,INPUT);
  pinMode(KNOPF2,INPUT);

und in der Funktion

  if (digitalRead(KNOPF1)) bitSet(state,0); // bit0 in state setzen
  if (digitalRead(KNOPF2)) bitSet(state,1); // bit1 in state setzen

Die Funktion liefert übrigens "Dauerfeuer", solange die Bedingung "mind. 5 Sek. gedrückt" erfüllt ist. Falls es nur ein "Einzelfeuer" geben soll, muß man die Funktion noch etwas erweitern.

[quote author=Udo Klein link=topic=191850.msg1417834#msg1417834 date=1381059798] Wenn Du Knopf 1 und 2 nicht getrennt auswerten musst, dann schalte sie doch einfach in Reihe und Werte dadurch immer beide zusammen aus. [/quote]

Er schrieb allerdings schon im Ausgangsposting, dass er die Doppeldruckauswertung der Buttons [u]zusätzlich[/u] zur Einzelauswertung benötigt.

Hallo,

ich habe es mir mittlerweile selbst erarbeitet und es läuft auch mit der aktuellen Bounce-Library.

#include <Bounce.h>

byte prellzeit = 10;                                          // Global festgelegte Entprellzeit für alle Knöpfe

byte Knopf_1 = 3;                                             // Knopf_1 ist am definierten Anschluss
boolean val_1;                                                // Bouncerrückgabewert für Knopf 1
boolean Knopf_1_State;                                        // Zustand Knopf 1
Bounce Knopf_1_Bouncer = Bounce( Knopf_1,prellzeit);          // Aktivierung der Entprellfunktion für Knopf 1

byte Knopf_2 = 4;                                             
boolean val_2;                                                   
boolean Knopf_2_State;
Bounce Knopf_2_Bouncer = Bounce( Knopf_2,prellzeit);

unsigned long knopfdruckzeitpunkt = 0;                        // Gibt an, wann einer der beiden Knöpfe zuletzt gedrückt wurde.
int druckdauer = 3000;                                        // Gibt an, wie lange beide Knöpfe gleichzeitig gedrückt werden müssen.

byte LED = 13;

void setup()
{
  Serial.begin(9600);
  pinMode(Knopf_1, INPUT);
  pinMode(Knopf_2, INPUT);
  pinMode(LED, OUTPUT);
  digitalWrite(LED,LOW);
}

void loop()
{

Knopf_1_Bouncer.update ( );                                  // Abfrage des "Knopf_1_Bouncer"-Wertes.

val_1 = Knopf_1_Bouncer.read();                              // Bouncerrückgabewert für Knopf_1 wird in "val_1" gespeichert

if (val_1 != Knopf_1_State)                                  // Nur dann (<-!), wenn sich der eingelesene Bouncerrückgabewert (also "val_1") gegenüber "Knopf_1_State" geändert hat.. 
{                          
  if (val_1 == HIGH)                                         // ..und dieser nun "HIGH" ist..
  {                                                          // ..soll "etwas" passieren
    Serial.println("Knopf1 wurde gedrueckt");
    knopfdruckzeitpunkt = millis();
  }
  else if (val_1 == LOW)
  {
    Serial.println("Knopf1 wurde losgelassen");
    knopfdruckzeitpunkt = 0;
    digitalWrite(LED,LOW);
  }
}
Knopf_1_State = val_1;



Knopf_2_Bouncer.update ( );

val_2 = Knopf_2_Bouncer.read();

if (val_2 != Knopf_2_State)
{                          
  if (val_2 == HIGH)        
  {
    Serial.println("Knopf2 wurde gedrueckt");
    knopfdruckzeitpunkt = millis();
  }
  else if (val_2 == LOW)
  {
    Serial.println("Knopf2 wurde losgelassen");
    knopfdruckzeitpunkt = 0;
    digitalWrite(LED,LOW);
  }
}
Knopf_2_State = val_2;

if (Knopf_1_State == 1 && Knopf_2_State == 1 && knopfdruckzeitpunkt != 0 && millis() - knopfdruckzeitpunkt > druckdauer)
{
  Serial.println("LED an");
  knopfdruckzeitpunkt = 0;
  digitalWrite(LED,HIGH);
}

}

Gruß Chris