Arduino: Mit Tastern über einen gemeinsamen I/O mehrere LEDS schalten

Liebe Community,

ich beschäftige mich seit wenigen Tagen mit dem Thema “Arduino”. Ziel in meinem ersten Projekt ist es, über zwei Taster insgesamt 4 LEDs zu schalten. Es exisitieren neben Button1 und Button2, siehe Grafik “Arduino Forum1” noch der Button3, der zunächst nicht benötigt wird. Das System wird bei Funktion auf drei Schalter und je 4 LEDs pro Schalter erweitert.

Drückt man einmal auf den Button1, so soll die rote LED1_1 leuchten, drückt man ein zweites Mal auf den Button1, so soll die zweite LED1_2 an und bei dreifachem Klick beide ausgehen. Dasselbe gilt für den Button2. Lasse ich beide über einen eigenen I/0 “laufen”, so lässt sich mein Code einwandfrei, ohne die Optionen mit dem “keyVal”, ausführen. Der auskommentierte Code folgt. Mir ist bewusst, dass ein delay() vermieden werden sollte, jedoch möchte ich dies erst zum Schluss meines Projektes ausbessern.

Momentan läuft der Code nicht wie gewünscht. Es lässt sich keine LED anschalten. Wie kann ich den Code verändern, damit erkannt wird, ob der Button1 oder Button2 gedrückt wurde und wie oft?

Durch den seriellen Monitor erkenne ich, dass das Problem bei der Übergabe des A0 zu den jeweiligen Buttonstatus liegen muss. Leider habe ich mir noch kein Know-how diesbezüglich anlesen können und fand in den früheren Forenbeiträgen keine Hilfe für dieses Problem.

const int ButtonPlayer = A0;  //analoger Eingang für die zwei Buttons 1 und 2

const int LED1_1 = 8;         //digitaler Ausgang für die LED1 die bei Button1 angehen soll, wenn einmal gedrückt
const int LED1_2 = 9;         //digitaler Ausgang für die LED2 die bei Button1 angehen soll, wenn ein zweites Mal gedrückt

const int LED2_1 = 11;        //digitaler Ausgang für die LED1 die bei Button2 angehen soll, wenn einmal gedrückt
const int LED2_2 = 12;        //digitaler Ausgang für die LED2 die bei Button2 angehen soll, wenn ein zweites Mal gedrückt

int zaehlerSpieler1 = 0;      // Zähler wie oft der Button1 gedrückt wurde
int Button1Status = 0;        // Status ob der Button1 gedrückt wurde
int lastButton1State = 0;     // Voriger Status des Buttons1

int zaehlerSpieler2 = 0;      // Zähler wie oft der Button2 gedrückt wurde
int Button2Status = 0;        // Status ob der Button2 gedrückt wurde
int lastButton2State = 0;     // Voriger Status des Buttons2


void setup() 
{
  // put your setup code here, to run once:
  pinMode(LED1_1, OUTPUT);    // Legt digitalen I/O als O fest
  pinMode(LED1_2, OUTPUT);    // Legt digitalen I/O als O fest

  pinMode(LED2_1, OUTPUT);    // Legt digitalen I/O als O fest
  pinMode(LED2_2, OUTPUT);    // Legt digitalen I/O als O fest
  pinMode(ButtonPlayer, INPUT); // Legt digitalen I/O als I fest
  
  Serial.begin(9600);         // Start des seriellen Monitors
  Serial.println("Start ");   // Ausgabe bei Start: "Start"

}

