Pages: [1]   Go Down
Author Topic: Mehrere Inputs debouncen  (Read 384 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Moin,

ich quäle mich seit mehreren Tagen mit dem Problem mehrere Inputs (via buttonState) zu debouncen. Ein einzelner Input ist kein Problem, da habe ich mit der bounce library gearbeitet. Ich habe es allerdings nicht geschafft diese so umzubauen das es auch mit mehreren Inputs funktioniert.

Code:
int buttonState = 0;
...
void loop(){
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
    Serial.print("H");
}
else {
    Serial.print("L");
}

Ich habe gelesen das die bounce library gänzlich ungeeignet sein soll, wie kann ich also mehrere Inputs debouncen?

Gruß sxon
Logged

Offline Offline
Edison Member
*
Karma: 18
Posts: 1709
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Warum soll die bounce libary ungeeignet sein? Die geht wunderbar. Von deinem Sketch her sehe ich aber nicht, ob du es überhaupt irgend schon versucht hast.
Logged

Kein technischer Support über die Private Nachricht!

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wie gesagt, ich habe das nur gelesen.

Code:
#include <Bounce2.h>

#define OUT_PIN 11
#define LEDPin 10
#define buttonPin 13


// Instantiate a Bounce object
Bounce debouncer = Bounce();


int x_buttonState = 0;
int y_buttonState = 0;


void setup()
{
  Serial.begin(9600);
  pinMode(buttonPin, INPUT);
  pinMode(LEDPin, INPUT);
 
  digitalWrite(buttonPin,HIGH);
  digitalWrite(LEDPin,HIGH);
 
  debouncer.attach(buttonPin);
  debouncer.interval(5);
 
  debouncer.attach(LEDPin);
  debouncer.interval(5);
 
  //Setup the LED
  pinMode(HUPE_PIN,OUTPUT);
 

}

void loop(){
x_buttonState = digitalRead(buttonPin);
if (x_buttonState == HIGH) {
    Serial.print("H");
}
else {
    Serial.print("L");

}
y_buttonState = digitalRead(LEDPin);
if (y_buttonState == HIGH) {
    Serial.print("H");
}
else {
    Serial.print("L");

}
 // Update the debouncer
  debouncer.update();
 
 // Get the update value
 int value = debouncer.read();
 
 // Turn on or off the LED
 if ( value == HIGH) {
   digitalWrite(OUT_PIN, HIGH );
 } else {
    digitalWrite(OUT_PIN, LOW );
 }

}
Logged

Germany
Offline Offline
Newbie
*
Karma: 0
Posts: 20
Let’s get dangerous !
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich persönlich bin dazu übergegangen, bestimmte Dinge auch mal ganz einfach in Hardware zu lösen. Wenn es also dein Projekt erlaubt, und du sowieso hier und da noch andere Komponenten benutzt, dann kommts auf ein paar mehr oder weniger sicher auch nicht mehr drauf an.  smiley-wink

Was ich damit sagen will: vllt. ist jetzt die Zeit gekommen, sich einmal das Hardware-Deboucing als Alternative anzusehen. Jeremy Blum hat dazu ein super Video gemacht: Klick! (Wir sind hier zwar im Deutsch-Abteil, aber ich hoffe du bist des Englischen trotzdem mächtig? Ansonsten einfach auf den Schaltplan und das Breadboard schauen. smiley-wink )

(Ist bisschen off-topic, soll auch nur als Tipp nebenbei angesehen werden; wegen dem Tellerrand und so … smiley-wink
Logged

Franken
Offline Offline
Jr. Member
**
Karma: 0
Posts: 69
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
Bounce debounce1 = Bounce();
Bounce debounce2 = Bounce();
...

debounce1.attatch(button1);
debounce2.attatch(button2);
...
Logged

Offline Offline
Faraday Member
**
Karma: 80
Posts: 2738
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ja, Schmitt-Trigger mit RC-Glied ist eine schöne Schaltung dafür, und wesentlich einfacher als ein RS-Flip-Flop. Damit kann man auch problemlos mehrere Taster entprellen, da es bis zu 6 Gatter pro IC gibt. smiley
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
Bounce debounce1 = Bounce();
Bounce debounce2 = Bounce();
...

debounce1.attatch(button1);
debounce2.attatch(button2);
...
Das erscheint logisch, funktionieren tut es aber nicht. Im SerialMonitor schreibt er dann "HLHLHLHLHL".

Hier nochmal mein angepasster Code, habe ich noch einen Fehler verbaut?
Code:
#include <Bounce2.h>

#define buttonPin3 11
#define buttonPin1 10
#define buttonPin2 13


// Instantiate a Bounce object
Bounce debounce1 = Bounce();
Bounce debounce2 = Bounce();


//const int buttonPin = 12;     // the number of the pushbutton pin
int buttonState = 0;

void setup()
{
  Serial.begin(9600);
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
 
  digitalWrite(buttonPin1,HIGH);
  digitalWrite(buttonPin2,HIGH);
 
  debounce1.attach(buttonPin1);
  debounce1.interval(5);
 
  debounce2.attach(buttonPin2);
  debounce2.interval(5);
 
  //Setup the LED
  pinMode(buttonPin3,OUTPUT);
 

}

void loop(){
buttonState = digitalRead(buttonPin1);
if (buttonState == HIGH) {
    Serial.print("H");
}
else {
    Serial.print("L");

}
buttonState = digitalRead(buttonPin2);
if (buttonState == HIGH) {
    Serial.print("H");
}
else {
    Serial.print("L");

}
 // Update the debouncer
  debounce1.update();
  debounce2.update();
 
 // Get the update value
 int value = debounce1.read();
 
 // Turn on or off the LED
 if ( value == HIGH) {
   digitalWrite(buttonPin3, HIGH );
 } else {
    digitalWrite(buttonPin3, LOW );
 }
 int value2 = debounce2.read();
  if ( value2 == HIGH) {
   digitalWrite(buttonPin3, HIGH );
 } else {
    digitalWrite(buttonPin3, LOW );
 }

}
Logged

Germany, Dresden
Offline Offline
Sr. Member
****
Karma: 7
Posts: 308
30 Jahre Elektronikbastelei, Programmieren null Ahnung!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Versuch doch mal beim debouncen die Zeit hochzusetzen.
Ansonsten bin ich auch für Hardwarelösungen. Ein Triggergatter benötigst du nicht. Die Digitaleingänge kommen mit einer RC Kombination auch so ganz gut klar. Grob kalkuliert ergibt 1µF x 1K = 1ms. R im Bereich 10K bis 100K und C so im Bereich 100n KerKo bis vielleicht 2,2µ Elko. Der Taster überbrückt das C und R nach Plus oder Masse, je nachdem, ob man H oder L aktiv schalten will.

Gruß Gerald
Logged

rot ist blau und Plus ist Minus

Germany S-H
Offline Offline
Edison Member
*
Karma: 117
Posts: 2448
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ich quäle mich seit mehreren Tagen mit dem Problem mehrere Inputs (via buttonState) zu debouncen.

Ich glaube, sowas ähnliches wird hier im Forum häufiger mal gefragt.

Ich habe daher mal eben was vorbereitet, das man dafür verwenden kann und dabei relativ allgemein gehalten ist.

Eine Datenstruktur, in die man seine Buttons verpacken kann und zwei Funktionen:
- initButtons() ==> wird in der setup-Funktion aufgerufen
- setButtons() ==> wird in der loop-Funktion aufgerufen

Die Funktion kann für beliebig viele Buttons verwendet werden, begrenzt nur die Anzahl der freien Arduino-Pins.

Die Buttons können wahlweise mit externen PullDown-Widerständen angeschlossen sein (#define BUTTONTYPE INPUT) oder es können Buttons mit den internen PullUp-Widerständen verwendet werden (#define BUTTONTYPE INPUT_PULLUP).

Man ruft in der loop die Funktion "setButtons()" auf und dabei werden für jeden einzelnen Button folgende Informationen gesetzt:
myButtons[].down ==> down ist "true", wenn der Button momentan gedrückt ist
myButtons[].pressed ==> pressed ist nur einmalig "true", wenn der Button während des letzten Aufrufs von setButtons() den Status von down==false nach down==true geändert hat.

Wer möchte, kann es ja mal ausprobieren, was man damit machen kann.
Code:
// Multiple buttons debouncing demo by 'jurs' for German Arduino Forum
#define BUTTONTYPE INPUT_PULLUP  // INPUT or INPUT_PULLUP
struct debouncedButton {byte pin; unsigned long lastChanged; boolean down; boolean pressed;};

debouncedButton myButtons[]={
  {2,0,false,false}, // pin-2
  {3,0,false,false}, // pin-3
  {4,0,false,false}, // pin-4
  {5,0,false,false}, // pin-5
  {6,0,false,false}, // pin-6
};

#define NUMBUTTONS sizeof(myButtons)/sizeof(myButtons[0])
#define DEBOUNCETIME 5

void initButtons()
{
  for (int i=0; i<NUMBUTTONS; i++)
    pinMode(myButtons[i].pin,BUTTONTYPE); // set button pinMode
}

void setButtons()
{
  for (int i=0; i<NUMBUTTONS; i++)
  {
    myButtons[i].pressed=false;
    boolean state=digitalRead(myButtons[i].pin);
    if (BUTTONTYPE==INPUT_PULLUP) state=!state;
    if (state==HIGH && myButtons[i].down==false && labs(millis()-myButtons[i].lastChanged)>DEBOUNCETIME)
    {
      myButtons[i].lastChanged=millis();
      myButtons[i].down=true;
      myButtons[i].pressed=true;
    }
    else if (state==LOW && myButtons[i].down==true && labs(millis()-myButtons[i].lastChanged)>DEBOUNCETIME)
    {
      myButtons[i].down=false;
      myButtons[i].lastChanged=millis();
    }
  } 
}


void setup() {
  Serial.begin(9600);
  Serial.println("Press any button");
  initButtons();
}


void loop() {
  setButtons();
  for (int i=0; i<NUMBUTTONS; i++)
  {
    if (myButtons[i].pressed)
    {
      Serial.print("Button pressed, Index ");Serial.print(i);
      Serial.print("\tPin ");Serial.println(myButtons[i].pin);
    }
  }
}
Logged

Offline Offline
Sr. Member
****
Karma: 2
Posts: 391
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,
dieses "SoftWareDebouncing" habe ich aufgegeben. Es mag Leute geben die damit
klar kommen. Wenn ich das anwende suche ich nach kürzerster Zeit nach einen
Hammer um den Arduino auszuschalten.
Ich werde das in Zukunft nur noch über Hardware machen. Du brauchst dann keine
Code mehr und es funktioniert immer.
Bis dahin "behelfe" ich mich damit:

Code:
-------------------------------------------
int valZS1;                               
int buttonStateS1;                       
int buttonPressesS1 = 0;

-----------------------------------------

valZS1 = digitalRead(S1);             
if (valZS1 != buttonStateS1)
{                                     
if (valZS1 == LOW)
{                                     
buttonPressesS1++;                         
}
}
buttonStateS1 = valZS1;

 if (buttonPressesS1 > 9)
{
buttonPressesS1 = 1;
}

----------------------------------------------

Damit kann ich, mit zwei Tastern, meine Uhrzeit (Tag, Monat, Jahr, Wtag, Std, Min, Sek) manuell in der RTC setzen.
Ich finde das einfach und recht "mächtig"
Gruß und Spaß
Andreas
Logged

die zweite Maus bekommt den Speck...

Franken
Offline Offline
Jr. Member
**
Karma: 0
Posts: 69
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bounce2.h ?
Welche Lib benutzt du? bei mir heißt die einfach nur Bounce.h..

im ersten Abschnitt fragst du ja wieder direkt den ButtonPin ab.. der is ja am Bouncen.. darum evtl dein "HLHLHL"..

Code:
#include <Bounce2.h>

#define buttonPin3 11
#define buttonPin1 10
#define buttonPin2 13


// Instantiate a Bounce object
Bounce debounce1 = Bounce();
Bounce debounce2 = Bounce();


//const int buttonPin = 12;     // the number of the pushbutton pin


void setup()
{
  Serial.begin(9600);
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
 
  digitalWrite(buttonPin1,HIGH);
  digitalWrite(buttonPin2,HIGH);
 
  debounce1.attach(buttonPin1);
  debounce1.interval(5);
 
  debounce2.attach(buttonPin2);
  debounce2.interval(5);
 
  //Setup the LED
  pinMode(buttonPin3,OUTPUT);
 

}

void loop(){

if ( debounce1.read() == HIGH) {
    Serial.print("B1 = H");
}
else {
    Serial.print("B1 = L");

}

if (debounce2.read() == HIGH) {
    Serial.print("B2 = H");
}
else {
    Serial.print("B2 =  L");

}
 // Update the debouncer
  debounce1.update();
  debounce2.update();
 
 // Get the update value
 int value = debounce1.read();
 
 // Turn on or off the LED
 if ( value == HIGH) {
   digitalWrite(buttonPin3, HIGH );
 } else {
    digitalWrite(buttonPin3, LOW );
 }
 int value2 = debounce2.read();
  if ( value2 == HIGH) {
   digitalWrite(buttonPin3, HIGH );
 } else {
    digitalWrite(buttonPin3, LOW );
 }

}

(Ungetestet)



Machs wie in dem unteren Abschnitt. Die Bounce-Funktion abfragen. Oder, wie bei dir, den Rückkgabewert der Bouncefunktion in eine Var packen und die dann Abfragen (Weiß nicht, ob das direkte Abfragen von debounce1.read() in einem == verwendet werden kann)

Gehen tuts auf jedenfall.. verwende es selbst genau so. Nur ich habe eine Lib, die nur "Bounce.h" heißt. Hab ich glaub ich aus dem Playground..

Gruß
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Danke Fr33man, der Code funktioniert einwandfrei! Die Bounce2.h ist die aktuellste Library  aus dem Playground.
Die Hardwarevariante werde ich aber auch noch testen.

Vielen dank auch an alle anderen!

Gruß Daniel
« Last Edit: February 12, 2014, 05:23:20 pm by sxon » Logged

Pages: [1]   Go Up
Jump to: