Taster entprellen

Hallo zusammen,

ich hab mal wieder eine elektrotechnische Frage.
Ich habe mir für mein neues Projekt eine Platine mit 18 Schaltern nach dem Vorbild der Tutorials gelötet. Es ist eine Lochrasterplatine, die Bahnen sind mit Blankdraht gezogen.

Wenn ich nun die Platine in Betrieb nehme erhalte ich ein massives Prellverhalten. Das heiißt konkret einmal berührt und es prellt mehrere Sekunden nach. Das Eingangssignal wird vielfach (zwischen 30 und 100 mal) gewertet. Selbst eine Berührung der signalführenden Kabel führt zum Auslösen.

Die Softwareentprellung aus den Beispielen hat nur minimale Verbesserung gebracht. Was kann ich tun?

Welche Tutorials? Welcher Sketch? Welchen Aufbau verwendest du, vielleicht mit aussagekräftigem Foto?

Taster prellen im Allgemeinen nicht im Sekundenbereich, da scheint zusätzlich noch ein anderes Problem vorzuliegen, bspw. der Verzicht auf Pullup- bzw. Pulldown-Widerstände.

Rtdler:
Das heiißt konkret einmal berührt und es prellt mehrere Sekunden nach.

{Glaskugelmodul AN}
Wenn Deine Software bereits auf "Berührung" statt auf "Schalterkontakt" reagiert, dürfte Deine Schaltung oder Dein Sketch schwere Fehler im Umgang mit PullUp-/PullDown-Widerständen aufweisen. Oder solche gar nicht enthalten bzw. aktivieren.
{Glaskugelmodul AUS}

Schaltung?
Sketch?

Hallo,

ich dachte die Beschreibung hätte geholfen. Hier die Infos.

Ich habe folgende Sketche ausprobiert:

Die Schaltung habe ich 1:1 übernommen. Bild der Platinenunterseite anbei mit Beschriftung.

Diese Schalter verwende ich http://www.reichelt.de/Eingabetaster-Digitast-/DT-6-SW/3/index.html?&ACTION=3&LA=446&ARTICLE=7241&GROUPID=3280&artnr=DT+6+SW

Wenn ich die Schaltereinzeln auf dem BreadBoard verbaue habe ich 54 Wiederholungen.

Hast du mal debounceDelay größer gemacht? Wobei wie gesagt, mehrere Sekunden so oder so nicht normal sind.

Rtdler:
Hier die Infos.

So, also Schaltung mit Tastern und 10K PullDown-Widerstand.
Scheint soweit korrekt, wenn ich mir das anhand der gezeigten Platinenrückseite zusammenreime.

Rtdler:
Wenn ich die Schaltereinzeln auf dem BreadBoard verbaue habe ich 54 Wiederholungen.

Zeige den Sketch mit dem Du die Tastendrücken auswertest!

Den "Button" Sketch kannst Du dabei total vergessen, der ist ohne Entprellung.

Wenn Du bei 18 Buttons in der Schaltung 54 Wiederholungen bei einmal Tastendrücken hast, dann sind das genau drei Wiederholungen pro Button in der Schaltung. Wenn das immer dreimal soviel Wiederholungen bei der Auswertung gibt wie Buttons in der Schaltung sind, dann spricht das ganz klar für einen systematischen Softwarefehler.

Beim Debounce-Sketch kommst Du möglicherweise bei der Erweiterung auf mehrere Buttons mit "lastDebounceTime" durcheinander, ohne hier korrekt die "lastDebounceTime" für jeden Button als getrennte Variable vorliegen zu haben.

Du kannst auch mal das hier probieren:
http://playground.arduino.cc//Code/Bounce

Da hat man für jeden Taster ein Bounce Objekt. Dadurch sind die Variablen gekapselt und sollten sich nicht in die Quere kommen. Und der Code ist bei 18 Tastern wesentlich übersichtlicher.

Hallo,

erstmal danke für eure Antworten.

Aktuell bin ich mir unsicher, was die Hardware betrifft. Ich habe nochmal alle Belegungen durchgetestet. Je sechs Schalter bilden bei mir einen Block (via 6 poligem Kabel an die Arduino Pins angeschlossen).

Bei dem zweiten Block kann ich ein "normales" Prellverhalten feststellen. D.h. bei einem Tastendruck wird bis zu 12 mal wiederholt in circa 0,5 Sek. Bei den Blöcken 1 und 3 tritt das nicht nachvollziehbare Verhalten auf. Ich drücke einen Schalter und mehrere reagieren oder sekundenlang wird wiederholt (für den jeweiligen Schalter).