void loop() {
  // read the pushbutton input pin:
  int keyVal = digitalRead(ButtonPlayer);              // Speichert den analogen Ausgang A0 als keyVal ab
  Serial.println("Der KeyVal beträgt: ");             // Überprüfung des Spannungswertes
  Serial.println(keyVal);         
        
  if (keyVal >= 500 && keyVal <= 600)                 // Wenn der keyVal zwischen 500 und 600 liegt, ist Button1 gedrückt
  {
    Button1Status = digitalRead(ButtonPlayer);        // Der Status des Button1 wird zu "HIGH", da die Spannung über 0 (zwischen 510 und 513) ist und damit HIGH
    Serial.println("Button 1");                       
  }
    if (keyVal >= 900 && keyVal <= 1010)              // Wenn der keyVal zwischen 500 und 600 liegt, ist Button1 gedrückt

  {
    Button2Status = digitalRead(ButtonPlayer);        // Der Status des Button1 wird zu "HIGH", da die Spannung über 1000 (zwischen 1000 und 1010) ist und damit HIGH
    Serial.println("Button 2");
  }


  if (Button1Status != lastButton1State)              // Wenn der Button1 gedrückt wurde, sprich HIGH und der vorige Status LOW war = Ein Buttonklick
  {
        if (Button1Status == HIGH)                          
    {      
      zaehlerSpieler1++;                              // dann erhöhe den Spieler1 Zähler und gebe die Anzahl wie oft geklickt wurde aus
      Serial.println("on"); 
      Serial.print("number of button pushes: ");
      Serial.println(zaehlerSpieler1);
      delay(50);                                      // 50 Millisekungen warten
    }
  }   
  lastButton1State = Button1Status;                   // setzt den Button Status auf 0 zurück
  
switch (zaehlerSpieler1) 
    {                                                 // Wenn der Spieler1 Zähler auf 1 steht, geht die erste LED  und wenn auf 2, die zweite LED an 
    case 1:                                           // Ist der Zähler auf 0, so gehen/bleiben beide aus
      digitalWrite(LED1_1,HIGH);
      digitalWrite(LED1_2,LOW);
      break;
    case 2:
      digitalWrite(LED1_1,HIGH);
      digitalWrite(LED1_2,HIGH);
      break;
    default:                                          // Sollte der Button des Spielers 1 ein drittes/sechstes/... Mal gedrückt werden, so gehen beide LEDs aus und der Spieler Zähler geht auf 1 zurück.
      digitalWrite(LED1_1,LOW);
      digitalWrite(LED1_2,LOW);
      zaehlerSpieler1=0;
      break;
    break;
    }

  if (Button2Status != lastButton2State)                // siehe oben, identisch zu Spieler1 
    {
    if (Button2Status == HIGH)
      {
      zaehlerSpieler2++;
      Serial.println("on");
      Serial.print("number of button pushes2: ");
      Serial.println(zaehlerSpieler2);
      delay(50);
      }
    }   
  lastButton2State = Button2Status;
  
switch (zaehlerSpieler2)
    {
    case 1:
      digitalWrite(LED2_1,HIGH);
      digitalWrite(LED2_2,LOW);
      break;
    case 2:
      digitalWrite(LED2_1,HIGH);
      digitalWrite(LED2_2,HIGH);
      break;
    default:
      digitalWrite(LED2_1,LOW);
      digitalWrite(LED2_2,LOW);
      zaehlerSpieler2=0;
      break;
    }
  }

Arduino_Forum_2.PNG

Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
Das kannst Du auch nachträglich noch ändern.

digitalRead liefert nur HIGH und LOW.

Wie hast Du denn Deine Buttons angeschlossen?

Gruß Tommy

Hi

Wenn ich Deinen Sketch recht interpretiere, willst Du die Buttons über den analogen Spannungswert erkennen - dazu musst Du, wie Tommy schon andeutet, ANALOG einlesen.
digitalRead - liest den Pin digital ein - HIGH oder LOW
analogRead - liest den Analog-Pin analog ein - gibt einen Wert 0...1023

MfG

Aber wenn ich an der Stelle einen analogRead() einsetze, so übergibt der ja bspw. 1011 an den Button1Status und nicht HIGH. Das funktioniert dann leider auch nicht. :confused:
An der Stelle direkt unter dem void loop wurde das geändert. An der Stelle ist das natürlich richtig.

@Tommy56: Vielen Dank für den Hinweis mit dem [*code]. Nutze das Forum zum ersten Mal und hatte mich schon gefragt wie das geht :slight_smile: Wie ich die Buttons angeschlossen habe siehst du in meinen angehängten .png

Ich habe mein Problem jetzt behoben. Zu einem war es das fehlerhafte int keyVal = digitalRead(A0) zum anderen habe ich den letzten Button Status auf den aktuellen Buttonstatus gesetzt. Dies habe ich nun umgekehrt, siehe neuer Code. Mein Programm funktioniert nun. Danke an alle :slight_smile:

const int ButtonPlayer = A0;  //analoger Eingang für die zwei Buttons 1 und 2

