Mehrere Taster erkennen

Moin Gemeinde :slight_smile:

Ich bin blutiger Anfänger, und ich hacke mir die Finger wund am folgenden Thema: Ich möchte mehrere Taster erkennen, und zB eine LED entsprechend blinken lassen nach folgendem Schema:

if(Taster1 == HIGH);
digitalWrite(ledPin1, 1xblinken);
if(Taster2 == HIGH);
digitalWrite(ledPin1, 2xblinken);
if(Taster3 == HIGH);
digitalWrite(ledPin1, 3xblinken);

oder

if(Taster1 == HIGH);
digitalWrite(ledPin1, 1xblinken);
if(Taster2 == HIGH);
digitalWrite(ledPin2, 1xblinken);
if(Taster3 == HIGH);
digitalWrite(ledPin2, 1xblinken);

optimalerweise:

if(Taster1 == HIGH);
lcd.print("Taster1");
if(Taster2 == HIGH);
lcd.print("Taster2");
if(Taster3 == HIGH);
lcd.print("Taster3");

Im Netz habe ich nur etwas zu Interrupts gefunden, aber das ist Kost von Morgen. Mit dem LCD Display habe ich mich bereits erfolgreich auseinandergesetzt, und die Taster mit entsprechender Interrputschaltung (Mit Dioden breadboarding.de - This website is for sale! - breadboarding Resources and Information.) gebaut. Aber anscheinend haper es an Details.

Hier habe ich noch einen Code gefunden, der aber mit Analogen Pins arbeitet: 3 Tasten einlesen im Arduino | Shelvin – Elektronik ausprobiert und erläutert

Freue mich auf Antworten :slight_smile:

Für handbetätigte Taster brauchst Du keine Interrupts.

Wenn der Taster nicht betätigt ist, braucht er ein festes Potential sonst wirken sie wie Antennen und fangen alles (Un)Mögliche ein.
Dazu gibt es mehrere Varianten, die ich hier in #4 aufgeschrieben habe.

Gruß Tommy

Grundsätzlich wird dein Sketch wie oben nicht funktionieren.
Du darfst eine if-Abfrage nicht mit einem Semikolon abschließen.
Damit wird die Abfrage abgeschlossen und weitere Anweisungen direkt ausgeführt.

Hallo,
In der IDE gibts ein Beispiel das solltest Du dir mal ansehen ,

Datei / Beispiel / Basics / digitalReadSerial

enthalte ist ebenfalls ein Link der das erklärt.

Heinz

IOIOIIOO:
optimalerweise:

if(Taster1 == HIGH);
lcd.print("Taster1");
if(Taster2 == HIGH);
lcd.print("Taster2");
if(Taster3 == HIGH);
lcd.print("Taster3");

Noch optimaler geht es mit einer switch()-Konstruktion. Möglicherweise kommt noch einer mit der optimalsten Lösung :wink:

Gruß

Gregor

@TO
Was für Informationen brauchst du noch ?
Damit solltest du doch dein Problem lösen können.

if(Taster1 == HIGH);
lcd.print("Taster1");
if(Taster2 == HIGH);
lcd.print("Taster2");
if(Taster3 == HIGH);
lcd.print("Taster3");

Damit klappt die Ausgabe auf den Serialmonitor, aber ich denke der Fehler liegt in meiner Schaltung, denn es wird nicht der Schalter angezeigt der gedrückt wurde, sondern immer der 1., und selten der 2. Der 3. wird nie angezeigt. Die Taster sind nicht entprellt genug, bzw die Anschlüsse floaten.

Ihr kennt doch diese grossen roten Buzzer. Wenn Teams gegeneinander antreten, wird draufgehauen wer die Antwort als erstes weiss. So eine Anlage brauche ich für meine Teammitglieder. Am liebsten auf 20 Teams skalierbar. Die Digitalen Ports für die Drücker kann man leicht erweitern, und die Ausgabe soll auf ein lcd Display erfolgen. Ich scheitere aber bereits an der Anordnung von 2 Dioden auf meinem Breadbord :frowning:

Es würde Dir garantiert helfen, wenn Du die Antworten auf Deine Fragen auch lesen würdest.

Gruß Tommy

Ich sehe das mal so:
Wenn dich unsere Antworten nicht interessieren, dann brauchen wir ja auch keine weiteren Antworten zu geben.

Oder möchtest du, dass wir dir den Sketch schreiben ?
Dann bist du hier total falsch.