Ich habe die Platine gerade noch einmal ausgebaut und durchgemessen. Es sind alle Werte identisch.

Nun habe ich die Vermuttung, dass die Schalter entweder so schlecht sind, dass Sie sich festfressen, wogegen aber spricht, dass mehrere signale eingehen, oder mein Testscatch ist Müll.

Ich habe in meinem Testscatch die Schalter initialisiert

  const int CH1_On = 27;
  const int CH1_Lamp = 29;
  const int CH1_Lamp100 = 31; 
  const int CH1_Powermode = 33;
  const int CH1_Beep = 35;
  const int CH1_Test = 37; 
  const int CH2_On = 34;
  const int CH2_Lamp = 36;
  const int CH2_Lamp100 = 38; 
  const int CH2_Powermode = 40;
  const int CH2_Beep = 42;
  const int CH2_Test = 44;
  const int CH3_On = 51;
  const int CH3_Lamp = 49;
  const int CH3_Lamp100 = 47; 
  const int CH3_Powermode = 45;
  const int CH3_Beep = 43;
  const int CH3_Test = 41;

Im Setup als Input festgelegt

  pinMode(CH1_On, INPUT); 
  pinMode(CH1_Lamp, INPUT); 
  pinMode(CH1_Lamp100, INPUT); 
  pinMode(CH1_Powermode, INPUT); 
  pinMode(CH1_Beep, INPUT); 
  pinMode(CH1_Test, INPUT); 
  pinMode(CH2_On, INPUT); 
  pinMode(CH2_Lamp, INPUT); 
  pinMode(CH2_Lamp100, INPUT); 
  pinMode(CH2_Powermode, INPUT); 
  pinMode(CH2_Beep, INPUT); 
  pinMode(CH2_Test, INPUT); 
  pinMode(CH3_On, INPUT); 
  pinMode(CH3_Lamp, INPUT); 
  pinMode(CH3_Lamp100, INPUT); 
  pinMode(CH3_Powermode, INPUT); 
  pinMode(CH3_Beep, INPUT); 
  pinMode(CH3_Test, INPUT);

Und frage sie per If ab

void Schalteranschluss ()
{
  //if (digitalRead(CH1_On) == HIGH){ Serial.println("Ch1_On"); }
  if (digitalRead(CH1_Lamp) == HIGH){ Serial.println("Ch1_Lamp"); }
  if (digitalRead(CH1_Lamp100) == HIGH){ Serial.println("Ch1_Lamp100"); }
  if (digitalRead(CH1_Powermode) == HIGH){ Serial.println("Ch1_Powermode"); }
  if (digitalRead(CH1_Beep) == HIGH){ Serial.println("Ch1_Beep"); }
  if (digitalRead(CH1_Test) == HIGH){ Serial.println("CH1_Test"); }
  if (digitalRead(CH2_On) == HIGH){ Serial.println("Ch2_On"); }
  if (digitalRead(CH2_Lamp) == HIGH){ Serial.println("Ch2_Lamp"); }
  if (digitalRead(CH2_Lamp100) == HIGH){ Serial.println("Ch2_Lamp100"); }
  if (digitalRead(CH2_Powermode) == HIGH){ Serial.println("Ch2_Powermode"); }
  if (digitalRead(CH2_Beep) == HIGH){ Serial.println("Ch2_Beep"); }
  if (digitalRead(CH2_Test) == HIGH){ Serial.println("CH2_Test"); }
  if (digitalRead(CH2_On) == HIGH){ Serial.println("Ch3_On"); }
  if (digitalRead(CH3_Lamp) == HIGH){ Serial.println("Ch3_Lamp"); }
  if (digitalRead(CH3_Lamp100) == HIGH){ Serial.println("Ch3_Lamp100"); }
  if (digitalRead(CH3_Powermode) == HIGH){ Serial.println("Ch3_Powermode"); }
  if (digitalRead(CH3_Beep) == HIGH){ Serial.println("Ch3_Beep"); }
  if (digitalRead(CH3_Test) == HIGH){ Serial.println("CH3_Test"); }
}

Die Debourncer Methode habe ich mit einem einzelnen Schalter auf einem Breadboard probiert. Das läuft. Ebenso würde es mit einem Interupt Timer gehen.
Das seltsame Verhalten der Schalter macht mir allerdings Sorgen.

