In while-Schleife gefangen

Hey leute :slight_smile: als bisher ziemlich passiver Nutzer des Forums habe ich jetzt endlich auch einmal ein Problem bei dem ich durch googlen und suchen einfach nicht weiter komme. Also, HALLO COMMUNITY!!!

Ich habe das Problem das ich innerhalb meines loop´s in einer while-Schleife gefangen bleibe und nichtmehr heraus komme.
Ich empfange via Serieller Schnittstelle von meinem Raspi Signale wie Z.B. "F;senden", das eintreffen der Signale startet der "SerialEvent"-befehl und verarbeitet den eintreffenden String zu einzelnen teilstrings die dann jeweils in der loop ihre eigenen befehle ausführen (die angegebene else if in der loop ist nur einer.... es gibt noch mehr aber die funktionieren alle tadellos).

Den Serial.print vor und nach der while-schleife habe ich nur eingfügt um für mich selbst auszutesten wie weit das Programm kommt. Aber da der Serial.print("bereit wurde auf 1 gesetzt") nie angezeigt wird schlussfolgere ich daraus das ich in der Schleife bleibe und als ich dann mal ein Serial.print("test") reingemacht habe, hat sich das auch bestätigt :).

Wisst ihr woran es liegen könnte?

loop()
{
if (stringComplete == true)
 {
else if (teilstring[0] == "F" && teilstring[1] == "senden")

    {
      //Status_F_Sensoren_pruefen();
      Status_F_Sensoren_senden();
      bereit = false;     
      Serial.print("ich versuche bereit auf 1 zu setzen");
      while (bereit == false)
      {
          // In dieser Schleife bin ich gefangen
          Serial.print("test"); 
      }
      Serial.print("bereit wurde auf 1 gesetzt");
    }

stringComplete = false;
 }
}



 void serialEvent()
  {

    while (Serial.available())
    {
      char inChar = (char)Serial.read();
      inputString += inChar;
      if (inChar == '\n')
      {
        Splitcode();
        stringComplete = true;
      }
    }
  }


  void Splitcode()
  {
    n = 0;
    String buffer = "";
    for (int i = 0; i < inputString.length(); i++)
    {
      if ((inputString[i] == ';') || (inputString[i] == '\n'))
      {
        teilstring[n] = buffer;
        buffer = "";
        n++;
         if(teilstring[1] == "bereit")
        {
          bereit = true;
        }
      }
      else
      {
        buffer += inputString[i];
      }
    }
    inputString = "";
  }


  void Status_F_Sensoren_senden()
  {
    uint8_t Status = B00000000;

    // Feuchtigkeitssensor B3 in Q1
    if (F_sensor_B3)
    {
      Status = Status | B00000001;
    }
    // Feuchtigkeitssensor B4 in Q2
    if (F_sensor_B4)
    {
      Status = Status | B00000010;
    }

    // Feuchtigkeitssensor B5 in Q3
    if (F_sensor_B5)
    {
      Status = Status | B00000100;
    }

    // Feuchtigkeitssensor B6 in Q4
    if (F_sensor_B6)
    {
      Status = Status | B00001000;
    }

    Serial.print((String)Status);
  }

Die Variablen teilstring[], n, bereit sowie die 4 F_Sensoren wurden global deklariert.

Mit besten Grüßen,
killachamp

achja ich benutze einen AtMega2560 + aufgesetzten RAMPS 1.4.

Und wer Lust hat sich durch den komletten Code zu wühlen darf dies gerne tun :slight_smile: den poste ich hier jetzt auch nochmal denn ich habe im Post oben nur die relevanten Stellen herauskopiert.

#include <AccelStepper.h>

AccelStepper Z_stepper(1, 46, 48); // 1=SM-Treiber,46=Z-STEP,48=Z-DIR
AccelStepper Y_stepper(1, 60, 61); // 1=SM-Treiber,60=Y-STEP,61=Y-DIR
String teilstring[3];
String inputString = "", Y_Modus, Z_Modus, Status_F_sensoren;
boolean F_sensor_B3 = false, F_sensor_B4 = true, F_sensor_B5 = true, F_sensor_B6 = false, stringComplete = false, bereit = false;
int n = 0;

