Programmcode für ein autonomes Auto, welches nur vor- und rückwärts fahren soll

Hi Leute,

Zurzeit müssen wir in der Schule ein Projekt erstellen, indem wir ein autonomes Auto bauen, welches nur nach vorne und hinten fahren soll. Zur Verfügung steht mir dabei:

  • 1x Ultraschallsensor (man kann auch 2 benutzen)
  • 1x Piezo
  • 1x oder auch mehrere LEDs
  • 1x Gleichstrommotor (12V)
  • und optional kann man auch noch weitere Dinge benutzen.

Mein Problem lautet jetzt, dass der Piezo am Anfang kurz einen Ton von sich gibt und sich der Gleichstrommotor kurz nach hinten dreht, obwohl das eigentlich gar nicht passieren soll. Dies dauert nicht lange an, geschätzt 0,5 Sekunden, dennoch stört es mich und das soll nicht beim Starten des Autos passieren.
Ebenfalls soll das Auto, wenn es vor sich eine Wand oder sonstiges erkennt, nach hinten fahren. Dieses "nach hinten fahren", soll dann konstant bleiben und nicht, wenn der Sensor wieder einen größeren Abstand zur Wand erkennt, wieder nach vorne fahren. In dem Fall ist es egal ob das Auto hinten gegen eine Wand oder sonstiges knallt/stößt.
Nebenbei soll das Auto beim Fahren nach hinten eine Art Piepston von sich geben. Dies hat aber in meinem Fall sehr gut mit dem Piezo geklappt.

Vielen vielen Dank schonmal im Voraus. Ich hoffe jemand kann mir weiterhelfen.

Mit freundlichen Grüßen :wink:

int trigger = 7;     //erstellt eine Variable mit dem Namen "trigger", welcher den Wert 7 erhält (= 7 steht für den Pin an dem der Trigger des Ultraschallsensors angeschlossen wird)
int echo = 6;        //erstellt eine Variable mit dem Namen "echo", welcher den Wert 6 erhält (= 6 steht für den Pin an dem das Echo des Ultraschallsensors angeschlossen wird)
long dauer = 0;      //erstellt eine Ganzzahlkonstant-Variable mit dem Namen "dauer" und dem Anfangswert 0
long entfernung = 0; //erstellt eine Ganzzahlkonstant-Variable mit dem Namen "entfernung" und dem Anfangswert 0

int piezo = 5; //erstellt eine Variable mit dem Namen "piezo", welcher den Wert 5 erhält (= 5 steht für den Pin an dem der Piezo angeschlossen wird)
int led = 4;   //erstellt eine Variable mit dem Namen "led", welcher den Wert 4 erhält (= 4 steht für den Pin an dem die LED angeschlossen wird)

int motorPin1 = 10;         //erstellt eine Variable mit dem Namen "motorPin1", welcher den Wert 10 erhält (= 10 steht für den Pin an dem der Minuspol des Motors angeschlossen wird)
int motorPin2 = 11;         //erstellt eine Variable mit dem Namen "motorPin2", welcher den Wert 11 erhält (= 11 steht für den Pin an dem der Pluspol des Motors angeschlossen wird)
int geschwindigkeit1 = 175;  //erstellt eine Variable mit dem Namen "geschwindigkeit1", welcher den Wert 175 erhält (= 175 steht für die Geschwindkeit mit dem der Motor nach vorne läuft)
int geschwindigkeit2 = 140; //erstellt eine Variable mit dem Namen "geschwindigkeit2", welcher den Wert 140 erhält (= 140 steht für die Geschwindkeit mit dem der Motor nach hinten läuft)

void piepen() {     //mithilfe eines weiteren void-Befehls wird ein neuer Befehl mit dem Namen "piepsen" erstellt
  tone(piezo, 988); //der Piezo soll den Ton h'' (988 = h'') abspielen
  delay(400);       //dieser Ton soll 0,4 Sekunden abgespielt werden
  noTone(piezo);    //nach der Verzögerung soll der Piezo keinen Ton ausgeben
  delay(800);       //es soll für 0,8 Sekunden kein Ton mehr ausgegeben werden
}

void setup() {
  pinMode(trigger, OUTPUT);
  pinMode(echo, INPUT);
  pinMode(piezo, OUTPUT);
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(led, OUTPUT);
  digitalWrite(led, HIGH);
  Serial.begin(9600);
}