IOIOIIOO:
Damit klappt die Ausgabe auf den Serialmonitor, aber ich denke der Fehler liegt in meiner Schaltung, denn es wird nicht der Schalter angezeigt der gedrückt wurde, sondern immer der 1., und selten der 2. Der 3. wird nie angezeigt. Die Taster sind nicht entprellt genug, bzw die Anschlüsse floaten.

Ihr kennt doch diese grossen roten Buzzer. Wenn Teams gegeneinander antreten, wird draufgehauen wer die Antwort als erstes weiss. So eine Anlage brauche ich für meine Teammitglieder. Am liebsten auf 20 Teams skalierbar. Die Digitalen Ports für die Drücker kann man leicht erweitern, und die Ausgabe soll auf ein lcd Display erfolgen. Ich scheitere aber bereits an der Anordnung von 2 Dioden auf meinem Breadbord :frowning:

Beherzige endlich den Ratschlag von HotSystems in der 2. Antwort.

Wenn Du uns zu einem Bier und einer Pizza einläds dann kommen wir gerne und schauen uns Deine Schaltung an. Bis dahin ist es besser daß DU uns den Schaltplan zeigst (auch handgezeichnet und abfotografiert) oder gute Foto von Deinem Aufbau.

Grüße Uwe

Hallo

Zeig uns doch mal den gesamten code, das was wir bisher gesehen haben ist ja nur eine Idee

Heinz

Und lies bitte alle unsere Beiträge richtig, damit du auch alles verstehst.

Mein Entprellansatz, basierend auf combies Vorschlag, läßt sich für eine Buzzerauswertung nutzen. Der Taster an Pin 2 schaltet die Buzzer scharf, bei den anderen gewinnt, welcher Buzzer zuerst gedrückt wurde.

// Quelle der Bibliothek: https://github.com/duinoWitchery/hd44780
#include <Wire.h>
#include <hd44780.h> // include hd44780 library header file
#include <hd44780ioClass/hd44780_I2Cexp.h> // i/o expander/backpack class
hd44780_I2Cexp lcd; // auto detect backpack and pin mappings

#define LCD_COLS 20
#define LCD_ROWS 4

const unsigned long debounceDelay = 50;
unsigned long jetzt;                     // Variable für den aktuellen Zeitpunkt
byte buzzer, altBuzzer;

struct Buzzer {                          // Struktur mit Konstanten, Variablen und Methoden
  Buzzer(const byte pin, const byte buzzerNum): pin(pin), buzzerNum(buzzerNum), aktZustand(0), altZustand(0), vorhin(0) {}

  void init()
  {
    pinMode(pin, INPUT_PULLUP);
    aktZustand = !digitalRead(pin);
    altZustand = aktZustand;
  }
  void run()
  {
    aktualisieren();                        // Buzzerzustände aktualisieren
    if (buzzer)
    {
      if (zustand() && !buzzerNum)
      {
        buzzer = buzzerNum;
      }
    } else {
      if (zustand())                        // Buzzer aktiv
      {
        buzzer = buzzerNum;
      }

    }
  }

  void aktualisieren()
  {
    altZustand = aktZustand;
    if (jetzt - vorhin >= debounceDelay)    // Entprellen
    {
      aktZustand = !digitalRead(pin);
      if (altZustand != aktZustand)
      {
        vorhin = jetzt;
      }
    }
  }
  /* nicht benutzt
    bool steigend()                           // steigende Signalflanke
    {
      if (!altZustand && aktZustand)
      {
        return true;
      }
      return false;
    }
  */
  bool zustand()
  {
    return aktZustand;
  }
  /* nicht benutzt
    bool fallend()
    {
      if (altZustand && !aktZustand)
      {
        return true;
      }
      return false;
    }
  */
  const byte pin;
  const byte buzzerNum;
  bool aktZustand;
  bool altZustand;
  unsigned long vorhin;
};

Buzzer buz[] {
  // Arduino-Pin, Buzzernummer
  {2, 0},  // Taster fuer Buzzerfreigabe
  {3, 1},  // Buzzer 1
  {4, 2},
  {5, 3},
  {6, 4},
  {7, 5},
  {8, 6}

};

void setup() {
  lcd.begin(LCD_COLS, LCD_ROWS);
  lcd.print("Buzzer-Spiel");
  lcd.setCursor (0, 1);
  lcd.print("                    ");
  lcd.setCursor (0, 2);
  lcd.print(">> Buzzerfreigabe <<");
  for (Buzzer &b : buz) b.init();
}

