Mit IRremote Unterprogramm stoppen

Hallo,
ich habe ein kleines Problem bei einem Schulprojekt. Wir machen gerade einen Arduino Minibot
Screenshot 2022-01-20 153001
der automatisch Hindernisse erkennen soll und diese Umfahren. Dies hat auch schon geklappt. Nun wollten ich eine weitere Funktion hinzufügen, das Starten und des automatischen Fahrens durch ein drücken einer Taste auf der IR-Fernbedienung. Da das Programm gerne mal 10s braucht, habe ich alle Delays mit der BlinkWithoutDelay-Technik ausgetauscht. Hierbei arbeite ich mit der IRremote Bibliothek und ich habe diese Anleitung befolgt. Obwohl der Arduino immer wieder die void loop durchläuft (habe ich mit einer Serial-Monitor Nachricht herausgefunden), stoppt er einfach nicht das Unterprogramm fahren.

Wir arbeiten mit einem L293D Motortreiber, in meinem Programm starte ich die Motoren über z.B. motor11 hierbei meine ich den ersten Steuerungspin des ersten Motors (motor12 würde den 2. Steuerungspin meinen).

Unsere Komponenten sind so verbunden (kann nur 1 Bild hochladen).

Und das hier ist mein Code:

/* 
  Version: 3.0
  Aktueller Stand: 18.01.2022

*/

//----- Festlegen -----
  //Motoren
    #define enable1 9                                           //Enableport des 1. Motors
    #define enable2 10                                          //Enableport des 2. Motors
    #define motor11 6                                           //1. Steuerungspin vom 1. Motor
    #define motor12 5                                           //2. Steuerungspin vom 1. Motor
    #define motor21 4                                           //1. Steuerungspin vom 2. Motor
    #define motor22 3                                           //2. Steuerungspin vom 2. Motor
  //Zeiten, Geschwindigkeiten
    #define kurvezeit 1500                                      //Zeit in ms, die der Minibot braucht um eine Kurve zu fahren
    #define enablewert1 250                                     //Geschwindigkeitsfeinjustierung vom 1. Motor
    #define enablewert2 185                                     //Geschwindigkeitsfeinjustierung vom 2. Motor
  //Ultraschall
    #define trigger 8                                           //Trigger/Auslöser vom Ultraschallsensors
    #define echo 12                                             //Echo/Empfägner vom Ultraschallsensors
    long dauer=0;                                               //Variable zum Speichern der Dauer (von Auslößen bis zum Empfangen einer Ultraschallwelle)
    long entfernung=0;                                          //Variable zum Speichern der Entfernung (nach vorne gerichtet)
    long entfernungl=0;                                         //Variable zum Speichern der linken Entfernung
    long entfernungr=0;                                         //Variable zum Speichern der rechten Entfernung
  //IR-Remote
    #include <IRremote.h>                                       //Library zur IR-Steuerung wird eingebunden
    #define RECEIVER_PIN 11                                     //Pin des Ultraschallsensors
    IRrecv receiver(RECEIVER_PIN);                              //Objekt zum Empfangen wird erstellt
    decode_results results;                                     //Objekt zum Speichern der Ergebnisse wird erstellt
    #define Vor 0xFF629D                                        //IR-Empfangs-Hex-Zahl der Vor-Taste
    #define Zurueck 0xFFA857                                    //IR-Empfangs-Hex-Zahl der Zurück-Taste
    #define Rechts 0xFFC23D                                     //IR-Empfangs-Hex-Zahl der Rechts-Taste
    #define Links 0xFF22DD                                      //IR-Empfangs-Hex-Zahl der Links-Taste
    #define Power 0xFD00FF                                      //IR-Empfangs-Hex-Zahl der Power-Taste
    #define Stop 0xFD40BF                                       //IR-Empfangs-Hex-Zahl der Stop-Taste
  //Flags
    int steuerflag = 0;                                         //Flag um Befehl/e nur 1 mal auszuführen
    int linksflag = 0;                                          //Flag um Befehl/e nur 1 mal auszuführen
    int rechtsflag = 0;                                         //Flag um Befehl/e nur 1 mal auszuführen
    int fahrenflag = 0;                                         //Flag um Befehl/e nur 1 mal auszuführen
    int entscheidungflag = 0;                                   //Flag um Befehl/e nur 1 mal auszuführen
    int linksfertig = 0;                                        //Flag um Befehl/e nur 1 mal auszuführen
    int rechtsfertig = 0;                                       //Flag um Befehl/e nur 1 mal auszuführen
    int rechtsbereit = 0;                                       //Flag um Befehl/e nur 1 mal auszuführen
    int entscheidungsbereit = 0;                                //Flag um Befehl/e nur 1 mal auszuführen
  //Millis
    unsigned long linkskurvemillis;                             //Variable zum abspeichern der Millis am Anfang des Linkskurvenunterprogramms
    unsigned long rechtskurvemillis;                            //Variable zum abspeichern der Millis am Anfang des Rechtskurveunterprogramms
    unsigned long entscheidungmillis;                           //Variable zum abspeichern der Millis am Anfang des Entscheidungunterprogramms
    unsigned long fahrenmillis;                                 //Variable zum abspeichern der Millis am Anfang des Fahrenunterprogramms



void setup() {
//----- Definieren -----
  //Motoren
    pinMode(enable1, OUTPUT);
    pinMode(enable2, OUTPUT);
    pinMode(motor11, OUTPUT);
    pinMode(motor12, OUTPUT);
    pinMode(motor21, OUTPUT);
    pinMode(motor22, OUTPUT);
  //Ultraschall
    pinMode(trigger, OUTPUT);
    pinMode(echo, INPUT);
  //IR-Remote    
    receiver.blink13(true);                                     //Blinklicht des IR-Empfängers wird aktiviert
    receiver.enableIRIn();                                      //IR-Empfänger wird als Eingang gekennzeichnet
  //Serieller Monitor
    Serial.begin(9600);                                         //Serieller Monitor wird gestartet
}

void loop() {
  if (receiver.decode(&results)) {                              //dekodiert das empfangene IR-Signal und speichert es in dem "Results"-Objekt
    Serial.println(results.value, HEX);                         //schreibt den Hex-Code aus dem "Results"-Objekt in den seriellen Monitor
    receiver.resume();                                          //IR-Empfänger-Objekt wird zurückgesetzt
  }

if(results.value == Power){                                    //Wenn die IR-Empfangs-Hex-Zahl der Power-Taste dem "Results"-Objekt
  fahren();                                                     //entspricht wird das Unterprogramm "fahren" ausgeführt
}
if(results.value == Stop){                                      //Wenn die IR-Empfangs-Hex-Zahl der Stop-Taste dem "Results"-Objekt
  resetallflag();                                               //entspricht wird das Unterprogramm "resetallflag" ausgeführt
}
}
 