void loop() {
  digitalWrite(trigger, LOW);
  delayMicroseconds(10);
  digitalWrite(trigger, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigger, LOW);
  dauer = pulseIn(echo, HIGH);
  entfernung = (dauer / 2) * 0.03432;
  Serial.println(entfernung);

  if (entfernung >= 15) {
    analogWrite(motorPin1, 0);
    analogWrite(motorPin2, geschwindigkeit1);
  }

  if (entfernung <= 15) {
    analogWrite(motorPin1, geschwindigkeit2);
    analogWrite(motorPin2, 0);
    piepen();
  }

}
const byte trigger = 7;     //erstellt eine Konstante mit dem Namen "trigger", welcher den Wert 7 erhält (= 7 steht für den Pin an dem der Trigger des Ultraschallsensors angeschlossen wird)
const byte echo = 6;        //erstellt eine Konstante mit dem Namen "echo", welcher den Wert 6 erhält (= 6 steht für den Pin an dem das Echo des Ultraschallsensors angeschlossen wird)
unsigned long entfernung = 0; //erstellt eine Ganzzahl-Variable mit dem Namen "entfernung" und dem Anfangswert 0

const byte piezo = 5; //erstellt eine Konstante mit dem Namen "piezo", welcher den Wert 5 erhält (= 5 steht für den Pin an dem der Piezo angeschlossen wird)
const byte led = 4;   //erstellt eine Konstante mit dem Namen "led", welcher den Wert 4 erhält (= 4 steht für den Pin an dem die LED angeschlossen wird)

const byte motorPin1 = 10;         //erstellt eine Konstante mit dem Namen "motorPin1", welcher den Wert 10 erhält (= 10 steht für den Pin an dem der Minuspol des Motors angeschlossen wird)
const byte motorPin2 = 11;         //erstellt eine Konstante mit dem Namen "motorPin2", welcher den Wert 11 erhält (= 11 steht für den Pin an dem der Pluspol des Motors angeschlossen wird)
const byte geschwindigkeit1 = 175; //erstellt eine Konstante mit dem Namen "geschwindigkeit1", welcher den Wert 175 erhält (= 175 steht für die Geschwindkeit mit dem der Motor nach vorne läuft)
const byte geschwindigkeit2 = 140; //erstellt eine Konstante mit dem Namen "geschwindigkeit2", welcher den Wert 140 erhält (= 140 steht für die Geschwindkeit mit dem der Motor nach hinten läuft)

void piepen() {     //mithilfe eines weiteren void-Befehls wird ein neuer Befehl mit dem Namen "piepsen" erstellt
  while (true) {
    tone(piezo, 988); //der Piezo soll den Ton h'' (988 = h'') abspielen
    delay(400);       //dieser Ton soll 0,4 Sekunden abgespielt werden
    noTone(piezo);    //nach der Verzögerung soll der Piezo keinen Ton ausgeben
    delay(800);       //es soll für 0,8 Sekunden kein Ton mehr ausgegeben werden
  }
}

void setup() {
  pinMode(trigger, OUTPUT);
  pinMode(echo, INPUT);
  pinMode(piezo, OUTPUT);
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(led, OUTPUT);
  digitalWrite(led, HIGH);
  Serial.begin(9600);
}

void loop() {
  digitalWrite(trigger, LOW);
  delayMicroseconds(10);
  digitalWrite(trigger, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigger, LOW);
  entfernung = (pulseIn(echo, HIGH) * 17) / 1000;
  Serial.println(entfernung);

  if (entfernung >= 15) {
    analogWrite(motorPin1, 0);
    analogWrite(motorPin2, geschwindigkeit1);
  } else {
    analogWrite(motorPin1, geschwindigkeit2);
    analogWrite(motorPin2, 0);
    piepen();
  }
}

Setze den Piezo im setup() auf noTone und den Motor auf "aus", damit diese nicht läuft.

1 Like

Die ENABLE Leitung des Treibers mit einem Widerstand auf "inaktiv" stellen.

Die Aufgabe sollte schon etwas ausführlicher beschrieben sein. Soll das Auto nach dem Starten losfahren oder soll es warten, bis sich von vorne ein Hindernis nähert? usw...

IMO ist es unsinnig, das Auto unkontrolliert nach hinten wegfahren zu lassen und Schäden am Fahrzeug und Umgebung zu riskieren. Und wenn man das Auto wieder eingefangen hat, wie soll man es dann abschalten?

Ihr solltet euren Lehrer mit solchen praktischen Fragen löchern, bis die Aufgabenstellung wirklich allen klar ist. Ein Programmierer muß sich immer fragen, was in welchem Betriebszustand passieren kann und wie darauf reagiert werden soll. Wenn das nicht ausreichend beschrieben ist, dann ist die Aufgabenstellung unvollständig, für euch in der Schule und vor allem für das Forum.

Die Beschreibung der Motorpins ist gaaaanz schlecht lesbar und IMO falsch. Oder wollt ihr den Motor wirklich ohne Treiber vom Arduino powern lassen? In der Stückliste steht jedenfalls keiner drin.