const int LED1_1 = 8;         //digitaler Ausgang für die LED1 die bei Button1 angehen soll, wenn einmal gedrückt
const int LED1_2 = 9;         //digitaler Ausgang für die LED2 die bei Button1 angehen soll, wenn ein zweites Mal gedrückt

const int LED2_1 = 11;        //digitaler Ausgang für die LED1 die bei Button2 angehen soll, wenn einmal gedrückt
const int LED2_2 = 12;        //digitaler Ausgang für die LED2 die bei Button2 angehen soll, wenn ein zweites Mal gedrückt

int zaehlerSpieler1 = 0;      // Zähler wie oft der Button1 gedrückt wurde
int Button1Status = 0;        // Status ob der Button1 gedrückt wurde
int lastButton1State = 0;     // Voriger Status des Buttons1

int zaehlerSpieler2 = 0;      // Zähler wie oft der Button2 gedrückt wurde
int Button2Status = 0;        // Status ob der Button2 gedrückt wurde
int lastButton2State = 0;     // Voriger Status des Buttons2


void setup() 
{
  // put your setup code here, to run once:
  pinMode(LED1_1, OUTPUT);    // Legt digitalen I/O als O fest
  pinMode(LED1_2, OUTPUT);    // Legt digitalen I/O als O fest

  pinMode(LED2_1, OUTPUT);    // Legt digitalen I/O als O fest
  pinMode(LED2_2, OUTPUT);    // Legt digitalen I/O als O fest
  pinMode(ButtonPlayer, INPUT); // Legt digitalen I/O als I fest
  
  Serial.begin(9600);         // Start des seriellen Monitors
  Serial.println("Start ");   // Ausgabe bei Start: "Start"

}

void loop() {
  // read the pushbutton input pin:
  int keyVal = analogRead(ButtonPlayer);              // Speichert den analogen Ausgang A0 als keyVal ab
  Serial.println("Der KeyVal beträgt: ");             // Überprüfung des Spannungswertes
  Serial.println(keyVal);         
        
  if (keyVal >= 500 && keyVal <= 600)                 // Wenn der keyVal zwischen 500 und 600 liegt, ist Button1 gedrückt
  {
    Button1Status = 1;                                // Der Status des Button1 wird zu "HIGH", da die Spannung über 0 (zwischen 510 und 513) ist und damit HIGH
    Serial.println("Button 1");
    Serial.println(Button1Status);
    Serial.println(lastButton1State);                       
  }
  else if (keyVal >= 900 && keyVal <= 1010)              // Wenn der keyVal zwischen 500 und 600 liegt, ist Button1 gedrückt

  {
    Button2Status = 1;        // Der Status des Button1 wird zu "HIGH", da die Spannung über 1000 (zwischen 1000 und 1010) ist und damit HIGH
    Serial.println("Button 2");
  }


  if (Button1Status != lastButton1State)              // Wenn der Button1 gedrückt wurde, sprich HIGH und der vorige Status LOW war = Ein Buttonklick
  {
        if (Button1Status == 1)                          
    {      
      zaehlerSpieler1++;                              // dann erhöhe den Spieler1 Zähler und gebe die Anzahl wie oft geklickt wurde aus
      Serial.println("on"); 
      Serial.print("number of button pushes: ");
      Serial.println(zaehlerSpieler1);
      delay(50); // 50 Millisekungen warten
      
    }
    Button1Status = lastButton1State;
  }   
              
   lastButton1State = Button1Status;       // setzt den Button Status auf 0 zurück
  
switch (zaehlerSpieler1) 
    {                                                 // Wenn der Spieler1 Zähler auf 1 steht, geht die erste LED  und wenn auf 2, die zweite LED an 
    case 1:                                           // Ist der Zähler auf 0, so gehen/bleiben beide aus
      digitalWrite(LED1_1,HIGH);
      digitalWrite(LED1_2,LOW);
      break;
    case 2:
      digitalWrite(LED1_1,HIGH);
      digitalWrite(LED1_2,HIGH);
      break;
    default:                                          // Sollte der Button des Spielers 1 ein drittes/sechstes/... Mal gedrückt werden, so gehen beide LEDs aus und der Spieler Zähler geht auf 1 zurück.
      digitalWrite(LED1_1,LOW);
      digitalWrite(LED1_2,LOW);
      zaehlerSpieler1=0;
      break;
    break;
    }

  if (Button2Status != lastButton2State)                // siehe oben, identisch zu Spieler1 
    {
    if (Button2Status == 1)
      {
      zaehlerSpieler2++;
      Serial.println("on");
      Serial.print("number of button pushes2: ");
      Serial.println(zaehlerSpieler2);
      delay(50);
      }
    }   
   Button2Status = lastButton2State ;
  
switch (zaehlerSpieler2)
    {
    case 1:
      digitalWrite(LED2_1,HIGH);
      digitalWrite(LED2_2,LOW);
      break;
    case 2:
      digitalWrite(LED2_1,HIGH);
      digitalWrite(LED2_2,HIGH);
      break;
    default:
      digitalWrite(LED2_1,LOW);
      digitalWrite(LED2_2,LOW);
      zaehlerSpieler2=0;
      break;
    }
  

  }