void fahren(){                                                  //Unterprogramm "fahren"
digitalWrite(trigger, HIGH);                                    //Ultraschallsensor wird angeschaltet, 10ms gewartet und dann wieder ausgeschaltet
delay(10);
digitalWrite(trigger, LOW);

dauer = pulseIn(echo, HIGH);                                    //Der Zeitabstand zwischen dem Ausschalten bis der Empfänger eine Welle empfängt, wird gemessen und auf die Variable "dauer" gespeichert
entfernung = (dauer / 2) * 0.0343;                              //Die Zeit wird durch 2 geteilt (wegen Hin- und Rückweg) und mit der Schallgeschwindigkeit multiplizieren, so dass man ein Maßstab hat

if(fahrenflag == 0){                                            //Die Variable "fahrenmillis" wird auf die aktuellen "millis" gesetzt, mithilfe einer Flag wird sichergestellt
  fahrenmillis = millis();                                      //das dies nur 1 mal passiert, bis die Flag wieder zurückgesetzt wird.
}
fahrenflag = 1;

if(millis() - fahrenmillis >= 500){                             //500ms werden durch Millis abgewartet
  if (entfernung >= 35){
    analogWrite(enable1, enablewert1);                          //Wenn die ausgerechnete Entfernung weniger (oder gleich) 35 ist, fährt er 1s nach vorne (Code von 131 - 141)
    analogWrite(enable2, enablewert2);
    digitalWrite(motor11, HIGH);
    digitalWrite(motor12, LOW);
    digitalWrite(motor21, HIGH);  
    digitalWrite(motor22, LOW);

    if(millis() - fahrenmillis >= 1000 + 500){                  //1s wird durch Millis abgewartet
      digitalWrite(enable1, LOW);
      digitalWrite(enable2, LOW);
      fahrenflag = 0;                                           //Der Flag "fahrenflag" wird zurückgesetzt, sodass beim nächsten die Millis wieder neu gesetzt werden
    }
  }
else{
if(linksfertig == 0){                                           //Unterprogramm "linkskurve" wird solange ausgeführt, bis "linksfertig" nicht mehr 0 ist
  linkskurve();
}

if(rechtsbereit == 1 && rechtsfertig == 0){                     //Unterprogramm "rechtskurve" wird ausgeführt wenn "rechtsbereit" 1 ist und endet wenn rechtsfertig nicht mehr 0 ist
  rechtskurve();
}

if(entscheidungsbereit == 1){
  entscheidung();                                               //Unterprogramm "entscheidung" wird ausgeführt wenn "entscheidungsbereit" 1 ist
}
}
}
}

void linkskurve() {                                             //Unterprogramm "linkskurve"
if(linksflag == 0){                                             //Die Variable "linkskurvemillis" wird auf die aktuellen "millis" gesetzt, mithilfe einer Flag wird sichergestellt
  linkskurvemillis = millis();                                  //das dies nur 1 mal passiert, bis die Flag wieder zurückgesetzt wird.
}
linksflag = 1;

analogWrite(enable1, enablewert1);
digitalWrite(enable2, LOW);
digitalWrite(motor11, HIGH);
digitalWrite(motor12, LOW);                                     //Rechter Motor gibt Gas


if(millis() - linkskurvemillis >= kurvezeit){                   //"kurvenzeit" wird durch Millis abgewartet
  digitalWrite(enable1, LOW);                                   //Rechter Motor hält an

  digitalWrite(trigger, HIGH);
  if(millis() - linkskurvemillis >= kurvezeit + 10){            //10ms wird durch Millis abgewartet
    digitalWrite(trigger, LOW);                                 //Ultraschallwellen werden für 10ms über den Sender/Trigger ausgestrahlt
    
    dauer = pulseIn(echo, HIGH);                                //Der Zeitabstand zwischen dem Ausschalten bis der Empfänger eine Welle empfängt, wird gemessen und auf die Variable "dauer" gespeichert
    entfernungl = (dauer / 2) * 0.0343;                         //Die Zeit wird durch 2 geteilt (wegen Hin- und Rückweg) und mit der Schallgeschwindigkeit multiplizieren, so dass man ein Maßstab hat. Dieser
                                                                //wird auf der Variable "entfernungl" gespeichert.

	  if(millis() - linkskurvemillis >= kurvezeit + 10 + 500){    //500ms (Rechenzeit) wird durch Millis abgewartet
      analogWrite(enable1, enablewert1);
      digitalWrite(motor11, LOW);
      digitalWrite(motor12, HIGH);
      if(millis() - linkskurvemillis >= kurvezeit + 10 + kurvezeit + 500){ //"kurvenzeit" wird durch Millis abgewartet
        digitalWrite(enable1, LOW);                             //Rechter Motor fährt für "kurvenzeit" rückwärts, um sich wieder in Normalposition zu begeben
        linksfertig = 1;                                        //Flag "linksfertig" wird auf 1 gesetzt, so dass das Unterprogramm "linkskurve" nicht mehr ausgeführt wird, bis die Flag zurückgesetzt wird
        rechtsbereit = 1;                                       //Flag "rechtsbereit" wird auf 1 gesetzt, so dass jetzt das Unterprogramm "rechtskurve" ausgeführt werden kann
    }
  }
  }
}
}

void rechtskurve() {                                            //Unterprogramm "rechtskurve"
if(rechtsflag == 0){                                            //Die Variable "rechtskurvemillis" wird auf die aktuellen "millis" gesetzt, mithilfe einer Flag wird sichergestellt
  rechtskurvemillis = millis();                                 //das dies nur 1 mal passiert, bis die Flag wieder zurückgesetzt wird.
}
rechtsflag = 1;

analogWrite(enable2, enablewert2);
digitalWrite(enable1, LOW);
digitalWrite(motor21, HIGH);
digitalWrite(motor22, LOW);                                     //Linker Motor gibt Gas

if(millis() - rechtskurvemillis >= kurvezeit){                  //"kurvenzeit" wird durch Millis abgewartet
  digitalWrite(enable2,LOW);

  digitalWrite(trigger, HIGH);
  if(millis() - rechtskurvemillis >= kurvezeit + 10){           //10ms wird durch Millis abgewartet
    digitalWrite(trigger, LOW);                                 //Ultraschallwellen werden für 10ms über den Sender/Trigger ausgestrahlt
    
    dauer = pulseIn(echo, HIGH);                                //Der Zeitabstand zwischen dem Ausschalten bis der Empfänger eine Welle empfängt, wird gemessen und auf die Variable "dauer" gespeichert
    entfernungr = (dauer / 2) * 0.0343;                         //Die Zeit wird durch 2 geteilt (wegen Hin- und Rückweg) und mit der Schallgeschwindigkeit multiplizieren, so dass man ein Maßstab hat. Dieser
                                                                //wird auf der Variable "entfernungr" gespeichert.

    if(millis() - rechtskurvemillis >= kurvezeit + 10 + 500){   //500ms (Rechenzeit) wird durch Millis abgewartet
      analogWrite(enable2, enablewert2);
      digitalWrite(motor21, LOW);
      digitalWrite(motor22, HIGH);
      if(millis() - rechtskurvemillis >= kurvezeit + 10 + kurvezeit + 500){ //"kurvenzeit" wird durch Millis abgewartet
        digitalWrite(enable2, LOW);                             //Linker Motor fährt für "kurvenzeit" rückwärts, um sich wieder in Normalposition zu begeben
        rechtsfertig = 1;                                       //Flag "rechtsfertig" wird auf 1 gesetzt, so dass das Unterprogramm "rechtskurve" nicht mehr ausgeführt wird, bis die Flag zurückgesetzt wird
        entscheidungsbereit = 1;                                //Flag "entscheidungsbereit" wird auf 1 gesetzt, so dass jetzt das Unterprogramm "entscheidung" ausgeführt werden kann
      }
    }
  }
}
}