void setup()
{
  // Serielle Schnittstelle mit Baudrate: 9600, Stopbits: 1, Paritätbit: 0, Datenbits: 8 initialisieren
  Serial.begin(9600);

  // 200 Bytes für Input reservieren
  inputString.reserve(200);

  //Pins initialisieren
  pinMode(13, OUTPUT);
  pinMode(11, INPUT);
  pinMode(6, INPUT);
  pinMode(5, INPUT);
  pinMode(4, INPUT);
  Y_stepper.setEnablePin(56);
  Z_stepper.setEnablePin(62);
  Z_stepper.setPinsInverted(false, false, true);
  Y_stepper.setPinsInverted(false, false, true);
}

void loop()
{
  if (stringComplete == true)
  {

    if (teilstring[0] == "Z")
    {
      Z_Motor_bewegen(teilstring[1], teilstring[2].toInt());
    }

    else if (teilstring[0] == "Y")
    {
      Y_Motor_bewegen(teilstring[1], teilstring[2].toInt());
    }

    else if (teilstring[0] == "F" && teilstring[1] == "senden")

    {
      //Status_F_Sensoren_pruefen();
      Status_F_Sensoren_senden();
      bereit = false;
      // Serial.print(bereit);
      Serial.print("ich versuche bereit auf 1 zu setzen");
      while (bereit == false)
      {
       
      }
      Serial.print("bereit wurde auf 1 gesetzt");
    }


    else if (teilstring[0] == "Ventil")
    {
      if (teilstring[1] == "1")
      {
        digitalWrite(13, HIGH);
      }
      else
      {
        digitalWrite(13, LOW);
      }
    }

    // Fehlercode: String konnte keinem Motor zugewiesen werden
    else
    {
      for (int i = 0; i < 4; i++)
      {
        digitalWrite(13, HIGH);
        delay(200);
        digitalWrite(13, LOW);
        delay(200);
      }
      for (int i = 0; i < 3; i++)
      {
        teilstring[i] = "";
      }


    }

    String_senden("bereit;1\n");
    stringComplete = false;
  }
}
 // RX - Interrupt
  void serialEvent()
  {

    while (Serial.available())
    {
      char inChar = (char)Serial.read();
      inputString += inChar;
      if (inChar == '\n')
      {
        Splitcode();
        stringComplete = true;
      }
    }
  }

  // teilt den Code in 3 teilstrings auf
  void Splitcode()
  {
    n = 0;
    String buffer = "";
    for (int i = 0; i < inputString.length(); i++)
    {
      if ((inputString[i] == ';') || (inputString[i] == '\n'))
      {
        teilstring[n] = buffer;
        buffer = "";
        n++;
         if(teilstring[1] == "bereit")
        {
          bereit = true;
        }
      }
      else
      {
        buffer += inputString[i];
      }
    }
    inputString = "";
  }

  //Bewegt den Y_Schrittmotor
  void Y_Motor_bewegen(String Y_Modus, int Y_Position)
  {
    //Modus 1 = Positionierungsfahrt
    if (Y_Modus == "1")
    {
      Y_stepper.enableOutputs();
      Y_stepper.setAcceleration(1000);
      Y_stepper.moveTo(Y_Position);
      Y_stepper.setSpeed(800);
      Y_stepper.runToPosition();
      Y_stepper.disableOutputs();
    }

    //Modus 2 = Gießfahrt
    else if (Y_Modus == "2")
    {
      Y_stepper.enableOutputs();
      Y_stepper.setAcceleration(1000);
      Y_stepper.moveTo(Y_Position);
      Y_stepper.setSpeed(200);
      Y_stepper.runToPosition();
      Y_stepper.disableOutputs();
    }

    // Modus 3 = Initialisierungsfahrt
    /*else if (Y_Modus == "3")
    {
    Y_stepper.enableOutputs();
    Y_stepper.setAcceleration(100);
    Y_stepper.moveTo(-20000);
    Y_stepper.setSpeed(100);
    while (digitalRead(? == LOW))
    {
    if (digitalRead(? == LOW))
    {
    Y_stepper.run();
    }
    }
    Y_stepper.disableOutputs();
    }*/

    // Fehlerblinkcode falls kein Modus gefunden oder fehlerhaft
    else
    {
      for (int i = 0; i < 6; i++)
      {
        digitalWrite(13, HIGH);
        delay(200);
        digitalWrite(13, LOW);
        delay(200);
      }
    }
  }

  //Bewegt den Z_Schrittmotor
  void Z_Motor_bewegen(String Z_Modus, int Z_Position)
  {
    // Modus 1 = Positionierungsfahrt
    if (Z_Modus == "1")
    {
      Z_stepper.enableOutputs();
      Z_stepper.setAcceleration(300);
      Z_stepper.moveTo(Z_Position);
      Z_stepper.setSpeed(900);
      Z_stepper.runToPosition();
      Z_stepper.disableOutputs();
    }

    //Modus 2 = Gießfahrt
    else if (Z_Modus == "2")
    {
      Z_stepper.enableOutputs();
      Z_stepper.setAcceleration(5000);
      Z_stepper.moveTo(Z_Position);
      Z_stepper.setSpeed(200);
      Z_stepper.runToPosition();
      Z_stepper.disableOutputs();
    }

    // Modus 3 = Initialisierungsfahrt
    /*else if (Y_Modus == "3")
    {
    Z_stepper.enableOutputs();
    Z_stepper.setAcceleration(100);
    Z_stepper.moveTo(-20000);
    Z_stepper.setSpeed(100);
    while (digitalRead(? == LOW))
    {
    if (digitalRead(? == LOW))
    {
    Z_stepper.run();
    }
    }
    Z_stepper.disableOutputs();
    }*/
  }

  void Status_F_Sensoren_senden()
  {
    uint8_t Status = B00000000;

    // Feuchtigkeitssensor B3 in Q1
    if (F_sensor_B3)
    {
      Status = Status | B00000001;
    }
    // Feuchtigkeitssensor B4 in Q2
    if (F_sensor_B4)
    {
      Status = Status | B00000010;
    }

    // Feuchtigkeitssensor B5 in Q3
    if (F_sensor_B5)
    {
      Status = Status | B00000100;
    }

    // Feuchtigkeitssensor B6 in Q4
    if (F_sensor_B6)
    {
      Status = Status | B00001000;
    }

    Serial.print((String)Status);
  }

  /*void Status_F_Sensoren_pruefen()
  {
  // Feuchtigkeitssensor B3
  if (digitalRead(4) == HIGH)
  {
  F_sensor_B3 = true;

  }

  else
  {
  F_sensor_B3 = false;
  }

  // Feuchtigkeitssensor B4
  if (digitalRead(5) == HIGH)
  {
  F_sensor_B4 = true;
  }

  else
  {
  F_sensor_B4 = false;
  }

  // Feuchtigkeitssensor B5
  if (digitalRead(6) == HIGH)
  {
  F_sensor_B5 = true;
  }

  else
  {
  F_sensor_B5 = false;
  }

  // Feuchtigkeitssensor B6
  if (digitalRead(11) == HIGH)
  {
  F_sensor_B6 = true;
  }

  else
  {
  F_sensor_B6 = false;
  }

  }
  */