const int ButtonPlayer = A0;  //analoger Eingang für die zwei Buttons 1 und 2

Erklähr mir bitte wie Du mit einem Eingang 2 Taster unterscheiden kannst.

Grüße Uwe

@uwefeld: An der Stelle wird nur der O der beiden Schalter festeglegt.

void loop() {
  int keyVal = analogRead(ButtonPlayer);              // Speichert den analogen Ausgang A0 als keyVal ab
       
  if (keyVal >= 500 && keyVal <= 600)                 // Wenn der keyVal zwischen 500 und 600 liegt, ist  [right]Button1 gedrückt[/right]
  {
    Button1Status = 1;                                     // Der Status des Button1 wird zu "1"                 
  }
  else if (keyVal >= 900 && keyVal <= 1010)        // Wenn der keyVal zwischen 900 und 1000 liegt, [right]ist Button1 gedrückt[/right]
  {
    Button2Status = 1;                                    // Der Status des Button2 wird zu "1"
  }

In diesem Abschnitt werden die beiden Buttons unterschieden. Die Widerstandsmatrix ändert die Spannungswerte im Schaltkreis und wenn der Wert, bei mir, 1008 beträgt, dann wurde der Button 2 gedrückt und bei ca. 511 der Button 1, zumindest habe ich das so verstanden und es klappt ;D In der Grafik im Anhang sieht man auch den Aufbau.

uwefed:
Erklähr mir bitte wie Du mit einem Eingang 2 Taster unterscheiden kannst.

Erklär ohne h! Man kann auch 5 oder mehr Taster an einem Eingang abfragen, noch nie davon gehört/gelesen?

In diesem Abschnitt werden die beiden Buttons unterschieden.

In diesem Beispiel wird einer von von zwei Tastern erkannt. Kann relativ sicher auf ca. 5 Taster erweitert werden. (▲▼:arrow_forward::arrow_backward: ●) Dass mehr als ein Taster gleichzeitig gedrückt ist, ist in der Regel nicht vorgesehen. Allerdings darf der wichtigste Fall (kein Taster) nicht vergessen werden.

Programmiertechnisch einfacher ist es, nur 1 Variable für den Zustand des "keypad" zu verwenden als (wie hier) mehrere Variable, die man vergisst, wieder zurück zu setzen.

DeluxeUser:
@uwefeld: An der Stelle wird nur der O der beiden Schalter festeglegt.

void loop() {

int keyVal = analogRead(ButtonPlayer);              // Speichert den analogen Ausgang A0 als keyVal ab
     
  if (keyVal >= 500 && keyVal <= 600)                // Wenn der keyVal zwischen 500 und 600 liegt, ist  [right]Button1 gedrückt[/right]
  {
    Button1Status = 1;                                    // Der Status des Button1 wird zu “1”               
  }
  else if (keyVal >= 900 && keyVal <= 1010)        // Wenn der keyVal zwischen 900 und 1000 liegt, [right]ist Button1 gedrückt[/right]
  {
    Button2Status = 1;                                    // Der Status des Button2 wird zu “1”
  }




In diesem Abschnitt werden die beiden Buttons unterschieden. Die Widerstandsmatrix ändert die Spannungswerte im Schaltkreis und wenn der Wert, bei mir, 1008 beträgt, dann wurde der Button 2 gedrückt und bei ca. 511 der Button 1, zumindest habe ich das so verstanden und es klappt ;D In der Grafik im Anhang sieht man auch den Aufbau.

Un wo setzt Du Button1Status oder Button2Status wieder auf null?
Grüße Uwe