Schleife mittels Tastendruck verlassen?

Hallo zusammen,

mein LDR Projekt hab ich erstmal auf Eis gelegt, da ich mir schon dachte, für Kinder eher uninteressant. Hab mich dann doch eher für einen HC-SR04 entschieden. Das läuft auch alles stabil, ABER ich hätte gerne das die Funktion taschenlampe() solange wiederholt wird, bis ein anderer Tastendruck z.B. F die Funktion abbricht und er zu Bluetooth zurückkehrt. Ich hab schon mit while und for rum experimentiert, aber kam immer nicht mehr aus der Schleife raus

/**
   Author: Omar Draidrya
   Date: 2024/07/03
   This code controls the forward and backward movement of a motor using an H-bridge.
*/

#include <AFMotor.h>
#include <Arduino.h>
byte triggerPin = A4;
byte echoPin = A5;
int duration, distance;
int number = 0;
byte star = 1;
AF_DCMotor motor1(1);  // Create motor #1 using M1 connector
AF_DCMotor motor2(2);  // Create motor #2 using M2 connector
AF_DCMotor motor3(3);  // Create motor #3 using M3 connector
AF_DCMotor motor4(4);  // Create motor #4 using M4 connector

char command;

void setup() {
  Serial.begin(9600);    // Start serial communication at 9600 baud rate
  motor1.setSpeed(150);  // Set initial motor speeds
  motor2.setSpeed(150);
  motor3.setSpeed(150);
  motor4.setSpeed(150);
  pinMode(triggerPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() {
  connection();
  taschenlampe_data();
}

void connection() {
  if (Serial.available() > 0) {
    command = Serial.read();
    Serial.println(command);  // Read the incoming command
    switch (command) {
      case 'F':
        forward();

        break;
      case 'B':
        backward();

        break;
      case 'L':
        turnLeft();

        break;
      case 'R':
        turnRight();

        break;
      case 'S':
        stop();

        break;
      case 'X':
        taschenlampe();
        break;
    }
  }
}

void taschenlampe_data() {

  distance = 0;
  digitalWrite(triggerPin, LOW);
  delayMicroseconds(4);
  digitalWrite(triggerPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(triggerPin, LOW);

  duration = pulseIn(echoPin, HIGH);
  distance = round(duration * .0343) / 2;
  Serial.print("Distance: ");
  Serial.println(distance);
  delay(100);
}

void taschenlampe() {
  switch (distance) {
    case 1 ... 15:
      backward();
      //Serial.println("vorwärts");
      delay(1200);
      drive();
      //Serial.println(number);
      break;
    case 16 ... 30:
      motor1.setSpeed(90);
      motor2.setSpeed(90);
      motor3.setSpeed(90);
      motor4.setSpeed(90);
      forward();
      //Serial.println("langsam vor");

      break;
    case 31 ... 300:
      forward();
      //Serial.println("Vorwaerts");

      break;
    default:
      backward();
      //Serial.println("default");
      break;
  
}}


void drive() {
  number = random(3);
  if (number == 1) {
    turnLeft();
    delay(1500);
  } else {
    turnRight();
    delay(1500);
  }
}


void forward() {
  motor1.run(FORWARD);
  motor2.run(FORWARD);
  motor3.run(FORWARD);
  motor4.run(FORWARD);
}

void backward() {
  motor1.run(BACKWARD);
  motor2.run(BACKWARD);
  motor3.run(BACKWARD);
  motor4.run(BACKWARD);
}

void turnLeft() {
  motor1.run(BACKWARD);
  motor2.run(BACKWARD);
  motor3.run(FORWARD);
  motor4.run(FORWARD);
}

void turnRight() {
  motor1.run(FORWARD);
  motor2.run(FORWARD);
  motor3.run(BACKWARD);
  motor4.run(BACKWARD);
}

void stop() {
  motor1.run(RELEASE);
  motor2.run(RELEASE);
  motor3.run(RELEASE);
  motor4.run(RELEASE);
}

dein connection() reagiert nur auf neu hereinkommende Befehle.
ein Befehl löst eine Funktion somit einmal aus.
EINMAL.
Was du machen könntest, dass du dir auch merkst was der letzte Befehl war.
Dann kannst du z.B. im loop auch prüfen, ob der letzte Befehl 'X' war und die taschenlampe() ausführen.

Sauberer ist, du zeichnest dir eine klare finite state machine, führst bestimmte befehle bei einem Statusübergang aus (stop(), forward(), ...) bzw. machst auch aktivitäten dauerhaft (z.b. taschenlampe())

Du kommst dir selbst in die Quere. In

UND in

steuerst du Motoren an. Du brauchst zuerst einmal einen Plan, was wann geschehen soll. Diesen Plan setzt du dann in einer finite state machine um. In jeden State gibt es eine oder mehrere Bedingungen, wie der Status verlassen werden kann und was dann die Aktion ist und was der neue Status ist. Ohne eine Statemaschine wirst du dein Auto nie richtig zum laufen bekommen.

Und noch was: Vergiss das es delay gibt. Wartezeiten werden auch in der Statemaschine gemacht. Bei dem Auto ist ein delay fahren ohne die Hände am Lenkrad zu haben und mit geschlossenen Augen. Die nächste Wand kommt bestimmt.

while und for brauchst du nicht. Du hast eine Schleife und die heißt loop.

In einem deiner ersten threats hatte ich Dir das schon mal gebaut, dass Du zwei unterschiedliche Quellen nutzen kannst.

Das ändert sich nicht, wenn Du eine Quelle änderst.

ok dann gucke ich dass nochmal durch :wink:

Das ist kinderleicht.

Einfach in der While-Schleife die Taste abfragen und dann die Bedingung der Schleife ändern. Meist bedeutet das, den Pin_Status abzufragen, an den die Taste angeklemmt ist. Man muss sich nur mit sich selbst einigen, ob Low oder High der "unbenutzte" Zustand ist, und abfragen ob der Zustand ein anderer ist.

Alternativ :

Gruß

Pucki.

Das schlimmste was es gibt, dafür ist die loop da, und nicht blockieren ganze loop.
Dazu nicht gelesen ! es wird kein Taster benutzt.
Und komm nicht mit blöden Kommentaren!.

Ähmm...
loop() ist eine Funktion, keine Schleife.

Schnell mal während eines Vortrages umgeschrieben - die denken alle ich bin ganz fleissig :grin:

/*
https://forum.arduino.cc/t/schleife-mittels-tastendruck-verlassen/1406825/
*/

#include <AFMotor.h>
#include <Arduino.h>
byte triggerPin = A4;
byte echoPin = A5;
int duration, distance;
int number = 0;
byte star = 1;
AF_DCMotor motor1(1);  // Create motor #1 using M1 connector
AF_DCMotor motor2(2);  // Create motor #2 using M2 connector
AF_DCMotor motor3(3);  // Create motor #3 using M3 connector
AF_DCMotor motor4(4);  // Create motor #4 using M4 connector

const char befehle[] = {'F', 'B', 'L', 'R', 'S', 'X'};

char command;

void setup()
{
  Serial.begin(9600);    // Start serial communication at 9600 baud rate
  motor1.setSpeed(150);  // Set initial motor speeds
  motor2.setSpeed(150);
  motor3.setSpeed(150);
  motor4.setSpeed(150);
  pinMode(triggerPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop()
{
  connection();
  action();
}

void connection()
{
  if (Serial.available() > 0)
  {
    char newCommand = Serial.read();
    Serial.println(command);  // Read the incoming command

    if (newCommand != command && isPrintable(newCommand)) // Neues Zeichen und ist anzeigbar
    {
      Serial.print(F("Neues Commando: "));                // ausgeben
      Serial.println(newCommand, HEX);

      for (byte b = 0; b < sizeof(befehle) / sizeof(befehle[0]); b++) // zähle durch alle vorandenen Werte
      {
        if (befehle[b] == newCommand)                                 // wenn vorhanden, dann übernehmen
        { command = newCommand; }
      }
    }
  }
}

void action()
{
  switch (command)
  {
    case 'F':
      forward();
      break;

    case 'B':
      backward();
      break;

    case 'L':
      turnLeft();
      break;

    case 'R':
      turnRight();
      break;

    case 'S':
      stop();
      break;

    case 'X':
      taschenlampe();
      break;
  }
}

void taschenlampe_data()
{
  distance = 0;
  digitalWrite(triggerPin, LOW);
  delayMicroseconds(4);
  digitalWrite(triggerPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(triggerPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = round(duration * .0343) / 2;
  Serial.print("Distance: ");
  Serial.println(distance);
  delay(100);
}
void taschenlampe()
{
  switch (distance)
  {
    case 1 ... 15:
      backward();
      //Serial.println("vorwärts");
      drive();
      //Serial.println(number);
      break;

    case 16 ... 30:
      motor1.setSpeed(90);
      motor2.setSpeed(90);
      motor3.setSpeed(90);
      motor4.setSpeed(90);
      forward();
      //Serial.println("langsam vor");
      break;

    case 31 ... 300:
      forward();
      //Serial.println("Vorwaerts");
      break;

    default:
      backward();
      //Serial.println("default");
      break;
  }
}
void drive()
{
  number = random(3);

  if (number == 1)
  {
    turnLeft();
    delay(1500);
  }
  else
  {
    turnRight();
    delay(1500);
  }
}
void forward()
{
  motor1.run(FORWARD);
  motor2.run(FORWARD);
  motor3.run(FORWARD);
  motor4.run(FORWARD);
}
void backward()
{
  motor1.run(BACKWARD);
  motor2.run(BACKWARD);
  motor3.run(BACKWARD);
  motor4.run(BACKWARD);
}
void turnLeft()
{
  motor1.run(BACKWARD);
  motor2.run(BACKWARD);
  motor3.run(FORWARD);
  motor4.run(FORWARD);
}
void turnRight()
{
  motor1.run(FORWARD);
  motor2.run(FORWARD);
  motor3.run(BACKWARD);
  motor4.run(BACKWARD);
}
void stop()
{
  motor1.run(RELEASE);
  motor2.run(RELEASE);
  motor3.run(RELEASE);
  motor4.run(RELEASE);
}

ich war auch fleissig :wink:

/**
   Author: Omar Draidrya
   Date: 2024/07/03
   This code controls the forward and backward movement of a motor using an H-bridge.
*/

#include <AFMotor.h>
#include <Arduino.h>
#include <Servo.h>
byte triggerPin = A4;
byte echoPin = A5;
long duration, distance;
int number = 0;
byte star = 1;
Servo myservo;
unsigned long lastServoAction;
long cm, cml, cmr;
int pos = 30;
bool richtung = true; 
int val;
constexpr uint8_t minPoint{ 45 };
constexpr uint8_t maxPoint{ 135 };
constexpr uint8_t servo{ 10 };
AF_DCMotor motor1(1);  // Create motor #1 using M1 connector
AF_DCMotor motor2(2);  // Create motor #2 using M2 connector
AF_DCMotor motor3(3);  // Create motor #3 using M3 connector
AF_DCMotor motor4(4);  // Create motor #4 using M4 connector

char BT_input;

void setup() {
  Serial.begin(9600);    // Start serial communication at 9600 baud rate
  motor1.setSpeed(150);  // Set initial motor speeds
  motor2.setSpeed(150);
  motor3.setSpeed(150);
  motor4.setSpeed(150);
  pinMode(triggerPin, OUTPUT);
  pinMode(echoPin, INPUT);
  myservo.attach(servo);
  myservo.write(minPoint);
}

void loop() {
  connection();
  setServoGetDist();
  ultra();
}

void connection() {
  if (Serial.available() > 0) {
    BT_input = Serial.read();
    Serial.println(BT_input);  // Read the incoming BT_input
    switch (BT_input) {
      case 'F':
        forward();

        break;
      case 'B':
        backward();

        break;
      case 'L':
        turnLeft();

        break;
      case 'R':
        turnRight();

        break;
      case 'S':
        stop();

        break;
      case 'X':
        automatic();
        break;
    }
  }
}

/*void taschenlampe() {
  distance = 0;
  digitalWrite(triggerPin, LOW);
  delayMicroseconds(4);
  digitalWrite(triggerPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(triggerPin, LOW);

  duration = pulseIn(echoPin, HIGH);
  distance = round(duration * .0343) / 2;
  Serial.print("Distance: ");
  Serial.println(distance);
  delay(100);
  switch (distance) {
    case 1 ... 15:
      backward();
      //Serial.println("vorwärts");
      delay(1200);
      drive();
      //Serial.println(number);
      break;
    case 16 ... 30:
      motor1.setSpeed(90);
      motor2.setSpeed(90);
      motor3.setSpeed(90);
      motor4.setSpeed(90);
      forward();
      //Serial.println("langsam vor");

      break;
    case 31 ... 300:
      forward();
      //Serial.println("Vorwaerts");

      break;
    default:
      backward();
      //Serial.println("default");
      break;
  
}}*/


void drive() {
  number = random(3);
  if (number == 1) {
    turnLeft();
    delay(1500);
  } else {
    turnRight();
    delay(1500);
  }
}


void forward() {
  motor1.run(FORWARD);
  motor2.run(FORWARD);
  motor3.run(FORWARD);
  motor4.run(FORWARD);
}

void backward() {
  motor1.run(BACKWARD);
  motor2.run(BACKWARD);
  motor3.run(BACKWARD);
  motor4.run(BACKWARD);
}

void turnLeft() {
  motor1.run(BACKWARD);
  motor2.run(BACKWARD);
  motor3.run(FORWARD);
  motor4.run(FORWARD);
}

void turnRight() {
  motor1.run(FORWARD);
  motor2.run(FORWARD);
  motor3.run(BACKWARD);
  motor4.run(BACKWARD);
}

void stop() {
  motor1.run(RELEASE);
  motor2.run(RELEASE);
  motor3.run(RELEASE);
  motor4.run(RELEASE);
}
void automatic() {
  static unsigned long lastAction = 0;
  static uint8_t State = 0;

  switch (State) {
    case 0:  //Foreward
      if ((cm < 30) || ((cm < 20) && (cmr < 20) && (cm < 20))) {
        Serial.println(F("zu eng...Stop"));
        stop();
        drive();  // erstmal anhalten
        State = 1;
        lastAction = millis();
      } else {
       forward();
      }
      break;
    case 1:  //Stop abwarten
      if (millis() - lastAction > 20) {
        lastAction = millis();
        Serial.println(F("Zurück"));
        backward();  // Rückwärts raus
        State = 2;
      }
      break;
    case 2:  //Zurück abwarten
      if (millis() - lastAction > 1000) {
        lastAction = millis();
        Serial.println(F("Stop"));
        stop();  // anhalten
        State = 3;
      }
      break;
    case 3:  //wohin?
      if (millis() - lastAction > 20) {
        lastAction = millis();
        if (cml < cmr) {  // Richtungsbewegung
          Serial.println(F("turnRight"));
          turnRight();
        } else {
          Serial.println(F("turnLeft"));
          turnLeft();
        }
        State = 4;
      }
      break;
    case 4:  //Stop abwarten
      if (millis() - lastAction > 20) {
        lastAction = millis();
        State = 0;
      }
      break;
  }
}

void setServoGetDist() {
  if (millis() - lastServoAction > 15) {                        // Pause für Echounterdrückung
    constexpr uint8_t fieldTicks{ (maxPoint - minPoint) / 3 };  // (40) gleichmässig Bereiche über den gesamten Arbeitsbereich verteilen
    static uint32_t tempData = 0;
    uint16_t d = ultra();
    tempData += d;
    /*
      Serial.print(F("Dura: "));
      Serial.print(d);
      Serial.print(F("  Summe: "));
      Serial.println(tempData);
    */
    lastServoAction = millis();

    switch (pos) {
      case minPoint:    // (30) ganz links
        if (!richtung)  // kommt von rechts
        {
          cml = tempData / (fieldTicks - 1);
        }
        Serial.println(F("Servo links"));
        richtung = HIGH;  // Richtungsumkehr
        tempData = 0;
        break;
      case minPoint + fieldTicks:  // (30+40 = 70)Ende linke Ausleuchtung - Anfang Mitte
        if (richtung) {            // Auf dem Weg nach rechts
          cml = tempData / (fieldTicks - 1);
        } else {  // auf dem Weg nach links
          cm = tempData / (fieldTicks - 1);
        }
        Serial.println(F("tick 70"));
        tempData = 0;
        break;
      case maxPoint - fieldTicks:  // (150-40 = 110) Ende Mitte - Anfang rechte Ausleuchtung
        if (!richtung) {           // Auf dem Weg nach links
          cmr = tempData / (fieldTicks - 1);
        } else {  // Auf dem Weg nach rechts
          cm = tempData / (fieldTicks - 1);
        }
        Serial.println(F("110 tick"));
        tempData = 0;
        break;
      case maxPoint:  // (150) ganz rechts
        if (richtung) {
          cmr = tempData / (fieldTicks - 1);
        }

        Serial.println(F("Servo rechts"));
        richtung = LOW;
        tempData = 0;
        break;
    }

    if (richtung) {
      pos++;
    } else {
      pos--;
    }

    // Fehlerbehandlung
    if (pos > maxPoint) {
      pos = maxPoint;
      Serial.println(F("maxPosFail"));
    }

    if (pos < minPoint) {
      pos = minPoint;
      Serial.println(F("minPosFail"));
    }
    myservo.write(pos);  // Servo setzen
  }
}
long ultra() {
  digitalWrite(triggerPin, LOW);
  delayMicroseconds(4);
  digitalWrite(triggerPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(triggerPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  return duration / 60;
}

Funktioniert, aber nur bedingt. Der Servo kommt mal wieder nicht aus dem Popo....

Und ja ich hab noch Servo nachgerüstet :wink:

Aus 2 mach 1


/*
https://forum.arduino.cc/t/schleife-mittels-tastendruck-verlassen/1406825/
*/

#include <AFMotor.h>
#include <Arduino.h>
#include <Servo.h>
byte triggerPin = A4;
byte echoPin = A5;
long duration, distance;
int number = 0;
Servo myservo;
unsigned long lastServoAction;
long cm, cml, cmr;
int pos = 30;
bool richtung = true; 
int val;
constexpr uint8_t minPoint{ 45 };
constexpr uint8_t maxPoint{ 135 };
constexpr uint8_t servo{ 10 };
AF_DCMotor motor1(1);  // Create motor #1 using M1 connector
AF_DCMotor motor2(2);  // Create motor #2 using M2 connector
AF_DCMotor motor3(3);  // Create motor #3 using M3 connector
AF_DCMotor motor4(4);  // Create motor #4 using M4 connector

const char befehle[] = {'F', 'B', 'L', 'R', 'S', 'X'};

char command;

void setup()
{
  Serial.begin(9600);    // Start serial communication at 9600 baud rate
  motor1.setSpeed(150);  // Set initial motor speeds
  motor2.setSpeed(150);
  motor3.setSpeed(150);
  motor4.setSpeed(150);
  pinMode(triggerPin, OUTPUT);
  pinMode(echoPin, INPUT);
    myservo.attach(servo);
  myservo.write(minPoint);
}

void loop()
{
  connection();
  action();
  setServoGetDist();
  ultra();
}

void connection()
{
  if (Serial.available() > 0)
  {
    char newCommand = Serial.read();
    Serial.println(command);  // Read the incoming command

    if (newCommand != command && isPrintable(newCommand)) // Neues Zeichen und ist anzeigbar
    {
      Serial.print(F("Neues Commando: "));                // ausgeben
      Serial.println(newCommand, HEX);

      for (byte b = 0; b < sizeof(befehle) / sizeof(befehle[0]); b++) // zähle durch alle vorandenen Werte
      {
        if (befehle[b] == newCommand)                                 // wenn vorhanden, dann übernehmen
        { command = newCommand; }
      }
    }
  }
}

void action()
{
  switch (command)
  {
    case 'F':
      forward();
      break;

    case 'B':
      backward();
      break;

    case 'L':
      turnLeft();
      break;

    case 'R':
      turnRight();
      break;

    case 'S':
      stop();
      break;

    case 'X':
      automatic();
      break;
  }
}

/*void taschenlampe_data()
{
  distance = 0;
  digitalWrite(triggerPin, LOW);
  delayMicroseconds(4);
  digitalWrite(triggerPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(triggerPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = round(duration * .0343) / 2;
  Serial.print("Distance: ");
  Serial.println(distance);
  delay(100);
}
void taschenlampe()
{
  switch (distance)
  {
    case 1 ... 15:
      backward();
      //Serial.println("vorwärts");
      drive();
      //Serial.println(number);
      break;

    case 16 ... 30:
      motor1.setSpeed(90);
      motor2.setSpeed(90);
      motor3.setSpeed(90);
      motor4.setSpeed(90);
      forward();
      //Serial.println("langsam vor");
      break;

    case 31 ... 300:
      forward();
      //Serial.println("Vorwaerts");
      break;

    default:
      backward();
      //Serial.println("default");
      break;
  }
}
*/
void drive()
{
  number = random(3);

  if (number == 1)
  {
    turnLeft();
    delay(1500);
  }
  else
  {
    turnRight();
    delay(1500);
  }
}
void forward()
{
  motor1.run(FORWARD);
  motor2.run(FORWARD);
  motor3.run(FORWARD);
  motor4.run(FORWARD);
}
void backward()
{
  motor1.run(BACKWARD);
  motor2.run(BACKWARD);
  motor3.run(BACKWARD);
  motor4.run(BACKWARD);
}
void turnLeft()
{
  motor1.run(BACKWARD);
  motor2.run(BACKWARD);
  motor3.run(FORWARD);
  motor4.run(FORWARD);
}
void turnRight()
{
  motor1.run(FORWARD);
  motor2.run(FORWARD);
  motor3.run(BACKWARD);
  motor4.run(BACKWARD);
}
void stop()
{
  motor1.run(RELEASE);
  motor2.run(RELEASE);
  motor3.run(RELEASE);
  motor4.run(RELEASE);
}
void automatic() {
  static unsigned long lastAction = 0;
  static uint8_t State = 0;

  switch (State) {
    case 0:  //Foreward
      if ((cm < 30) || ((cm < 20) && (cmr < 20) && (cm < 20))) {
        Serial.println(F("zu eng...Stop"));
        stop();
        drive();  // erstmal anhalten
        State = 1;
        lastAction = millis();
      } else {
       forward();
      }
      break;
    case 1:  //Stop abwarten
      if (millis() - lastAction > 20) {
        lastAction = millis();
        Serial.println(F("Zurück"));
        backward();  // Rückwärts raus
        State = 2;
      }
      break;
    case 2:  //Zurück abwarten
      if (millis() - lastAction > 1000) {
        lastAction = millis();
        Serial.println(F("Stop"));
        stop();  // anhalten
        State = 3;
      }
      break;
    case 3:  //wohin?
      if (millis() - lastAction > 20) {
        lastAction = millis();
        if (cml < cmr) {  // Richtungsbewegung
          Serial.println(F("turnRight"));
          turnRight();
        } else {
          Serial.println(F("turnLeft"));
          turnLeft();
        }
        State = 4;
      }
      break;
    case 4:  //Stop abwarten
      if (millis() - lastAction > 20) {
        lastAction = millis();
        State = 0;
      }
      break;
  }
}

void setServoGetDist() {
  if (millis() - lastServoAction > 15) {                        // Pause für Echounterdrückung
    constexpr uint8_t fieldTicks{ (maxPoint - minPoint) / 3 };  // (40) gleichmässig Bereiche über den gesamten Arbeitsbereich verteilen
    static uint32_t tempData = 0;
    uint16_t d = ultra();
    tempData += d;
    /*
      Serial.print(F("Dura: "));
      Serial.print(d);
      Serial.print(F("  Summe: "));
      Serial.println(tempData);
    */
    lastServoAction = millis();

    switch (pos) {
      case minPoint:    // (30) ganz links
        if (!richtung)  // kommt von rechts
        {
          cml = tempData / (fieldTicks - 1);
        }
        Serial.println(F("Servo links"));
        richtung = HIGH;  // Richtungsumkehr
        tempData = 0;
        break;
      case minPoint + fieldTicks:  // (30+40 = 70)Ende linke Ausleuchtung - Anfang Mitte
        if (richtung) {            // Auf dem Weg nach rechts
          cml = tempData / (fieldTicks - 1);
        } else {  // auf dem Weg nach links
          cm = tempData / (fieldTicks - 1);
        }
        Serial.println(F("tick 70"));
        tempData = 0;
        break;
      case maxPoint - fieldTicks:  // (150-40 = 110) Ende Mitte - Anfang rechte Ausleuchtung
        if (!richtung) {           // Auf dem Weg nach links
          cmr = tempData / (fieldTicks - 1);
        } else {  // Auf dem Weg nach rechts
          cm = tempData / (fieldTicks - 1);
        }
        Serial.println(F("110 tick"));
        tempData = 0;
        break;
      case maxPoint:  // (150) ganz rechts
        if (richtung) {
          cmr = tempData / (fieldTicks - 1);
        }

        Serial.println(F("Servo rechts"));
        richtung = LOW;
        tempData = 0;
        break;
    }

    if (richtung) {
      pos++;
    } else {
      pos--;
    }

    // Fehlerbehandlung
    if (pos > maxPoint) {
      pos = maxPoint;
      Serial.println(F("maxPosFail"));
    }

    if (pos < minPoint) {
      pos = minPoint;
      Serial.println(F("minPosFail"));
    }
    myservo.write(pos);  // Servo setzen
  }
}
long ultra() {
  digitalWrite(triggerPin, LOW);
  delayMicroseconds(4);
  digitalWrite(triggerPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(triggerPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  return duration / 60;
}

Das einzige was mich jetzt noch wirklich nervt, ist der Servo. Der geht zu langsam. Könnte man den Code so umbauen, dass er bei 135°, 90° und 45° scannt?

Was heisst das?

Alles ganz entspannt :slight_smile: ich bin ja froh das du dir überhaupt die Zeit nimmst mir zu helfen :slight_smile: Also warte ich solange es eben dauert und währenddessen kann ich ja selber rum probieren

Muss ich mir Zeit nehmen - schaff ich jetzt nicht. Schau ich nach dem wecken drauf :slight_smile:

Alles ganz entspannt :slight_smile: ich bin ja froh das du dir überhaupt die Zeit nimmst mir zu helfen :slight_smile: Also warte ich solange es eben dauert und währenddessen kann ich ja selber rum probieren

Las Dir mal die Zeiten ausgeben, wann die Servoroutine aufgerufen wird:

void setServoGetDist()
{
  uint32_t myMillis = millis();

  if (myMillis - lastServoAction > 15)                          // Pause für Echounterdrückung
  {
    if (lastServoAction != 0)
    {
      Serial.print(F("timing: "));
      Serial.println(myMillis - lastServoAction);
    }

    lastServoAction = myMillis;
    constexpr uint8_t fieldTicks{ (maxPoint - minPoint) / 3 };  // (40) gleichmässig Bereiche über den gesamten Arbeitsbereich verteilen
    static uint32_t tempData = 0;
    uint16_t d = ultra();
    tempData += d;
    /*
      Serial.print(F("Dura: "));
      Serial.print(d);
      Serial.print(F("  Summe: "));
      Serial.println(tempData);
    */

    switch (pos)
    {
      case minPoint:    // (30) ganz links
        if (!richtung)  // kommt von rechts
        {
          cml = tempData / (fieldTicks - 1);
        }

        Serial.println(F("Servo links"));
        richtung = HIGH;  // Richtungsumkehr
        tempData = 0;
        break;

      case minPoint + fieldTicks:  // (30+40 = 70)Ende linke Ausleuchtung - Anfang Mitte
        if (richtung)              // Auf dem Weg nach rechts
        {
          cml = tempData / (fieldTicks - 1);
        }
        else      // auf dem Weg nach links
        {
          cm = tempData / (fieldTicks - 1);
        }

        Serial.println(F("tick 70"));
        tempData = 0;
        break;

      case maxPoint - fieldTicks:  // (150-40 = 110) Ende Mitte - Anfang rechte Ausleuchtung
        if (!richtung)             // Auf dem Weg nach links
        {
          cmr = tempData / (fieldTicks - 1);
        }
        else      // Auf dem Weg nach rechts
        {
          cm = tempData / (fieldTicks - 1);
        }

        Serial.println(F("110 tick"));
        tempData = 0;
        break;

      case maxPoint:  // (150) ganz rechts
        if (richtung)
        {
          cmr = tempData / (fieldTicks - 1);
        }

        Serial.println(F("Servo rechts"));
        richtung = LOW;
        tempData = 0;
        break;
    }

    if (richtung)
    {
      pos++;
    }
    else
    {
      pos--;
    }

    // Fehlerbehandlung
    if (pos > maxPoint)
    {
      pos = maxPoint;
      Serial.println(F("maxPosFail"));
    }

    if (pos < minPoint)
    {
      pos = minPoint;
      Serial.println(F("minPosFail"));
    }

    myservo.write(pos);  // Servo setzen
  }
}

Das sollte ungefähr an den 15 ms (+ maximal 2) dran sein.
Wenn nicht kommentiere im loop() einfach mal automatic() aus. Wenn es dann passt, liegt da irgendwo der Hund begraben.

Normalerweise müsstest Du in

135-45 = 90 ticks mit je 15ms einmal rum sein: 90*15 = 1350.

Wenn das so passt und zu langsam ist, kannst Du pos++ / pos-- ersetzen durch

    if (richtung)
    {
      pos+=5;
    }
    else
    {
      pos-=5;
    }
07:58:22.865 -> timing: 698
07:58:23.596 -> timing: 696
07:58:24.266 -> timing: 697
07:58:25.010 -> timing: 698
07:58:25.692 -> timing: 695
07:58:26.388 -> timing: 696
07:58:27.086 -> timing: 696
07:58:27.782 -> timing: 696
07:58:28.464 -> timing: 695
07:58:29.175 -> timing: 698
07:58:29.861 -> timing: 695
07:58:30.601 -> timing: 696
07:58:31.285 -> timing: 696
07:58:31.968 -> timing: 705
07:58:32.707 -> timing: 707
07:58:33.407 -> timing: 705
07:58:34.103 -> timing: 698
07:58:34.786 -> timing: 695
07:58:35.485 -> timing: 696
07:58:36.208 -> timing: 696
07:58:36.894 -> timing: 707
07:58:37.632 -> timing: 696
07:58:37.632 -> tick 70
07:58:38.334 -> timing: 697
07:58:39.016 -> timing: 695
07:58:39.692 -> timing: 696
07:58:40.425 -> timing: 697
07:58:41.121 -> timing: 695
07:58:41.817 -> timing: 696
07:58:42.489 -> timing: 697
07:58:43.226 -> timing: 697
07:58:43.922 -> timing: 695
07:58:44.618 -> timing: 696
07:58:45.287 -> timing: 696
07:58:46.011 -> timing: 696
07:58:46.685 -> timing: 695
07:58:47.400 -> timing: 696
07:58:48.097 -> timing: 696
07:58:48.782 -> timing: 695
07:58:49.481 -> timing: 697
07:58:50.214 -> timing: 695
07:58:50.897 -> timing: 696
07:58:51.608 -> timing: 696
07:58:52.277 -> timing: 695
07:58:53.000 -> timing: 696
07:58:53.675 -> timing: 695
07:58:54.410 -> timing: 697
07:58:55.073 -> timing: 695
07:58:55.807 -> timing: 695
07:58:56.502 -> timing: 697
07:58:57.204 -> timing: 695
07:58:57.869 -> timing: 696
07:58:58.614 -> timing: 696
07:58:58.614 -> 110 tick
07:58:59.293 -> timing: 696
07:58:59.966 -> timing: 695
07:59:00.705 -> timing: 696
07:59:01.404 -> timing: 696
07:59:02.098 -> timing: 695
07:59:02.779 -> timing: 696
07:59:03.462 -> timing: 696
07:59:04.200 -> timing: 696
07:59:04.901 -> timing: 695
07:59:05.582 -> timing: 697
07:59:06.276 -> timing: 696
07:59:06.957 -> timing: 695
07:59:07.676 -> timing: 697
07:59:08.377 -> timing: 695
07:59:09.055 -> timing: 696
07:59:09.785 -> timing: 696
07:59:10.482 -> timing: 696
07:59:11.180 -> timing: 695
07:59:11.894 -> timing: 699
07:59:12.594 -> timing: 696
07:59:13.274 -> timing: 695
07:59:13.970 -> timing: 696
07:59:14.670 -> timing: 696
07:59:15.350 -> timing: 696
07:59:16.081 -> timing: 695
07:59:16.778 -> timing: 696
07:59:17.447 -> timing: 696
07:59:18.188 -> timing: 695
07:59:18.886 -> timing: 706
07:59:19.585 -> timing: 695
07:59:19.585 -> Servo rechts
07:59:20.279 -> timing: 696
07:59:20.951 -> timing: 696
07:59:21.675 -> timing: 695
07:59:22.374 -> timing: 696
07:59:23.067 -> timing: 696
07:59:23.813 -> timing: 742

auskommertieren hat auch keine Veränderung gebracht.

Das ist 40mal soviel, wie Du vorgesehen hast ....
Also action() und ultra() auskommentieren und sehen, ob sich was ändert.
Dann erst ultra() wieder rein und wen die Zeiten dann noch passen muss action() untersucht werden, wo es klemmt.

Ok, dann mach das mit den Postionsänderungen wie in 17 angedacht.

Wenn Du die nochmal tauscht, bekommst Du die Laufzeit der Funktion auch ausgegeben.

void setServoGetDist()
{
  uint32_t myMillis = millis();

  if (myMillis - lastServoAction > 15)                          // Pause für Echounterdrückung
  {
    if (lastServoAction != 0)
    {
      Serial.print(F("timing: "));
      Serial.print(myMillis - lastServoAction);
    }

    lastServoAction = myMillis;
    constexpr uint8_t fieldTicks{ (maxPoint - minPoint) / 3 };  // (40) gleichmässig Bereiche über den gesamten Arbeitsbereich verteilen
    static uint32_t tempData = 0;
    uint16_t d = ultra();
    tempData += d;
    /*
      Serial.print(F("Dura: "));
      Serial.print(d);
      Serial.print(F("  Summe: "));
      Serial.println(tempData);
    */

    switch (pos)
    {
      case minPoint:    // (30) ganz links
        if (!richtung)  // kommt von rechts
        {
          cml = tempData / (fieldTicks - 1);
        }

        Serial.println(F("Servo links"));
        richtung = HIGH;  // Richtungsumkehr
        tempData = 0;
        break;

      case minPoint + fieldTicks:  // (30+40 = 70)Ende linke Ausleuchtung - Anfang Mitte
        if (richtung)              // Auf dem Weg nach rechts
        {
          cml = tempData / (fieldTicks - 1);
        }
        else      // auf dem Weg nach links
        {
          cm = tempData / (fieldTicks - 1);
        }

        Serial.println(F("tick 70"));
        tempData = 0;
        break;

      case maxPoint - fieldTicks:  // (150-40 = 110) Ende Mitte - Anfang rechte Ausleuchtung
        if (!richtung)             // Auf dem Weg nach links
        {
          cmr = tempData / (fieldTicks - 1);
        }
        else      // Auf dem Weg nach rechts
        {
          cm = tempData / (fieldTicks - 1);
        }

        Serial.println(F("110 tick"));
        tempData = 0;
        break;

      case maxPoint:  // (150) ganz rechts
        if (richtung)
        {
          cmr = tempData / (fieldTicks - 1);
        }

        Serial.println(F("Servo rechts"));
        richtung = LOW;
        tempData = 0;
        break;
    }

    if (richtung)
    {
      pos += 5;
    }
    else
    {
      pos -= 5;
    }

    // Fehlerbehandlung
    if (pos > maxPoint)
    {
      pos = maxPoint;
      Serial.println(F("maxPosFail"));
    }

    if (pos < minPoint)
    {
      pos = minPoint;
      Serial.println(F("minPosFail"));
    }

    myservo.write(pos);  // Servo setzen
    Serial.print(F("endFunc: "));
    Serial.println(millis() - lastServoAction);
  }
}