void loop() {
  jetzt = millis();
  altBuzzer = buzzer;
  for (Buzzer &b : buz) b.run();
  if (altBuzzer != buzzer)
  {
    if (buzzer)
    {
      lcd.setCursor (0, 1);
      lcd.print("Buzzer:             ");
      lcd.setCursor (8, 1);
      lcd.print(buzzer);
      lcd.setCursor (0, 2);
      lcd.print("                    ");
    } else {
      lcd.setCursor (0, 1);
      lcd.print("                    ");
      lcd.setCursor (0, 2);
      lcd.print(">> Buzzerfreigabe <<");
    }
  }
}

Ich würde mich freuen, wenn es jemand als Vorschlag für eigene Überlegungen nutzen kann :slight_smile:

Hallo,

Ich bin blutiger Anfänger...

Ja, da hat man es oft schwer aber ohne die Umsetzung von #2 wird das nichts. Wenn Du nicht verstehst was HotSystems damit gemeint hat dann frag einfach.

if(Taster1 == HIGH); // Das Semikolon beendet die if Abfrage
digitalWrite(ledPin1, 1xblinken); // Dies ist jetzt eine Funktion die NICHT an if geknüpft ist.
//.....

if(Taster1 == HIGH) digitalWrite(ledPin1, 1xblinken); // So kann man _eine_ Funktion durch if aufrufen
if(Taster1 == HIGH) { // So kannst Du mehrere Funktionen ausführen
  funktion1();
  funktion2();
  //...
} // if ende

Das ist aber erst der Anfang...

digitalWrite(ledPin1, 1xblinken);

:o Versuch mal lieber die LED leuchten oder nicht leuchten zu lassen, die LED blinken zu lassen und nebenher die Taster weiter abzufragen, da bedarf es noch einiges an Grundlagen.

Ich kann Dir helfen den Code zu schreiben aber schreiben musst Du ihn schon selber.

optimalerweise:

if(Taster1 == HIGH);
lcd.print("Taster1");

Mach hier einfach das, was Dir bereits gesagt wurde, dann funktioniert es im Gegensatz zu Deinem ersten Beispiel. Korrekte Verkabelung vorausgesetzt.

Grüße,
Donny

Oft will man nicht erkennen, ob ein Taster zur Zeit gedrückt ist oder nicht, sondern einen (entprellten) Wechsel zwischen gedrückt und losgelassen...

Insbesondere Textausgaben sollten nicht unnötig wiederholt werden.

Selbst wenn dein Blinken nur weiterlaufen soll, während und solange der Taster gedrückt ist, brauchst du den Wechsel, um den Blink-Vorgang zu starten.

Variablen-Namen können übrigens nicht mit einer Ziffer anfangen, 1xblinken ist also schlecht.

Auch lautet der Titel "Mehrere Taster erkennen". Daraus schließe ich, dass du -während der eine Blink-Vorgang noch läuft- auf einen weiteren/anderen Tastendruck reagieren willst. Das geht nicht mit Interrupts (auch später nicht), sondern so, dass loop ohne größere delays immer wieder durchläuft blinkWithoutDelay

Hi

Och ... so kannst Du Das aber nicht sagen :slight_smile:
Klar kann ich via PC-INT an sehr vielen 'Beinchen' auf einen Pegelwechsel reagieren und dadurch einen Interrupt aufrufen lassen.
Aber eben nur EINEN - der PC (Pin Change) Interrupt umfasse mehrere Ports und man muß sich, bei einem auftretendem Interrupt, selber darum kümmern, welcher Pin nun Seinen Pegel gewechselt hat.
Dann muß man den Interrupt-Aufruf so umfunktionieren, daß Er danach auf den anderen Pegel reagiert.
Alles in Allem kein wirklich einfacher Weg und in loop() muß man den Kram eh noch Abarbeiten.

Einziger Vorteil: Dir geht kein Tastendruck verloren - zumindest ein 'Da war Mal was' hast Du immer, selbst, wenn Du zum Auswerten, welcher Pin nun den Zustand wechselte, zu langsam warst.
(Kleinkram kann man in der ISR machen, z.B. das betroffene Port 'am Stück' in ein Byte schieben, um in loop() darin die Änderung zu erkennen)

MfG