void entscheidung() {                                           //Unterprogramm "rechtskurve"
if(entscheidungflag == 0){                                      //Die Variable "rechtskurvemillis" wird auf die aktuellen "millis" gesetzt, mithilfe einer Flag wird sichergestellt
  entscheidungmillis = millis();                                //das dies nur 1 mal passiert, bis die Flag wieder zurückgesetzt wird.
}
entscheidungflag = 1;
  
if(entfernungl>entfernungr){                                    //Wenn die vorhin errechnete Entfernung "entfernungl" größer als die Entfernung "entfernungr" ist,
  analogWrite(enable1, enablewert1);                            //dann gibt der rechte Motor gas
  digitalWrite(enable2, LOW);
  digitalWrite(motor11, HIGH);
  digitalWrite(motor12, LOW);

  if(millis() - entscheidungmillis >= kurvezeit){               //"kurvenzeit" wird durch Millis abgewartet
    digitalWrite(enable1, LOW);                                 //rechter Motor wird wieder abgeschaltet
    resetallflag();                                             //Unterprogramm "resetallflag" wird ausgeführt, da dass das Ende des "fahren" Unterprogramms ist
  }

}
else{
  analogWrite(enable2, enablewert2);                            //Wenn die vorhin errechnete Entfernung "entfernungl" nicht größer als die Entfernung "entfernungr" ist,
  digitalWrite(enable1, LOW);                                   //dann gibt der linke Motor gas
  digitalWrite(motor21, HIGH);
  digitalWrite(motor22, LOW);

  if(millis() - entscheidungmillis >= kurvezeit){               //"kurvenzeit" wird durch Millis abgewartet
    digitalWrite(enable2, LOW);                                 //linker Motor wird wieder abgeschaltet
    resetallflag();                                             //Unterprogramm "resetallflag" wird ausgeführt, da dass das Ende des "fahren" Unterprogramms ist
  }
}
}

void resetallflag(){                                            //Unterprogramm "resetallflag"
  steuerflag = 0;
  linksflag = 0;
  rechtsflag = 0;
  fahrenflag = 0;
  entscheidungflag = 0;
  linksfertig = 0;
  rechtsfertig = 0;
  rechtsbereit = 0;
  entscheidungsbereit = 0;                                      //alle Flags werden zurückgesetzt (auf 0 gesetzt)
}

In meinem Code wird das Unterprogramm fahren ausgeführt, wenn man die Taste POWER drückt. Dann misst er erstmal mit einem Ultraschallsensor die Entfernung, wenns sie weniger als 35 ist fährt er für 500ms geradeaus. Sonst macht er eine linkskurve und misst dort, dreht sich zurück, macht eine rechtskurve und misst dort, dreht sich zurück. Dann führt er entscheidung aus. Und dreht sich in die Richtung, wo die Entfernung höher ist.

Ich hoffe irgendjemand hat hier vielleicht eine Idee, was ich ändern muss damit das Unterprogramm fahren gestoppt werden kann.

  unsigned int IRwert = results.value;
  if (irrecv.decode(&results)) {
    irrecv.decode(&results);
    // Serial.println(IRwert);
    irrecv.resume();
  }
   if (IRwert == 16738455) //mach was// ;
  if (IRwert == 16726215) //mach was// ;

Du schreibst nur deine hex werte rein

Was benutzt Du für eine lib?

Das kenn ich nicht.

Kannst mal Dein loop() tauschen:

void loop()
{
  static byte mySwitch = 0;
  if (receiver.decode(&results))                                //dekodiert das empfangene IR-Signal und speichert es in dem "Results"-Objekt
  {
    Serial.println(results.value, HEX);                         //schreibt den Hex-Code aus dem "Results"-Objekt in den seriellen Monitor
  }
  if (results.value == Power)                                    //Wenn die IR-Empfangs-Hex-Zahl der Power-Taste dem "Results"-Objekt
  {
    mySwitch = 1;
  }
  if (results.value == Stop)                                      //Wenn die IR-Empfangs-Hex-Zahl der Stop-Taste dem "Results"-Objekt
  {
    mySwitch = 2;
  }
  receiver.resume();                                          //IR-Empfänger-Objekt wird zurückgesetzt
  switch (mySwitch)
  {
    case 1:
      fahren();                                                     //entspricht wird das Unterprogramm "fahren" ausgeführt
      break;
    case 2:
      resetallflag();                                               //entspricht wird das Unterprogramm "resetallflag" ausgeführt
      break;
  }
}

Nur umgeschrieben - ohne Anspruch das es funktioniert.

Was benutzt Du für eine lib?

Ich benutze wie oben schon beschrieben IRremote, nach dieser Anleitung.

Ich probiere eure Versionen, dann beide mal aus

Bei resetallflag(); beide Motoren ausschalten, sonst bleiben die im undefiniertem zustand

Ich habe jetzt dein Verbesserungsvorschlag ausprobiert. Leider funktioniert er auch nicht. Allerdings drehen diesmal nicht beide Motoren durchgehend, sondern nur der Rechte.

Das ist der aktuelle Code:

/* 
  Version: 3.0
  Aktueller Stand: 24.01.2022

*/

