If mit oder verknüpfen

Hallo, ich habe hier eine kleine Blink-Schaltung.
Folgender Plan :
Bei Eingabe 'e' >> Lampe ein mit Ausgabe: die LED wurde eingeschaltet.
Bei Eingabe 'a' >>Lampe aus mit Ausgabe: Die LED wurde ausgeschaltet.
Wenn man irgendwas anderes eingibt, Lampe aus und Ausgabe 'falsche Eingabe'.

die vorläufige Umsetzung:

void loop() {
  if(Serial.available())
  {
    char Eingabe = Serial.read();
    if(Eingabe=='e')
      {
      digitalWrite(13, 1);
      Serial.println("Die LED wurde eingeschaltet.");
      }
    if(Eingabe=='a')
      {
      digitalWrite(13,0);
      Serial.println("Die LED wurde ausgeschaltet.");
      }
    if(Eingabe!='a'||'e');
      {
      digitalWrite(13,0);
      Serial.println("falsche Eingabe.");
      }
  }
}      

Die dritte Bedingung will nicht, wie ich wohl möchte. Hat vielleicht jemand eine Idee, welchen Denkfehler ich hier mache?

Danke schon mal im Vorraus.

MFG Stephan

if((Eingabe!='a')||(Eingabe!='e'))

Vermutlich besser: switch/case

Wenns denn unbedingt if sein muss...

    if(Eingabe=='e')
      {
      digitalWrite(13, 1);
      Serial.println("Die LED wurde eingeschaltet.");
      }
    else if(Eingabe=='a')
      {
      digitalWrite(13,0);
      Serial.println("Die LED wurde ausgeschaltet.");
      }
    else
      {
      digitalWrite(13,0);
      Serial.println("falsche Eingabe.");
      }

Aus meiner Wühlkiste, leicht modifiziert:


void setup()
{
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
}

void serialEvent()
{
  switch(Serial.read())
  {
    case '\n': break;
    case '\r': break;
    case 'e' : digitalWrite(LED_BUILTIN, 1); break;
    case 'a' : digitalWrite(LED_BUILTIN, 0); break;
    default  : digitalWrite(LED_BUILTIN, 0); Serial.println("falsche Eingabe.");
  }
}

void loop()
{

}

@steplo

mit Ausnutzung von Copy Paste kann man auch zeigen wie ein "oder" in einem switch case gemacht wird. Man nutzt dazu ein "fall through":

void setup() {
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
}

void serialHandle() {
  switch (Serial.read()) {
    case -1 :       // keine Eingabe
    case '\n':      // Zeilenvorschub ignorieren
    case '\r':      // Zeilenanfang ignorieren
      break;
    case 'e' :
      digitalWrite(LED_BUILTIN, HIGH);
      Serial.println(F("Die LED wurde eingeschaltet."));
      break;
    case 'a' :
      digitalWrite(LED_BUILTIN, LOW);
      Serial.println(F("Die LED wurde ausgeschaltet."));
      break;
    default :
      Serial.println(F("falsche Eingabe."));
  }
}

void loop() {
  serialHandle();
}
//

Außerdem sollst du Fixtexte in ein F-Makro geben.
Spart auf einem kleinen Microcontroller SRAM.

Mag sein, dass es bessere Wege als if geht. Aber ich bin in der Thematik ganz am Anfang. Daher heißt die Aufgabenstellung jetzt eben, if und Konsorten verstehen lernen.

Danke für deinen Vorschlag. Es hat sich ein wenig verbessert. Die Lampe leuchtet zwar immer noch nicht wie gewünscht, aber am Ende erscheint nur einmal "falsche Eingabe". DAs ist ein Fortschritt. Ich werde das weiter untersuchen und auch die anderen Lösungen werde ich wohl bald besser verstehen...

Ja, if hat seine sinnvollen Einsätze, aber dieser gehört nicht unbedingt dazu.

Schule?
Wie auch immer, meine Empfehlung: Ein schönes dickes C++ Grundlagenbuch.

Das liegt daran, dass Du mit einem 'e' noch mindetstens ein weiteres Steuerzeichen sendest.
Nimm mal bitte im letzten else-Zweig das ausschalten der LED raus.
Somit schaltest Du immer nur mit 'e' ein und zwingend mit 'a' aus.

Um das zu vermeiden gibt es Funktionen, die das auswerten bestimmter Zeichen unterbindet.

Edit:

void loop()
{
  if (Serial.available())
  {
    char Eingabe = Serial.read();

    if (isPrintable(Eingabe))
    {
      if (Eingabe == 'e')
      {
        digitalWrite(13, 1);
        Serial.println("Die LED wurde eingeschaltet.");
      }
      else if (Eingabe == 'a')
      {
        digitalWrite(13, 0);
        Serial.println("Die LED wurde ausgeschaltet.");
      }
      else
      {
        digitalWrite(13, 0);
        Serial.println("falsche Eingabe.");
      }
    }
  }
}

um auch noch zu erläutern, warum die Logik nicht funktioniert (mal vom ; zuviel in der ersten Zeile abgesehen) :
"ist Eingabe nicht 'a' oder 'e'" ist quasi immer wahr, auch bei 'a' oder 'e', weil es ja dann "nicht e" ODER "nicht a" ist... Mit einer UND-Verknüpfung wäre das schon zielführender ("nicht a und auch nicht e") :slight_smile:

Dein Code ist fast korrekt, aber die dritte Bedingung hat einen logischen Fehler. Die Zeile if(Eingabe!='a'||'e') ist syntaktisch falsch. Der Operator || vergleicht zwei vollständige Bedingungen, also müsstest du if(Eingabe!='a' && Eingabe!='e') schreiben, um zu prüfen, ob die Eingabe weder a noch e ist. Außerdem ist das Semikolon nach der Bedingung falsch platziert.

Dein Vorschlag krankt dann aber auch daran:

Danke, das ist tatsächlich eine gut nachvollziehbare und funktionierende Lösung.

Das Semikolon ist in diesem Fall egal, denn

void setup() {
  char Eingabe = 'a';  // genauso bei 'e' oder 'x'
  Serial.begin(115200);
  if(Eingabe!='a'||'e') {
    Serial.println("Das kommt immer");
  }
}
void loop() { }

Dein if wird in dieser Reihenfolge (Klammern beachten) ausgewertet:
if ( (Eingabe!='a') || 'e')

'e' ist ungleich 0 und damit true , damit das if immer true. Ob sich das if auf die folgende Klammer oder nur das Semikolon bezieht, ist dann auch egal.

Natürlich kann man innerhalb eines if logische und ( && ) oder ( || ) und alles mögliche verwenden, auch dabei leicht die menschlichen Fähigkeiten überstrapazieren.