Automatischer Abstandhalter Auto

Hi Leute,
wie bereits in einem Beitrag erwähnt will ich mir eine Art Auto bauen, welches ungefähr Schuhkarton groß ist und welches eine vorgegebene Route fahren soll.
Hierbei habe ich an dieses "Auto" mehrere Buttons gebaut, sodass wenn etwas in den Weg kommt, dass das der Button auslöst und das Auto dieses Hindernis umfährt.
Hierbei habe ich ein Code (hier z.b. bei der festen Route vereinfacht dargestellt) geschrieben:

const int buttonPin3 = A3;     // hinten
const int buttonPin4 = A4;     // links
const int buttonPin2 = A2;     // vorne
const int buttonPin1 = A1;     // rechts
 
// variables will change:
int buttonState1 = 0;  
int buttonState2 = 0;  
int buttonState3 = 0;  
int buttonState4 = 0;  

int in1 = 6;
int in2 = 5;
int in3 = 2;
int in4 = 3;

enum CarState {
  FixedProgram,
  AvoidanceProgram
};

CarState currentState = FixedProgram;

void setup() {
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);  
  pinMode(buttonPin3, INPUT);  
  pinMode(buttonPin4, INPUT);    

  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
}

void loop() {
  // Abstandhalter
  buttonState1 = digitalRead(buttonPin1);
  buttonState2 = digitalRead(buttonPin2);
  buttonState3 = digitalRead(buttonPin3);
  buttonState4 = digitalRead(buttonPin4);

  if (buttonState3 == HIGH && currentState == FixedProgram) {
    currentState = AvoidanceProgram; // Wechsle zum Ausweichprogramm
  }

  switch (currentState) {
    case FixedProgram:
         digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);

  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);

  delay(5000); 
      digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);

  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);

  delay(1000);

      break;

    case AvoidanceProgram:
      // Hier führst du das Ausweichprogramm aus
       digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);

  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);

  delay(1000);



//Drehen
      digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);

  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);

  delay(500);
 //Drehen
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);

  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
delay(1000);
      currentState = FixedProgram; // Wechsle zurück zum festen Programm
      break;
  }
}

Das Problem dabei ist, dass das Auto die vorgegebene Route fährt, aber wenn der Button auslöst nicht das Ausweichprogramm fährt, sondern einfach weiterfährt. Wenn aber der Button genau am Ende des festen Programmes drückt, dass fährt das Auto das Ausweichprogramm.

Woran liegt das und wie kann ich Abhilfe schaffen, dass das Auto immer das Ausweichprogramm durchführt und nicht nur am Ende des festen Programms (Route) ?

Über eine Antwort würde ich mich sehr freuen.

LG

This section is English language.

Already moved

Hi guys,
as already mentioned in a post I want to build a kind of car, which is about the size of a shoebox and which should drive a predefined route.
Here I have built several buttons on this "car", so that if something comes in the way, that the button triggers and the car drives around this obstacle.
Here I have written a code (here for example with the fixed route simplified represented):

const int buttonPin3 = A3;     // back
const int buttonPin4 = A4;     // left
const int buttonPin2 = A2;     // front
const int buttonPin1 = A1;     // right
 
// variables will change:
int buttonState1 = 0;  
int buttonState2 = 0;  
int buttonState3 = 0;  
int buttonState4 = 0;  

int in1 = 6;
int in2 = 5;
int in3 = 2;
int in4 = 3;

enum CarState {
  FixedProgram,
  AvoidanceProgram
};

CarState currentState = FixedProgram;

void setup() {
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);  
  pinMode(buttonPin3, INPUT);  
  pinMode(buttonPin4, INPUT);    

  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
}

void loop() {
  // Abstandhalter
  buttonState1 = digitalRead(buttonPin1);
  buttonState2 = digitalRead(buttonPin2);
  buttonState3 = digitalRead(buttonPin3);
  buttonState4 = digitalRead(buttonPin4);

  if (buttonState3 == HIGH && currentState == FixedProgram) {
    currentState = AvoidanceProgram; // Switch to the alternate program
  }

  switch (currentState) {
    case FixedProgram:
         digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);

  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);

  delay(5000); 
      digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);

  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);

  delay(1000);

      break;

    case AvoidanceProgram:
   
       digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);

  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);

  delay(1000);



//Drehen
      digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);

  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);

  delay(500);
 //Drehen
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);

  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
delay(1000);
      currentState = FixedProgram; //Switch back to the fixed program
      break;
  }
}

The problem is that the car drives the predefined route, but when the button is triggered, it does not drive the avoidance program, but simply continues driving. But if the button is pressed exactly at the end of the fixed program, the car drives the avoidance program.

What is the reason for this and how can I remedy the situation so that the car always runs the avoidance program and not only at the end of the fixed program (route) ?

I would be very happy about an answer.

Best regards

Hallo tom929

Hier kommt meine Antwort.

Die im Sketch verwendeten delay()´s stören das erwartete Echtzeit verhalten.

Die benötigten "Verzögerungen" können mit Timer-Funktionen, basierend auf dem BlinkWithOutDelay Beispiel aus dem IDE, realisiert werden.

Ich wünsche einen geschmeidigen Tag und viel Spass beim Programmieren in C++.