//----- Festlegen -----
  //Motoren
    #define enable1 9                                           //Enableport des 1. Motors
    #define enable2 10                                          //Enableport des 2. Motors
    #define motor11 6                                           //1. Steuerungspin vom 1. Motor
    #define motor12 5                                           //2. Steuerungspin vom 1. Motor
    #define motor21 4                                           //1. Steuerungspin vom 2. Motor
    #define motor22 3                                           //2. Steuerungspin vom 2. Motor
  //Zeiten, Geschwindigkeiten
    #define kurvezeit 1500                                      //Zeit in ms, die der Minibot braucht um eine Kurve zu fahren
    #define enablewert1 250                                     //Geschwindigkeitsfeinjustierung vom 1. Motor
    #define enablewert2 185                                     //Geschwindigkeitsfeinjustierung vom 2. Motor
  //Ultraschall
    #define trigger 8                                           //Trigger/Auslöser vom Ultraschallsensors
    #define echo 12                                             //Echo/Empfägner vom Ultraschallsensors
    long dauer=0;                                               //Variable zum Speichern der Dauer (von Auslößen bis zum Empfangen einer Ultraschallwelle)
    long entfernung=0;                                          //Variable zum Speichern der Entfernung (nach vorne gerichtet)
    long entfernungl=0;                                         //Variable zum Speichern der linken Entfernung
    long entfernungr=0;                                         //Variable zum Speichern der rechten Entfernung
  //IR-Remote
    #include <IRremote.h>                                       //Library zur IR-Steuerung wird eingebunden
    #define RECEIVER_PIN 11                                     //Pin des Ultraschallsensors
    IRrecv receiver(RECEIVER_PIN);                              //Objekt zum Empfangen wird erstellt
    decode_results results;                                     //Objekt zum Speichern der Ergebnisse wird erstellt
    #define Vor 0xFF629D                                        //IR-Empfangs-Hex-Zahl der Vor-Taste
    #define Zurueck 0xFFA857                                    //IR-Empfangs-Hex-Zahl der Zurück-Taste
    #define Rechts 0xFFC23D                                     //IR-Empfangs-Hex-Zahl der Rechts-Taste
    #define Links 0xFF22DD                                      //IR-Empfangs-Hex-Zahl der Links-Taste
    #define Power 0xFFA25D                                      //IR-Empfangs-Hex-Zahl der Power-Taste
    #define Stop 0xFFE21D                                       //IR-Empfangs-Hex-Zahl der Stop-Taste
  //Flags
    int steuerflag = 0;                                         //Flag um Befehl/e nur 1 mal auszuführen
    int linksflag = 0;                                          //Flag um Befehl/e nur 1 mal auszuführen
    int rechtsflag = 0;                                         //Flag um Befehl/e nur 1 mal auszuführen
    int fahrenflag = 0;                                         //Flag um Befehl/e nur 1 mal auszuführen
    int entscheidungflag = 0;                                   //Flag um Befehl/e nur 1 mal auszuführen
    int linksfertig = 0;                                        //Flag um Befehl/e nur 1 mal auszuführen
    int rechtsfertig = 0;                                       //Flag um Befehl/e nur 1 mal auszuführen
    int rechtsbereit = 0;                                       //Flag um Befehl/e nur 1 mal auszuführen
    int entscheidungsbereit = 0;                                //Flag um Befehl/e nur 1 mal auszuführen
  //Millis
    unsigned long linkskurvemillis;                             //Variable zum abspeichern der Millis am Anfang des Linkskurvenunterprogramms
    unsigned long rechtskurvemillis;                            //Variable zum abspeichern der Millis am Anfang des Rechtskurveunterprogramms
    unsigned long entscheidungmillis;                           //Variable zum abspeichern der Millis am Anfang des Entscheidungunterprogramms
    unsigned long fahrenmillis;                                 //Variable zum abspeichern der Millis am Anfang des Fahrenunterprogramms



void setup() {
//----- Definieren -----
  //Motoren
    pinMode(enable1, OUTPUT);
    pinMode(enable2, OUTPUT);
    pinMode(motor11, OUTPUT);
    pinMode(motor12, OUTPUT);
    pinMode(motor21, OUTPUT);
    pinMode(motor22, OUTPUT);
  //Ultraschall
    pinMode(trigger, OUTPUT);
    pinMode(echo, INPUT);
  //IR-Remote    
    receiver.blink13(true);                                     //Blinklicht des IR-Empfängers wird aktiviert
    receiver.enableIRIn();                                      //IR-Empfänger wird als Eingang gekennzeichnet
  //Serieller Monitor
    Serial.begin(9600);                                         //Serieller Monitor wird gestartet
}



void resetallflag(){                                            //Unterprogramm "resetallflag"
  digitalWrite(enable1, LOW);
  digitalWrite(enable2, LOW);
  steuerflag = 0;
  linksflag = 0;
  rechtsflag = 0;
  fahrenflag = 0;
  entscheidungflag = 0;
  linksfertig = 0;
  rechtsfertig = 0;
  rechtsbereit = 0;
  entscheidungsbereit = 0;                                      //alle Flags werden zurückgesetzt (auf 0 gesetzt)
}


void loop() {
  if (receiver.decode(&results)) {                              //dekodiert das empfangene IR-Signal und speichert es in dem "Results"-Objekt
    receiver.decode(&results);
    Serial.println(results.value, HEX);                         //schreibt den Hex-Code aus dem "Results"-Objekt in den seriellen Monitor
    receiver.resume();                                          //IR-Empfänger-Objekt wird zurückgesetzt
  }
if(results.value == Power){                                     //Wenn die IR-Empfangs-Hex-Zahl der Power-Taste dem "Results"-Objekt
  fahren();                                                     //entspricht wird das Unterprogramm "fahren" ausgeführt
}
if(results.value == Stop){                                      //Wenn die IR-Empfangs-Hex-Zahl der Stop-Taste dem "Results"-Objekt
  resetallflag();                                               //entspricht wird das Unterprogramm "resetallflag" ausgeführt
}
}
 
void fahren(){                                                  //Unterprogramm "fahren"
if(fahrenflag == 0){                                            //Die Variable "fahrenmillis" wird auf die aktuellen "millis" gesetzt, mithilfe einer Flag wird sichergestellt
  fahrenmillis = millis();                                      //das dies nur 1 mal passiert, bis die Flag wieder zurückgesetzt wird.
}
fahrenflag = 1;
  
digitalWrite(trigger, HIGH);                                    //Ultraschallsensor wird angeschaltet, 10ms gewartet und dann wieder ausgeschaltet

if(millis() - fahrenmillis >= 10){    
digitalWrite(trigger, LOW);

dauer = pulseIn(echo, HIGH);                                    //Der Zeitabstand zwischen dem Ausschalten bis der Empfänger eine Welle empfängt, wird gemessen und auf die Variable "dauer" gespeichert
entfernung = (dauer / 2) * 0.0343;                              //Die Zeit wird durch 2 geteilt (wegen Hin- und Rückweg) und mit der Schallgeschwindigkeit multiplizieren, so dass man ein Maßstab hat



if(millis() - fahrenmillis >= 500 + 10){                             //500ms werden durch Millis abgewartet
  if (entfernung >= 35){
    analogWrite(enable1, enablewert1);                          //Wenn die ausgerechnete Entfernung weniger (oder gleich) 35 ist, fährt er 1s nach vorne (Code von 131 - 141)
    analogWrite(enable2, enablewert2);
    digitalWrite(motor11, HIGH);
    digitalWrite(motor12, LOW);
    digitalWrite(motor21, HIGH);  
    digitalWrite(motor22, LOW);

    if(millis() - fahrenmillis >= 1000 + 500 + 10){                  //1s wird durch Millis abgewartet
      digitalWrite(enable1, LOW);
      digitalWrite(enable2, LOW);
      fahrenflag = 0;                                           //Der Flag "fahrenflag" wird zurückgesetzt, sodass beim nächsten die Millis wieder neu gesetzt werden
    }
  }
}
else{
if(linksfertig == 0){                                           //Unterprogramm "linkskurve" wird solange ausgeführt, bis "linksfertig" nicht mehr 0 ist
  linkskurve();
}

if(rechtsbereit == 1 && rechtsfertig == 0){                     //Unterprogramm "rechtskurve" wird ausgeführt wenn "rechtsbereit" 1 ist und endet wenn rechtsfertig nicht mehr 0 ist
  rechtskurve();
}

if(entscheidungsbereit == 1){
  entscheidung();                                               //Unterprogramm "entscheidung" wird ausgeführt wenn "entscheidungsbereit" 1 ist
}
}
}
}