Weil (bereit == false) immer true ist.

Tipp:
Damit serialEvent() wieder aufgerufen wird, muss erst loop() verlassen werden.

Denn serialEvent() ist keine Interrupt Funktion!

Hallo combie,

Danke für den nützlichen Tipp.
Bin bisher davon ausgegangen das das ein Interrupt wäre.

habe den Code jetzt folgendermmaßen abgeändert und siehe da, es läuft.

    else if (teilstring[0] == "F" && teilstring[1] == "senden")

    {
      //Status_F_Sensoren_pruefen();
      Status_F_Sensoren_senden();
      bereit = false;
      // Serial.print(bereit);
      Serial.print("ich versuche bereit auf 1 zu setzen");
      while (bereit == false)
      {
        serialEvent();
      }
      Serial.print("bereit wurde auf 1 gesetzt");
    }

Tausend Dank :slight_smile: ich trinke später mal n Bier auf dich

habe den Code jetzt folgendermmaßen abgeändert und siehe da, es läuft.

Dann bekommst du einen provisorischen "Glückwunsch" von mir!

Denn eigentlich solltest du dafür sorgen, dass loop() alsbaldmöglichst verlassen wird.
Also auf solcherart Schleifen verzichten.
Dann brauchst du auch solche Hacks nicht.

Lesetipp:
Die "Nachtwächter Erklärung" hier im Forum.