Das Auto soll direkt nach dem Start losfahren können. Dieser Start wird per umschalten eines Schalters angesteuert. Dabei ist es egal ob es zuerst nach hinten oder nach vorne fährt. Dazu hat mein Lehrer uns gesagt, dass es am Anfang des Starts sehr wahrscheinlich zuerst nach vorne fahren soll, da wir das Auto sozusagen beim Testen in die Mitte des Raums stellen und es somit genügend Abstand zur vorderen Wand hat.

Diesen Punkt habe ich leider auch nicht ganz verstanden. Damals sagte der Lehrer zu mir jedenfalls: "Ja das Auto soll nur nach vorne fahren und wenn es eine Wand vor sich erkennt, soll es nach hinten fahren können. Egal ob es dann gegen eine Wand knallt oder nicht." Jedenfalls haben wir gerade Ferien und ich kann Ihn nicht kontaktieren, aber ich frage Ihn auf jeden Fall nach den Ferien nochmal nach. Das Auto soll dann wieder mit den Händen "aufgefangen" werden und per umschalten des Schalters wieder ausgeschaltet werden. Ach ja und insgesamt soll das System mit einer 9V-Batterie betrieben werden.

Wie gesagt wir können noch weitere Bauteile, wie einen Treiber, benutzen, aber das steht uns frei und wir wurden darüber kaum informiert, was wir zum Beispiel noch benutzen könnten. Aber im Großen und Ganzen lautet die Antwort: Ja, das Auto soll nur über einen einzigen Motor angetrieben werden, da wir daran noch 3D gedruckte Zahnräder dran machen müssen und mithilfe dieser Zahnräder eine (oder auch beide) Achsen des Autos antreiben müssen. Dabei muss dann das Übersetzungsverhältnis des Motors zu den Zahnräder und den Achsen passen, usw...

Aber vielen Dank für deine Rückmeldung DrDiettrich, ich werde mir das auf jeden Fall nochmal genau angucken und alles mit meinem Lehrer besprechen.

Hi Kolaha,

vielen Dank erstmal für Ihre Rückmeldung. Der Code hat super geklappt, genauso wie ich es mir für den Anfang vorgestellt hatte. Ich hätte nur eine Frage zur einer Zeile des Codes. Ich bin noch nicht so erfahren mit dem "Codeschreiben" beim Arduino. Könnten Sie mir bitte einen kleinen Kommentar zum besseren Verständnis hinzufügen. Beispielsweise verstehe ich nicht ganz, warum Sie *17 eingefügt haben und dann geteilt durch 1000 rechnen.
Ach ja und ebenfalls, was genau der Befehl "const byte" macht.?
Danke schonmal im Voraus.
(Die Zeile ist hier unten eingeblendet)
|
|

const will dir "read only" sagen.
Und byte (unsigned char oder uint8_t) ist ein Datentype.
Erklärungen findest du in jedem C++ Grundlagenbuch.


Ich würde sogar noch weiter gehen!


constexpr byte echo  {6};

Ok, vielen Dank. Ich werde mir nochmal zur Sicherheit die genauere Erklärung angucken.
Und danke für den weiteren Tipp.

Dafür sollte es ja nicht besonders schnell fahren.

So eine kleine Batterie und dann ein 12V Motor? Das kann ja nix werden :frowning:

Ja genau es soll relativ langsam fahren, leider...
Und ja nur eine einzige 9V-Batterie nicht mehr, nicht weniger.
Ich weiß selbst nicht ganz, wie man das insgesamt umsetzten soll. Naja ich versuch's einfach mal weiter und frag den Lehrer, wie gesagt, nochmal alles nach.

Wenn die Eingangsvariable vom Datentyp unsigned long ist und das Ergebnis auch, sollte man auch die Berechnung in diesen Datentypen lassen, zumindest wenn der Controller gar keine Hardware für Gleitkommaberechnungen hat.
Und wenn das Ergebnis nur für die Abfrage (entfernung < 15) verwendet wird, ist es sinnlos, das ganze mit 4 Stellen Auflösung (* 0.03432) zu rechnen.

Wenn das Auto sich später mal in echt vor und zurück bewegen wird, und die Entfernung davon abhängen wird, muss an der Steuerung noch ein wenig optimiert werden, damit das Ding nicht dauernd vor und zurück fährt... Viel Spaß!

Achso ok, habs jetzt auf jeden Fall verstanden. Vielen Dank

es ist schon teilweise erklärt.
die Formel ersetzt float Berechnungen die wegen 0.0343 entstehen,

изображение

so DAUER *0.0343 / 2 =
= DAUER * 343 / 2 /10000=
= DAUER * 171 /10000=
= DAUER * 17 /1000

Achso, das heißt du hast einfach nur die Zahlenwerte geändert, wobei dann das gleiche herauskommt. Danke dir jetzt weiß ich darüber Bescheid

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