void linkskurve() {                                             //Unterprogramm "linkskurve"
if(linksflag == 0){                                             //Die Variable "linkskurvemillis" wird auf die aktuellen "millis" gesetzt, mithilfe einer Flag wird sichergestellt
  linkskurvemillis = millis();                                  //das dies nur 1 mal passiert, bis die Flag wieder zurückgesetzt wird.
}
linksflag = 1;

analogWrite(enable1, enablewert1);
digitalWrite(enable2, LOW);
digitalWrite(motor11, HIGH);
digitalWrite(motor12, LOW);                                     //Rechter Motor gibt Gas


if(millis() - linkskurvemillis >= kurvezeit){                   //"kurvenzeit" wird durch Millis abgewartet
  digitalWrite(enable1, LOW);                                   //Rechter Motor hält an

  digitalWrite(trigger, HIGH);
  if(millis() - linkskurvemillis >= kurvezeit + 10){            //10ms wird durch Millis abgewartet
    digitalWrite(trigger, LOW);                                 //Ultraschallwellen werden für 10ms über den Sender/Trigger ausgestrahlt
    
    dauer = pulseIn(echo, HIGH);                                //Der Zeitabstand zwischen dem Ausschalten bis der Empfänger eine Welle empfängt, wird gemessen und auf die Variable "dauer" gespeichert
    entfernungl = (dauer / 2) * 0.0343;                         //Die Zeit wird durch 2 geteilt (wegen Hin- und Rückweg) und mit der Schallgeschwindigkeit multiplizieren, so dass man ein Maßstab hat. Dieser
                                                                //wird auf der Variable "entfernungl" gespeichert.

	  if(millis() - linkskurvemillis >= kurvezeit + 10 + 500){    //500ms (Rechenzeit) wird durch Millis abgewartet
      analogWrite(enable1, enablewert1);
      digitalWrite(motor11, LOW);
      digitalWrite(motor12, HIGH);
      if(millis() - linkskurvemillis >= kurvezeit + 10 + kurvezeit + 500){ //"kurvenzeit" wird durch Millis abgewartet
        digitalWrite(enable1, LOW);                             //Rechter Motor fährt für "kurvenzeit" rückwärts, um sich wieder in Normalposition zu begeben
        linksfertig = 1;                                        //Flag "linksfertig" wird auf 1 gesetzt, so dass das Unterprogramm "linkskurve" nicht mehr ausgeführt wird, bis die Flag zurückgesetzt wird
        rechtsbereit = 1;                                       //Flag "rechtsbereit" wird auf 1 gesetzt, so dass jetzt das Unterprogramm "rechtskurve" ausgeführt werden kann
    }
  }
  }
}
}

void rechtskurve() {                                            //Unterprogramm "rechtskurve"
if(rechtsflag == 0){                                            //Die Variable "rechtskurvemillis" wird auf die aktuellen "millis" gesetzt, mithilfe einer Flag wird sichergestellt
  rechtskurvemillis = millis();                                 //das dies nur 1 mal passiert, bis die Flag wieder zurückgesetzt wird.
}
rechtsflag = 1;

analogWrite(enable2, enablewert2);
digitalWrite(enable1, LOW);
digitalWrite(motor21, HIGH);
digitalWrite(motor22, LOW);                                     //Linker Motor gibt Gas

if(millis() - rechtskurvemillis >= kurvezeit){                  //"kurvenzeit" wird durch Millis abgewartet
  digitalWrite(enable2,LOW);

  digitalWrite(trigger, HIGH);
  if(millis() - rechtskurvemillis >= kurvezeit + 10){           //10ms wird durch Millis abgewartet
    digitalWrite(trigger, LOW);                                 //Ultraschallwellen werden für 10ms über den Sender/Trigger ausgestrahlt
    
    dauer = pulseIn(echo, HIGH);                                //Der Zeitabstand zwischen dem Ausschalten bis der Empfänger eine Welle empfängt, wird gemessen und auf die Variable "dauer" gespeichert
    entfernungr = (dauer / 2) * 0.0343;                         //Die Zeit wird durch 2 geteilt (wegen Hin- und Rückweg) und mit der Schallgeschwindigkeit multiplizieren, so dass man ein Maßstab hat. Dieser
                                                                //wird auf der Variable "entfernungr" gespeichert.

    if(millis() - rechtskurvemillis >= kurvezeit + 10 + 500){   //500ms (Rechenzeit) wird durch Millis abgewartet
      analogWrite(enable2, enablewert2);
      digitalWrite(motor21, LOW);
      digitalWrite(motor22, HIGH);
      if(millis() - rechtskurvemillis >= kurvezeit + 10 + kurvezeit + 500){ //"kurvenzeit" wird durch Millis abgewartet
        digitalWrite(enable2, LOW);                             //Linker Motor fährt für "kurvenzeit" rückwärts, um sich wieder in Normalposition zu begeben
        rechtsfertig = 1;                                       //Flag "rechtsfertig" wird auf 1 gesetzt, so dass das Unterprogramm "rechtskurve" nicht mehr ausgeführt wird, bis die Flag zurückgesetzt wird
        entscheidungsbereit = 1;                                //Flag "entscheidungsbereit" wird auf 1 gesetzt, so dass jetzt das Unterprogramm "entscheidung" ausgeführt werden kann
      }
    }
  }
}
}

void entscheidung() {                                           //Unterprogramm "rechtskurve"
if(entscheidungflag == 0){                                      //Die Variable "rechtskurvemillis" wird auf die aktuellen "millis" gesetzt, mithilfe einer Flag wird sichergestellt
  entscheidungmillis = millis();                                //das dies nur 1 mal passiert, bis die Flag wieder zurückgesetzt wird.
}
entscheidungflag = 1;
  
if(entfernungl>entfernungr){                                    //Wenn die vorhin errechnete Entfernung "entfernungl" größer als die Entfernung "entfernungr" ist,
  analogWrite(enable1, enablewert1);                            //dann gibt der rechte Motor gas
  digitalWrite(enable2, LOW);
  digitalWrite(motor11, HIGH);
  digitalWrite(motor12, LOW);

  if(millis() - entscheidungmillis >= kurvezeit){               //"kurvenzeit" wird durch Millis abgewartet
    digitalWrite(enable1, LOW);                                 //rechter Motor wird wieder abgeschaltet
    resetallflag();                                             //Unterprogramm "resetallflag" wird ausgeführt, da dass das Ende des "fahren" Unterprogramms ist
  }

}
else{
  analogWrite(enable2, enablewert2);                            //Wenn die vorhin errechnete Entfernung "entfernungl" nicht größer als die Entfernung "entfernungr" ist,
  digitalWrite(enable1, LOW);                                   //dann gibt der linke Motor gas
  digitalWrite(motor21, HIGH);
  digitalWrite(motor22, LOW);

  if(millis() - entscheidungmillis >= kurvezeit){               //"kurvenzeit" wird durch Millis abgewartet
    digitalWrite(enable2, LOW);                                 //linker Motor wird wieder abgeschaltet
    resetallflag();                                             //Unterprogramm "resetallflag" wird ausgeführt, da dass das Ende des "fahren" Unterprogramms ist
  }
}
}

