Problem if-Abfrage

Hallo,

würde es ein deutsches Anfängerunterforum geben, hätte ich da gepostet, so muss ich leider hier nerven. :blush:

Warum leuchtet LED_B nicht, wenn LED_A während eines Schleifendurchlaufs zweimal gedrückt wird (und der erfolg somit beim zweiten Drücken true sein müsste?

boolean erfolg=false;

knopf_A_Bouncer.update ( );
val_A = knopf_A_Bouncer.read();                       // Bouncerrückgabewert für Knopf_A wird in "val_A" gespeichert
  if (val_A != zustand_knopf_A)                       // (Nur) wenn der eingelesene Bouncerrückgabewert "val" nicht mehr dem "Zustand Knopf_A" entspricht..
  if (val_A == HIGH)                                  // ..und dieser "HIGH" ist..
  if (erfolg==false)
    {
      zaehler_knopf_A++;                              // Zähler für Knopf_A um eins erhöhen.  
      digitalWrite(LED_A,LOW);      // ..schaltet dies LED_A aus.
      erfolg=true;
    }
  else if (erfolg==true)
    digitalWrite(LED_B,HIGH);
     
     zustand_knopf_A = val_A;

Code zeigt den Inhalt von void loop.

Gruß Chris

Bitte den geasmten Sketch einfügen!!!

Hier setzt du erfolg auf false.

boolean erfolg=false;

Im Weiteren wird erfolg nicht geändert, sodass die Verzweigung niemals in den else-Zweig gehen wird.

knopf_A_Bouncer.update ( );
val_A = knopf_A_Bouncer.read();                       // Bouncerrückgabewert für Knopf_A wird in "val_A" gespeichert
  if (val_A != zustand_knopf_A)                       // (Nur) wenn der eingelesene Bouncerrückgabewert "val" nicht mehr dem "Zustand Knopf_A" entspricht..
  if (val_A == HIGH)                                  // ..und dieser "HIGH" ist..
  if (erfolg==false)
    {
      zaehler_knopf_A++;                              // Zähler für Knopf_A um eins erhöhen.  
      digitalWrite(LED_A,LOW);      // ..schaltet dies LED_A aus.
      erfolg=true;
    }
  else if (erfolg==true)
    digitalWrite(LED_B,HIGH);
     
     zustand_knopf_A = val_A;
#include <Bounce.h>


int knopf_A =  3;                                            // Alle Knöpfe über 10kOhm Pulldowns (Widerstand an GND)
int knopf_B =  5;
int start   =  2;
int x = 0;

Bounce knopf_A_Bouncer = Bounce( knopf_A,5 );                // 5 ms Bouncing für "Knopf_A"
Bounce knopf_B_Bouncer = Bounce( knopf_B,5 );                // 5 ms Bouncing für "Knopf_B"
Bounce start_Bouncer = Bounce( start,5 );                    // 5 ms Bouncing für "Start"

int val_A;                                                   // Variable Zustand Knopf_A
int zustand_knopf_A;                                         // Speicherplatz Zustand Knopf_A
int zaehler_knopf_A;                                         // Zählt die Anschläge an Knopf_A

int val_B;
int zustand_knopf_B;
int zaehler_knopf_B;

int val_start;
int zustand_start;
int zaehler_start;

int LED_A   =  7;
unsigned long LED_A_zeit = 0;
int LED_B   =  4;

int Piezo   =  8;                                            // Piezolautsprecher über 100Ohm Widerstand

int zufallsarray[4];                                         // Ein Array mit vier Stellen
int i;                               
boolean zufallszahl;                                         // Eine zufällige Zahl (0 oder 1)

unsigned long schleifenzeit = millis();                      // Schleifenzeit
int schleifenzaehler = 0;                                    // Zähler, der festhält, wie oft die Schleife durchlaufen wurde.

/***********************************************************************************************************/

void setup()
{
  pinMode(start,INPUT);                                      // Definition der Aus- und Eingänge
  pinMode(knopf_A,INPUT);
  pinMode(LED_A,OUTPUT);
  pinMode(knopf_B,INPUT);
  pinMode(LED_B,OUTPUT);

  digitalWrite(LED_A, LOW);                                  // LED_A und LED_B ausschalten bei einem RESET
  digitalWrite(LED_B, LOW);
  
  Serial.begin(9600);

  randomSeed(analogRead(0));          // Einmalige Erzeugung der Saat
}

void loop()
{

//********************************************************************************************************************************************************************
  
                                                             // Testroutine

             Serial.print("knopf_A: ");                     
             
             Serial.print(zustand_knopf_A);
             Serial.print("  ");
             Serial.print(zaehler_knopf_A);
             Serial.print("    knopf_B: ");
             
             Serial.print(zustand_knopf_B);
             Serial.print("  ");
             Serial.print(zaehler_knopf_B);
             Serial.print("    knopf_S: ");
             
             Serial.print(zustand_start);
             Serial.print("  ");
             Serial.print(zaehler_start);

Serial.println();
delay(100);

//***********************************************************************   Hauptschleife   *********************************************************************************************/

boolean erfolg=false;                                                               // Knopfüberwachung

if (millis()>schleifenzeit+1000 /*- (schleifenzaehler*8)*/)                         // Formel für die ansteigende Geschwindigleit der Schleife
  {
      schleifenzeit = millis();                                                     // Erfassung der aktuellen Schleifenzeit
      schleifenzaehler++;                                                           // Erhöhung des Schleifenzählers um "1"
      zufallszahl=random(0,2);                                                      // Ermittlung der schleifenzugehörigen Zufallszahl
      zufallsarray[i]=zufallszahl;                                              


      digitalWrite(LED_A,LOW);                                                      // Lampe ausschalten
      digitalWrite(LED_B,LOW);                                                      // Lampe ausschalten

      Serial.print("Schleifenzufallszahl: ");
      Serial.print(zufallsarray[i]);
      
      Serial.print("   Schleifenzaehler: ");
      Serial.print(schleifenzaehler);
      
      Serial.print("   Schleifenzeit: ");
      Serial.println(schleifenzeit);        
      
      if(zufallszahl%2==0)
      {
        digitalWrite(LED_A,HIGH);
      }
      else
      {
        digitalWrite(LED_B,HIGH);
      }
   
      
  }
  
if (millis() - schleifenzeit > 500)                                                 // Automatisches ausschalten der Lampen nach einer bestimmten Zeit vom Schleifenstart an gerechnet
     {
       digitalWrite(LED_A,LOW);
       digitalWrite(LED_B,LOW);
     }

/***************************************************************************   Knopfabfragen   ***********************************************************************************************************/
     
knopf_A_Bouncer.update ( );
val_A = knopf_A_Bouncer.read();                       // Bouncerrückgabewert für Knopf_A wird in "val_A" gespeichert
  if (val_A != zustand_knopf_A)                       // (Nur) wenn der eingelesene Bouncerrückgabewert "val" nicht mehr dem "Zustand Knopf_A" entspricht..
  if (val_A == HIGH)                                  // ..und dieser "HIGH" ist..
  if (erfolg==false)
    {
      zaehler_knopf_A++;                              // Zähler für Knopf_A um eins erhöhen.  
      digitalWrite(LED_A,LOW);      // ..schaltet dies LED_A aus.
      erfolg=true;
    }
  else if (erfolg==true)
    digitalWrite(LED_B,HIGH);
     
     zustand_knopf_A = val_A;                        // Speichern des neuen Zustands in "val_A"     

knopf_B_Bouncer.update ( );
val_B = knopf_B_Bouncer.read();                       
  if (val_B != zustand_knopf_B)
  if (val_B == HIGH)                                
    {
      zaehler_knopf_B++;                              
      digitalWrite(LED_B,LOW);    
    }
      zustand_knopf_B = val_B;
          
start_Bouncer.update ( );
val_start = start_Bouncer.read();                     
  if (val_start != zustand_start)                     
  if (val_start == HIGH)                            
    {
      zaehler_start++;                                
    }
      zustand_start = val_start;
    

     
}

Hiermit setze ich doch erfolg auf true, oder nicht?

erfolg=true;

Gruß Chris

Du verkettest Du if Statements auf sehr ungewöhnliche Weise. Ist das Absicht? Normalerweise macht man nach einem "if" und einem "else" immer eine Klammer auf, damit absolut klar ist zu was das "else" gehört.

So wie Dein Code aussieht ist das "else if" mehr als nur ein bischen verdächtig. Ein "else" würde da völlig reichen. Strukturier Deinen Code mal so wie andere Leute das auch tun, dann siehst Du sofort was ich meine.

Davon abgesehen sieht es so aus als würde

if (millis() - schleifenzeit > 500)                                                 // Automatisches ausschalten der Lampen nach einer bestimmten Zeit vom Schleifenstart an gerechnet
     {
       digitalWrite(LED_A,LOW);
       digitalWrite(LED_B,LOW);
     }

Deine LEDs viel schneller ausschalten als Du Dir denkst.

Hallo,

das würde ich sehr gerne, doch wenn man zum ersten Mal selbst ein Projekt in die Hand nimmt und nicht einfach nur Tutorials "abarbeitet" weiss man u.U. noch nicht einmal so ganz genau was damit gemeint ist, wenn Erfahrenere Dinge wie..

..schreiben. :blush:

Trotzdem danke.

Die LEDs gehen wie gewünscht nach 1/2 Sekunde aus, wenn man keinen Knopf drückt. Es ist gewollt, dass die LEDs u.U. früher ausgehen als der Knopfbefehl zustande kommt.

Gruß Chris

Was ich meine ist statt

  if (val_A != zustand_knopf_A)                       // (Nur) wenn der eingelesene Bouncerrückgabewert "val" nicht mehr dem "Zustand Knopf_A" entspricht..
  if (val_A == HIGH)                                  // ..und dieser "HIGH" ist..
  if (erfolg==false)
    {
      zaehler_knopf_A++;                              // Zähler für Knopf_A um eins erhöhen.  
      digitalWrite(LED_A,LOW);      // ..schaltet dies LED_A aus.
      erfolg=true;
    }
  else if (erfolg==true)
    digitalWrite(LED_B,HIGH);

folgendes zu schreiben

    if (val_A != zustand_knopf_A) {
        if (val_A == HIGH) {
            if (erfolg==false) {
                zaehler_knopf_A++;                              // Zähler für Knopf_A um eins erhöhen.  
                digitalWrite(LED_A,LOW);      // ..schaltet dies LED_A aus.
                erfolg=true;
            } else if (erfolg==true) {
                digitalWrite(LED_B,HIGH);
            }     
        }
    }

Das ist äquivalent zu dem was Du schreibst. Aber man sieht an den Einrückungen eher was Du kodiert hast. Ob Du das wirklich gemeinst hast musst Du selber wissen.

Danke.

Auch das hilft. :slight_smile:

Gruß Chris

Überleg Dir mal genau wann er in den Else Zweig läuft und ob Du das wirklich so willst...

  if (val_A != zustand_knopf_A)                       // (Nur) wenn der eingelesene Bouncerrückgabewert "val" nicht mehr dem "Zustand Knopf_A" entspricht..
  if (val_A == HIGH)                                  // ..und dieser "HIGH" ist..
  if (erfolg==false)
    {

kann man auch mit den UND-Operator (&&) verknüpfen:

  if (val_A != zustand_knopf_A && val_A == HIGH && erfolg==false)
    {

du hast in deinem loop am anfang folgendes stehen:

boolean erfolg=false;

D.h. jedesmal wenn das Programm durchgelaufen ist wird erfolg auf false gesetzt. auch wenn du im if-Zweig erfolg aus true setzt so wird das beim nächsten durchlauf wieder mit false überschrieben. die deklaration gehört nicht in den loop sondern in den kopf.

@kduin:

kann man auch mit den UND-Operator (&&) verknüpfen:

Aber nur solange man kein ELSE hinten stehen hat. Dann hat && eine andere Semantik als die Verkettung von IFs. Genau darauf reite ich die ganze Zeit herum.