Die Anschlusskabel habe ich auch nochmal auf Durchgang gemessen. Ebenso jeden einzelnen Schalter. Nun bin ich langsam ratlos und hoffe auf eure Tipps.

Ich häng nochmal ein Bild der Platine im Ganzen ran.

Unten links scheint eine Verbindung zu fehlen.

Mal ein Tip wegen dem Schaltdraht:
Wenn du den vor dem Verlöten mit zwei Zangen etwas in die Länge ziehst wird er schön gerade. Der verzieht sich dann nur wenn man Zwischenstellen anlötet, aber das kann man verhindern indem diese der Reihe nach macht und nicht erst die zwei Enden festlötet.

Und vielleicht die Temperatur des Lötkolbens ein klein wenig erhöhen.

Rtdler:
Bei dem zweiten Block kann ich ein "normales" Prellverhalten feststellen. D.h. bei einem Tastendruck wird bis zu 12 mal wiederholt in circa 0,5 Sek.

???

Rtdler:
Die Debourncer Methode habe ich mit einem einzelnen Schalter auf einem Breadboard probiert. Das läuft.

Wieso vermutest Du, dass wenn eine von vielen Usern getestete Funktion funktioniert und Dein Sketch funktioniert nicht, dass es dann an den Schaltern liegt? Und nicht an der von Dir verwendeten Schaltung oder dem Sketch?

Probier mal diesen Code:

// Tastendrücken mehrer Buttons abfragen
const byte buttonPins[]={27,29,31,33,35,37,34,36,38,40,42,44,51,49,47,45,43,41};
const byte buttonPinCount=sizeof(buttonPins);
#define DEBOUNCETIME 10

int buttonPressedMulti()
// returns number of button once a button is pressed
// returns -1 otherwise
{
  boolean State;
  static boolean buttonFired[buttonPinCount];
  static long buttonDownSince[buttonPinCount];
  for (int i=0;i<buttonPinCount;i++)
  {
    State=digitalRead(buttonPins[i]);
    if (State==LOW)  
    { // this button is not pressed at this time
      buttonFired[i]=false;
      buttonDownSince[i]=0;
    }
    else if (State==HIGH && buttonDownSince[i]==0)
    { // button is pressed but DEBOUNCETIME did not yet started counting
      buttonFired[i]=false;
      buttonDownSince[i]=millis();
    }
    if (State==HIGH && millis()-buttonDownSince[i]>=DEBOUNCETIME && buttonFired[i]==false)
    { // button is pressed and DEBOUNCETIME passed, so fire the button
      buttonFired[i]=true;
//      return(i); // return pin number in array
      return buttonPins[i]; // return pin number of button 
    }  
  }
  return(-1); // no button fired this time, return invalid pin number
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  for (int i=0;i<buttonPinCount;i++)
  {
    pinMode(buttonPins[i],INPUT);
  }
}


void loop() {
  // put your main code here, to run repeatedly: 
  int button=buttonPressedMulti();
  if (button>=0)
  {
    Serial.print("Button pressed: ");
    Serial.println(button);
  }  
}

Der Sketch sollte bei jedem Drücken einer Taste genau einmal einen "Button pressed" Code ausgeben.

BTW: Du hast hier bisher noch keinen vollständigen Sketch vorgezeigt. Deshalb der Hinweis:
Vernünftige Button-Auswertungen funktionieren nur in Programmen, in denen kein "delay()" verwendet wird!

Hallo,

vielen vielebn Dank für deine Hilfe. Der Sketch läuft wunderbar.

Folgende Fehler in meinem Aufbau konnte ich noch finden:

  • eine Verbindung zur Masse war defekt (Lötstelle gelöst) worduch die 3 Schalter gemeinsam prellten (es fehlte ja dann der PullDown)
  • Der Schalter in Block ein funktionierte auch mit deinem Sketch nicht sauber. Ich habe ihn ausgetauscht, jetzt läufts.

Die ursprünglichen Vermuttungen hinsichtlich Schalter und Sketch waren nur noch zielloses Suchen, da ich den Fehler nicht finden konnte. Es ging keines Falls darum, dass ich den Mustersketch als fehlerhaft angesehen habe, sondern eher die Frage ob ich ihn falsch modifiziert habe.

Schlussendlich scheint es die Kombination der Hardware und Softwarefehler von mir gewesen zu sein. Danke für die Hilfe.