void fvorne(){                                                  //Unterprogramm "fvorne"
  analogWrite(enable1, enablewert1);
  analogWrite(enable2, enablewert2);
  digitalWrite(motor11, HIGH);
  digitalWrite(motor12, LOW);
  digitalWrite(motor21, HIGH);
  digitalWrite(motor22, LOW);
  delay(1000);
  digitalWrite(enable1, LOW);
  digitalWrite(enable2, LOW);                                   //Beide Motor fahren für 1s nach Vorne
}


void fhinten(){                                                 //Unterprogramm "fhinten"
  analogWrite(enable1, enablewert1);
  analogWrite(enable2, enablewert2);
  digitalWrite(motor11, LOW);
  digitalWrite(motor12, HIGH);
  digitalWrite(motor21, LOW);
  digitalWrite(motor22, HIGH);
  delay(1000);
  digitalWrite(enable1, LOW);
  digitalWrite(enable2, LOW);                                   //Beide Motor fahren für 1s nach Hinten
}


void frechts(){                                                 //Unterprogramm "frechts"
  digitalWrite(enable1, LOW);
  analogWrite(enable2, enablewert2);
  digitalWrite(motor21, HIGH);
  digitalWrite(motor22, LOW);
  delay(kurvezeit);
  digitalWrite(enable2, LOW);                                   //Linker Motor macht eine Rechtskurve / Linker Motor gibt für "kurvenzeit" gas
}


void flinks(){                                                  //Unterprogramm "flinks"
  analogWrite(enable1, enablewert1);
  digitalWrite(enable2, LOW);
  digitalWrite(motor11, HIGH);
  digitalWrite(motor12, LOW);
  delay(kurvezeit);
  digitalWrite(enable1, LOW);                                   //Rechter Motor macht eine Rechtskurve / Rechter Motor gibt für "kurvenzeit" gas
}

Dann ersetz mal das setup.

void setup()
{
  //----- Definieren -----
  //Motoren
  digitalWrite(enable1, LOW);
  digitalWrite(enable2, LOW);
  digitalWrite(motor11, LOW);
  digitalWrite(motor12, LOW);
  digitalWrite(motor21, LOW);
  digitalWrite(motor22, LOW);
  pinMode(enable1, OUTPUT);
  pinMode(enable2, OUTPUT);
  pinMode(motor11, OUTPUT);
  pinMode(motor12, OUTPUT);
  pinMode(motor21, OUTPUT);
  pinMode(motor22, OUTPUT);
  //Ultraschall
  pinMode(trigger, OUTPUT);
  pinMode(echo, INPUT);
  //IR-Remote
  receiver.blink13(true);                                     //Blinklicht des IR-Empfängers wird aktiviert
  receiver.enableIRIn();                                      //IR-Empfänger wird als Eingang gekennzeichnet
  //Serieller Monitor
  Serial.begin(9600);                                         //Serieller Monitor wird gestartet
  Serial.println(F("Start..."));
  delay(10000);
}

Bitte auf dem Seriellen Monitor schauen. Nach der Ausgabe von "Start" bleibt der Code 10 Sekunden stehen. In der Zeit darf sich kein Motor bewegen.

Wenn dem so ist, dann darf auch danacvh sich kein Motor bewegen, bis Du Start auf der FB auslöst.

Nein, ich meine eigentlich der Motor dreht sich erst, wenn ich mit der Fernbedienung das Unterprogramm Fahren aktiviere