@paulpaulson hat dir schon geschrieben wo hapert, hier auf Deutsch :wink:

Kurzfassung: Du wirst früher oder später noch an ganz andere Grenzen stoßen.

Aber hier mal ein Ansatz:

const byte buttonPin3 = A3;     // back
const byte buttonPin4 = A4;     // left
const byte buttonPin2 = A2;     // front
const byte buttonPin1 = A1;     // right

// variables will change:
bool buttonState1 = false;
bool buttonState2 = false;
bool buttonState3 = false;
bool buttonState4 = false;

const byte out1 = 6;
const byte out2 = 5;
const byte out3 = 2;
const byte out4 = 3;



enum CarState
{
  FixedProgram,
  AvoidanceProgram
};

CarState currentState = FixedProgram;

enum {fixedOne, fixedTwo, fixedThree, fixedFour};
byte fixedStatus = fixedOne;

uint32_t startTime;

void setup()
{
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  pinMode(buttonPin4, INPUT);
  pinMode(out1, OUTPUT);
  pinMode(out2, OUTPUT);
  pinMode(out3, OUTPUT);
  pinMode(out4, OUTPUT);
}

void loop()
{
  // Abstandhalter
  buttonState1 = digitalRead(buttonPin1);
  buttonState2 = digitalRead(buttonPin2);
  buttonState3 = digitalRead(buttonPin3);
  buttonState4 = digitalRead(buttonPin4);
  if (buttonState3 == HIGH && currentState == FixedProgram)
  {
    currentState = AvoidanceProgram; // Switch to the alternate program
  }
  switch (currentState)
  {
    case FixedProgram:
      switch (fixedStatus)
      {
        case fixedOne:
          moveOne();
          startTime = millis();
          fixedStatus = fixedTwo;
          break;
        case fixedTwo:
          if (millis() - startTime >= 5000)
          {
            fixedStatus = fixedThree;
          }
          break;
        case fixedThree:
          moveStop();
          startTime = millis();
          fixedStatus = fixedFour;
          break;
        case fixedFour:
          if (millis() - startTime >= 1000)
          {
            fixedStatus = fixedOne;
          }
          break;
      }
      break;
    case AvoidanceProgram:
      moveTwo();
      delay(1000);
      //Drehen
      moveOne();
      delay(500);
      //Drehen
      moveThree();
      delay(1000);
      currentState = FixedProgram; //Switch back to the fixed program
      break;
  }
}

void moveOne()
{
  digitalWrite(out1, HIGH);
  digitalWrite(out2, LOW);
  digitalWrite(out3, HIGH);
  digitalWrite(out4, LOW);
}

void moveTwo()
{
  digitalWrite(out1, LOW);
  digitalWrite(out2, HIGH);
  digitalWrite(out3, LOW);
  digitalWrite(out4, HIGH);
}

void moveThree()
{
  digitalWrite(out1, HIGH);
  digitalWrite(out2, LOW);
  digitalWrite(out3, LOW);
  digitalWrite(out4, HIGH);
}

void moveStop()
{
  digitalWrite(out1, LOW);
  digitalWrite(out2, LOW);
  digitalWrite(out3, LOW);
  digitalWrite(out4, LOW);
}

Es macht nicht alles, aber zumindest wird während der fixed-Fahrt der Button abgerufen, egal wo Du bist.
Das kann aber zum Problem werden, wenn der button gedrückt und Du in die Pause gehst.
Für "optimale" Ergebnisse müsstest Du die Zeit der Umfahrung nämlich mitrechnen.....

Warum hast Du Deinen Beitrag wieder gelöscht?
Ich würd Dir ja helfen, müsste aber wissen wo die Reise hin geht.

Sorry, ich habe eine Frage bezüglich der Millis gestellt, die sich aber mittlerweile erledigt hat.
Vielen Dank nochmal für deine schnelle und ausführliche Antwort und dein großzügiges Angebot weiterhin zu helfen.
Ich habe tatsächlich noch eine Frage, da du erwähntest, dass für das optimale Ergebnis die Zeit der Umfahrung mitgerechnet werden muss. Wie wäre das realisierbar?

Es gibt mehrere Ansätze.
Der erste wäre

  • zu prüfen ob Du zum Zeitpunkt des auslösens eines Tasters im Zustand einer Pause bist und dann die bisher abgelaufene Zeit merken.
  • Den Umsetzprozessdurchlaufen und am Ende die aktuuel Zeit der Pause auf den Stand zu bringen, der beim auslösen vorhanden war. Das heisst, die Auslösezeit müsste dann millis()-bisherabgelaufeneZeit werden.
    Ablauf:
    Pausestart=millis() -> eigentlich steht das Fahrzeug, aber.... irgendwann wird ein Taster ausgelöst ausgelöst. Warum ist erstmal egal.
    Damit ist die abgelaufeneZeit=millis()-Pausestart -> die wird gemerkt
    Jetzt wird das Fahrzeug umgesetzt
    Nach dem Umsetzen wäre die Zeit aber weiter gelaufen. also muss Sie zurückgestellt werden.
    -> neuer Pausesstart=millis()-abgelaufeneZeit
    Du bist jetzt also genau an dem Zeitpunkt, wie vor dem Umsetzen.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.