Schreib was Du erwartest und was Du machst.
Im ersten Beitrag war es ein fehlender Stop, jetzt dreht der Motor erst wenn Du das auslöst und es ist auch nicht richtig ;(

Bin sicher, dass @my_xy_projekt das Problem schon lösen wird.

Ein kleiner Vorschlag:

Zur besseren Lesbarkeit könnte man die Ansteuerung der Motoren in Funktionen "verpacken"; um nicht zuviel auf einmal zu ändern, habe ich die grundsätzliche Vorgehensweise nicht geändert (da könnte man sicher auch noch durch Array-Nutzung einiges optimieren).

Mit MotorVorwaerts(1) wird Motor 1 angesteuert und entsprechend MotorVorwaerts(2) der zweite. Mit MotorVorwaerts(3) werden beide Motoren angesprochen.

Eine Verschachtelung der Befehle ist m.E. aufgrund der Geschwindigkeit des Controllers gegenüber der Trägheit der Motoren nicht erforderlich.

Dadurch sollte der Code besser lesbar werden. Wenn man will, kann man noch zusätzlich enums für das Ansprechen der Motoren vergeben, oder einfach definieren:

#define RECHTS  = 1
#define LINKS     = 2
#define BEIDE     = 3

// Beispiele
MotorVorwaerts(LINKS);
MotorRueckwaerts(RECHTS);
MotorStop(BEIDE);

void MotorVorwaerts(int No) {
  if (No == 1) {
    analogWrite(enable1, enablewert1);
    digitalWrite(motor11, HIGH);
    digitalWrite(motor12, LOW);
  };
  if (No == 2) {
    analogWrite(enable2, enablewert2);
    digitalWrite(motor21, HIGH);
    digitalWrite(motor22, LOW);
  };
  if (No == 3) {
    MotorVorwaerts(1);
    MotorVorwaerts(2);
  };
}

void MotorRueckwaerts(int No) {
  if (No == 1) {
    analogWrite(enable1, enablewert1);
    digitalWrite(motor11, LOW);
    digitalWrite(motor12, HIGH);
  };
  if (No == 2) {
    analogWrite(enable2, enablewert2);
    digitalWrite(motor21, LOW);
    digitalWrite(motor22, HIGH);
  };
  if (No == 3) {
    MotorRueckwaerts(1);
    MotorRueckwaerts(2);
  };
}

void MotorStop(int No) {
  if (No == 1) {
    digitalWrite(enable1, LOW);
  };
  if (No == 2) {
    digitalWrite(enable2, LOW);
  };
  if (No == 3) {
    MotorStop(1);
    MotorStop(2);
  };
}

Na Du hast ja Humor, jetzt den Druck auch noch erhöhen.... Ups... falscher Thread - dafür gibts die Druckluftbox :upside_down_face:

Na mal sehen, was kommt - ich würde erstmal aufräumen, die defines auflösen und dann sehen, das ich serielle Ausgaben baue um zu sehen, wo ich im Code bin.

Quatsch, habe vollstes Vertrauen in Deine Fähigkeiten, Probleme zu lösen ...
Und genau:

  • Defines auflösen
  • Funktionen für wiederholte Aufgaben einführen
  • Damit die Übersicht verbessern

Man könnte auch Arrays einführen, um die beiden Motoren per Index anzusprechen. Mein Vorschlag nutzt aber die einfacher nachzuvollziehenden direkten Aufrufe aus, damit sich die Lernenden im Code auch wiederfinden.

Wiederholungen vermeiden und "lesbaren" Code schreiben, halte ich für eines der unmittelbaren Lernziele.

Las ich in mein nächstes Zeugnis schreiben :innocent:
Danke.

Hehe, habe eben gesehen: Das 7-Segment-Wurfspiel wird Dich noch weiter begleiten :wink: :innocent: :cry:

Sorry für alle Unannehmlichkeiten!

Unser Lehrer will das so, find ich auch too much.

Ja, ist bloß irgendwie bisschen schwierig, wenn ich überall so Millis() Klammern hab, oder? (Bin noch neu mit denen)

Wie auch immer, auf Tinkercad hab mussten wir das ganze nachbauen und dort funktioniert komischerweise auch der Code. Hier ist mein Tinkercad Projekt.

Allerdings gibt es auch unterschiede, während ich wenn ich in echt auf der Fernbedienung z.B. die Vol+ Taste drücke fährt er für 1s nach vorne. Bei Tinkercad fährt er unendlich Lang nach Vorne, bis man Stop drückt.
Hier habe ich damit gearbeitet, dass der Microbot das Programm nur ausführt, wenn steuerflag 0 ist. Steuerflag wird dann 0 wenn, der Receiver ein Signal aufnimmt, was einer der Buttons der Steuerung ist. Weil der Bot in Tinkercad durchgehend nach fährt, schließe ich darauf in Tinkercad durchgehend das Signal der gedrückten Taste ankommt, obwohl diese garr nicht mehr gedrückt ist. Hoffe das ist einigermaßen Verständlich.

Vielleicht hat irgendjemand noch eine Idee, weil es in Tinkercad ja funktioniert.

Kleine Erklärung nochmal, was das Programm machen soll:

  • Vol+ Taste gedrückt ➥ Fährt mit beiden Motoren für 1s nach vorne
  • Vol- Taste gedrückt ➥ Fährt mit beiden Motoren für 1s nach hinten
  • Überspringen Rechts Taste gedrückt ➥ Fährt mit linkem Motor für kurvenzeit
  • Überspringen Links Taste gedrückt ➥ Fährt mit rechtem Motor für kurvenzeit
  • Power Taste gedrückt ⇩
    1. Mit Ultraschallsensor wird gemessen, wenn über 35cm entfernt dann fährt für 1s geradeaus mit beiden Motoren. Sonst:
    2. Macht eine Rechtskurve, misst, rechnet, fährt zurück in Normalposition
    3. Macht eine Linkskurve, misst, rechnet, fährt zurück in Normalposition
    4. Entscheidet sich, wo mehr Platz, dreht sich dahin
    5. Fängt von Vorne an
  • Stop Taste gedrückt ➥ Stoppt Power Taste (deshalb auch mit Millis() oder BlinkWithoutDelay)

Alles gut...
Kannst Du mal den aktuellen Code - und bitte wenigstens ein paar grundlegende Kommentare für die Tastencodes - hier rein packen...
Dann schaun wa mal.
Gibt ja nen Plan :wink:

Die millis() hindern ja nicht daran die in meinem Post vorgeschlagenen Funktionen einzusetzen: Hier mal ein Beispiel:

void rechtskurve() {                                            //Unterprogramm "rechtskurve"
if(rechtsflag == 0){                                            //Die Variable "rechtskurvemillis" wird auf die aktuellen "millis" gesetzt, mithilfe einer Flag wird sichergestellt
  rechtskurvemillis = millis();                                 //das dies nur 1 mal passiert, bis die Flag wieder zurückgesetzt wird.
}
rechtsflag = 1;


//digitalWrite(enable1, LOW);
MotorStop(RECHTS); 
// analogWrite(enable2, enablewert2);
//digitalWrite(motor21, HIGH);
//digitalWrite(motor22, LOW);                                     //Linker Motor gibt Gas
MotorVorwaerts(LINKS);

if(millis() - rechtskurvemillis >= kurvezeit){                  //"kurvenzeit" wird durch Millis abgewartet
  //digitalWrite(enable2,LOW);
  MotorStop(LINKS);
  digitalWrite(trigger, HIGH);
  if(millis() - rechtskurvemillis >= kurvezeit + 10){           //10ms wird durch Millis abgewartet
    digitalWrite(trigger, LOW);                                 //Ultraschallwellen werden für 10ms über den Sender/Trigger ausgestrahlt
    
    dauer = pulseIn(echo, HIGH);                                //Der Zeitabstand zwischen dem Ausschalten bis der Empfänger eine Welle empfängt, wird gemessen und auf die Variable "dauer" gespeichert
    entfernungr = (dauer / 2) * 0.0343;                         //Die Zeit wird durch 2 geteilt (wegen Hin- und Rückweg) und mit der Schallgeschwindigkeit multiplizieren, so dass man ein Maßstab hat. Dieser
                                                                //wird auf der Variable "entfernungr" gespeichert.

    if(millis() - rechtskurvemillis >= kurvezeit + 10 + 500){   //500ms (Rechenzeit) wird durch Millis abgewartet
      //analogWrite(enable2, enablewert2);
      //digitalWrite(motor21, LOW);
      //digitalWrite(motor22, HIGH);
      MotorRueckwaerts(LINKS);
      if(millis() - rechtskurvemillis >= kurvezeit + 10 + kurvezeit + 500){ //"kurvenzeit" wird durch Millis abgewartet
        //digitalWrite(enable2, LOW);                             //Linker Motor fährt für "kurvenzeit" rückwärts, um sich wieder in Normalposition zu begeben
        MotorStop(LINKS);
        rechtsfertig = 1;                                       //Flag "rechtsfertig" wird auf 1 gesetzt, so dass das Unterprogramm "rechtskurve" nicht mehr ausgeführt wird, bis die Flag zurückgesetzt wird
        entscheidungsbereit = 1;                                //Flag "entscheidungsbereit" wird auf 1 gesetzt, so dass jetzt das Unterprogramm "entscheidung" ausgeführt werden kann
      }
    }
  }
}
}

Und ohne die auskommentierten vorherigen Funktionen sieht das dann so aus:

void rechtskurve() {                                            //Unterprogramm "rechtskurve"
if(rechtsflag == 0){                                            //Die Variable "rechtskurvemillis" wird auf die aktuellen "millis" gesetzt, mithilfe einer Flag wird sichergestellt
  rechtskurvemillis = millis();                                 //das dies nur 1 mal passiert, bis die Flag wieder zurückgesetzt wird.
}
rechtsflag = 1;
MotorStop(RECHTS); 
MotorVorwaerts(LINKS);
if(millis() - rechtskurvemillis >= kurvezeit){                  //"kurvenzeit" wird durch Millis abgewartet
  MotorStop(LINKS);
  digitalWrite(trigger, HIGH);
  if(millis() - rechtskurvemillis >= kurvezeit + 10){           //10ms wird durch Millis abgewartet
    digitalWrite(trigger, LOW);                                 //Ultraschallwellen werden für 10ms über den Sender/Trigger ausgestrahlt
    dauer = pulseIn(echo, HIGH);                                //Der Zeitabstand zwischen dem Ausschalten bis der Empfänger eine Welle empfängt, wird gemessen und auf die Variable "dauer" gespeichert
    entfernungr = (dauer / 2) * 0.0343;                         //Die Zeit wird durch 2 geteilt (wegen Hin- und Rückweg) und mit der Schallgeschwindigkeit multiplizieren, so dass man ein Maßstab hat. Dieser
    if(millis() - rechtskurvemillis >= kurvezeit + 10 + 500){   //500ms (Rechenzeit) wird durch Millis abgewartet
      MotorRueckwaerts(LINKS);
      if(millis() - rechtskurvemillis >= kurvezeit + 10 + kurvezeit + 500){ //"kurvenzeit" wird durch Millis abgewartet
        MotorStop(LINKS);
        rechtsfertig = 1;                                       //Flag "rechtsfertig" wird auf 1 gesetzt, so dass das Unterprogramm "rechtskurve" nicht mehr ausgeführt wird, bis die Flag zurückgesetzt wird
        entscheidungsbereit = 1;                                //Flag "entscheidungsbereit" wird auf 1 gesetzt, so dass jetzt das Unterprogramm "entscheidung" ausgeführt werden kann
      }
    }
  }
 }
}

Allerdings zeigt die Vereinfachung der Lesbarkeit gleich Folgendes:

  • Wenn RechtsKurve nur einmal aufgerufen wird, nützen die if-millis() nichts, da sie NICHT warten. Hier müsste stattdessen so etwas wie
while (millis() - rechtskurvemillis < kurvezeit + 10) {..}

stehen oder

while (!(millis() - rechtskurvemillis >= kurvezeit + 10)) {..}

Falls rechtskurve() periodisch aufgerufen würde, wäre es anderseits hinderlich, wenn immer wieder

MotorStop(RECHTS); 
MotorVorwaerts(LINKS);

aufgerufen wird, während danach (wenn die Zeit abgelaufen ist, nacheinander

MotorStop(LINKS);
  // Hier mal die nicht relevanten Zeile weggelöscht 
  if(millis() - rechtskurvemillis >= kurvezeit + 10){           //10ms wird durch Millis abgewartet
    if(millis() - rechtskurvemillis >= kurvezeit + 10 + 500){   //500ms (Rechenzeit) wird durch Millis abgewartet
      MotorRueckwaerts(LINKS);
      if(millis() - rechtskurvemillis >= kurvezeit + 10 + kurvezeit + 500){ //"kurvenzeit" wird durch Millis abgewartet
        MotorStop(LINKS);

Stop, Rückwärts und wieder Stop aufgerufen wird.

Wenn ich mich nicht täusche, müsste man die Verschachtelung auflösen und dafür sorgen, dass immer nur eine der Bedingungen erfüllt wird.

So könnte es aussehen, wenn man rechtskurve() periodisch aufruft (auf die Schnelle, beispielhaft, Ihr müsst das mit Eurer Logik vergleichen, wann was passieren soll):

void Measure Distance() {
  digitalWrite(trigger, HIGH);
  delay(10);                                                    //10ms abwarten
  digitalWrite(trigger, LOW);                                 //Ultraschallwellen werden für 10ms über den Sender/Trigger ausgestrahlt
  dauer = pulseIn(echo, HIGH);                                //Der Zeitabstand zwischen dem Ausschalten bis der Empfänger eine Welle empfängt, wird gemessen und auf die Variable "dauer" gespeichert
  entfernungr = (dauer / 2) * 0.0343;                         //Die Zeit wird durch 2 geteilt (wegen Hin- und Rückweg) und mit der Schallgeschwindigkeit multiplizieren, so dass man ein Maßstab hat. Dieser
}

void rechtskurve() {                                            //Unterprogramm "rechtskurve"
  if (rechtsflag == 0) {                                          //Die Variable "rechtskurvemillis" wird auf die aktuellen "millis" gesetzt, mithilfe einer Flag wird sichergestellt
    rechtskurvemillis = millis();                                 //das dies nur 1 mal passiert, bis die Flag wieder zurückgesetzt wird.
    MotorStop(RECHTS);
    MotorVorwaerts(LINKS);
  }
  rechtsflag = 1;
  int modus = 0;
  if (millis() - rechtskurvemillis >= kurvezeit) modus = 1;                  //"kurvenzeit" wird durch Millis abgewartet
  if (millis() - rechtskurvemillis >= kurvezeit + 10 + 500) modus = 2;
  if (millis() - rechtskurvemillis >= kurvezeit + 10 + kurvezeit + 500) modus = 3;
  if (modus == 1) {
    MotorStop(LINKS);
    Measure_Distance();
  }
  if (modus == 2)    {  //500ms (Rechenzeit) wird durch Millis abgewartet
    MotorRueckwaerts(LINKS);
    Measure_Distance();
  }
  if (modus == 3) {
    MotorStop(LINKS);
    Measure_Distance();
    rechtsfertig = 1;                                       //Flag "rechtsfertig" wird auf 1 gesetzt, so dass das Unterprogramm "rechtskurve" nicht mehr ausgeführt wird, bis die Flag zurückgesetzt wird
    entscheidungsbereit = 1;                                //Flag "entscheidungsbereit" wird auf 1 gesetzt, so dass jetzt das Unterprogramm "entscheidung" ausgeführt werden kann
  }
 }

Die Periodizität kann man natürlich auch in die Funktion einbauen:

void Measure Distance() {
  digitalWrite(trigger, HIGH);
  delay(10);                                                    //10ms abwarten
  digitalWrite(trigger, LOW);                                 //Ultraschallwellen werden für 10ms über den Sender/Trigger ausgestrahlt
  dauer = pulseIn(echo, HIGH);                                //Der Zeitabstand zwischen dem Ausschalten bis der Empfänger eine Welle empfängt, wird gemessen und auf die Variable "dauer" gespeichert
  entfernungr = (dauer / 2) * 0.0343;                         //Die Zeit wird durch 2 geteilt (wegen Hin- und Rückweg) und mit der Schallgeschwindigkeit multiplizieren, so dass man ein Maßstab hat. Dieser
}

void rechtskurve() {                                            //Unterprogramm "rechtskurve"
  int modus = 0;
  while(modus < 3) {
  if (rechtsflag == 0) {                                          //Die Variable "rechtskurvemillis" wird auf die aktuellen "millis" gesetzt, mithilfe einer Flag wird sichergestellt
    rechtskurvemillis = millis();                                 //das dies nur 1 mal passiert, bis die Flag wieder zurückgesetzt wird.
    MotorStop(RECHTS);
    MotorVorwaerts(LINKS);
  }
  rechtsflag = 1;
  if (millis() - rechtskurvemillis >= kurvezeit) modus = 1;                  //"kurvenzeit" wird durch Millis abgewartet
  if (millis() - rechtskurvemillis >= kurvezeit + 10 + 500) modus = 2;
  if (millis() - rechtskurvemillis >= kurvezeit + 10 + kurvezeit + 500) modus = 3;
  if (modus == 1) {
    MotorStop(LINKS);
    Measure_Distance();
  }
  if (modus == 2)    {  //500ms (Rechenzeit) wird durch Millis abgewartet
    MotorRueckwaerts(LINKS);
    Measure_Distance();
  }
  if (modus == 3) {
    MotorStop(LINKS);
    Measure_Distance();
    rechtsfertig = 1;                                       //Flag "rechtsfertig" wird auf 1 gesetzt, so dass das Unterprogramm "rechtskurve" nicht mehr ausgeführt wird, bis die Flag zurückgesetzt wird
    entscheidungsbereit = 1;                                //Flag "entscheidungsbereit" wird auf 1 gesetzt, so dass jetzt das Unterprogramm "entscheidung" ausgeführt werden kann
  }
  }
 }