Schlauer Roboter mit Arduino: Unterschied zwischen den Versionen
Zeile 486: | Zeile 486: | ||
== YouTube Video == | == YouTube Video == | ||
== Weblinks == | == Weblinks == |
Version vom 20. Januar 2021, 19:40 Uhr
Autoren: Ibrahim El-Jaber Nsangou Pekariekouo, Franck Bakofa Njanpouop

Gruppe: 2.3
Betreuer: Prof. Schneider
→ zurück zur Übersicht: WS 20/21: Fachpraktikum Elektrotechnik (MTR)
Einleitung
Im Rahmen des GET-Fachpraktikums sollen Studenten ein Mechatronisches Projekt erstellen und durchführen. Wir haben uns dafür entschieden, ein Hindernis vermeidenden Roboter zu bauen und mit Hilfe von Arduino programmiert werden. Ziel unseres Projekts ist es einen Roboter zu bauen, der eine schwarze oder weiße Linie verfolgen und gleichzeitig Hindernisse auf seinen Weg, wenn es gibt, vermeiden kann.
Anforderungen
Um den Erfolg unseres Projekts zu gewährleisten, müssen die unter genannte Anforderungen erfüllen werden:
- Mini Auto Design mit 4 Reifen und 4 Getriebemotoren.
- System mit einem Schalter ein-/ausschalten.
- Der Roboter soll mit Hilfe Infrarot-Liniensensor entlang einer Linie fahren können.
- Der Roboter soll in der Lage sein, Hindernisse mit Hilfe Ultraschalsensoren zu erkennen.
- Der Roboter soll Hindernisse auf seinen Weg ausweichen können.
- Anzeige der Status auf einem integrierten Display (I2C LCD).
Funktionaler Systementwurf/Technischer Systementwurf
Der IR-Sensor besteht aus einer Infrarot LED und einem nebeneinander angeordneten Fototransistor.Die LED wirkt wie ein Sender und der Fototransistor wie ein Empfänger. Die Infrarot-LED sendet Infrarotlicht aus, d.h. Licht, das eine längere Wellenlänge (oder niedrigere Frequenz) hat und für das menschliche Auge unsichtbar ist. Trifft dieses Licht auf eine weiße Fläche, wird es reflektiert und prallt auf den Fototransistor,dann leuchtet eine LED. Trifft es dagegen auf eine schwarze Oberfläche, absorbiert das Material den größten Teil des Lichts und erreicht nicht den Fototransistor.Wir haben diese besondere Eigenschaft der IR-Sensor benutzt,damit unserer Roboter eine "schwarze/weiße" Linie folgen kann.

Damit unser Roboter die schwarze Linie folgt, haben wir einen 3-Kanal Line-tracking Infrarotsensor verwendet. Mit 3 Kanäle hat man 2^3 = 8 mögliche Zustände. Wenn der erste Kanal auf Schwarze Linie und die beide andere auf weiße Linie, dann liefert der Sensor '1' für die schwarze Linie und '0' für die weiße Linie, so bekommt man für dieses Beispiel ein Binärzahl von 100 und ergibt 4 in Dezimalzahl. Also die Arbeitsprinzipien sind wie folgende:
- Der Sensor erkennt die schwarze/ weiße Linie oder nicht und gib das Ergebnis als Binärzahl.
- Mithilfe eine Funktion wird diese Binärzahl in Dezimalzahl umgewandelt.
- Eine Variable "Sensorwert" bekommt die Dezimahlzahl und eine der acht Aktion wird ausgeführt.

.
Die Ultraschallsensoren als Abstandssensoren sind in der Lage, Objekte berührungslos zu erkennen und ihre Entfernung zum Sensor zu messen.Der Sensorkopf sendet dabei eine Ultraschallwelle aus und empfängt die vom Ziel reflektierte Welle. Ultraschallsensoren messen die Entfernung zum Ziel durch Messen der Zeit zwischen Aussendung und Empfang. Die Zeit, die das Echo benötigt, um den Sensor zu erreichen, wird bestimmt und wird zur Berechnung des Abstands verwendet, da die Schallgeschwindigkeit in Luft eine bekannte Konstante ist (343 m/s).
Die linke Abbildung erläutert die Vorgehensweisen,um Hindernisse auszuweichen.
Arbeitsprinzipien sind wie folgende:
- Der Ultraschallsensor misst den Mittenabstand "Entfernung[1]". Wenn er kleiner gleich einen vorgegebenen Abstand ist,Der Roboter stoppt.
- Mithile eines Servomoteurs dreht sich den Ultraschallsensor nach links und recht und misst dabei den rechten (Entfernung[2]) und linken Abstand (Entfernung[0]).
- Zum Schluss werden die Abstände verglichen.
Komponentenspezifikation

Hier zusammengefasst sieht man die Verbindung der Komponente mit dem Arduino Board. Die Verdrahtung des Roboters wurde mit dem Tool Fritzing gemacht.
Komponententest

void loop() { digitalWrite(Trigger,LOW); delay(5); digitalWrite(Trigger,HIGH); delay(10); digitalWrite(Trigger,LOW); Dauer = pulseIn(Echo,HIGH); Entfernung = (Dauer/2)*0.03432; Serial.print(Entfernung); Serial.println("cm"); delay(1000); }
Umsetzung (HW/SW)
Hardware
Die vier DC Motors werden an dem L298N Motor Driver angeschlossen,dadurch angesteurt und mit dem Arduino Uno Board verbunden.Am Rand des Boards befinden sich viele Steckplätze(Pins genannt), an denen man die unterschiedlichsten Module wie Sensoren und Aktoen anschließen kann.
Software
In unseren Projekt haben wir The The open-source Arduino Software (IDE) verwendet. Es besteht aus drei wesentlichen Teile:
Teile 1 : Variablen benennen
Teile 2 : Setup
Teile 3 : Loop
Variablen benennen
im ersten Teil werden Elemente des Programmms benannt.Zum Beispiel werden dort Variablen festgelegt oder sog.Programmmbibliotheken geladen.Dieser Teil ist nicht für jeden Sketch zwing erforderlich.
/*"Schlauer Robot mit Arduino" Autoren: Ibrahim EL-Jaber and Franck. Betreuer: Prof. Ebmeyer.*/ #include "Freenove_WS2812B_RGBLED_Controller.h" // Bibliothek für GRB Controller #define I2C_ADDRESS 0x20 #define LEDS_COUNT 10 #include<Wire.h> #include<LiquidCrystal_I2C.h> // Bibliothek für LCD Display. // Variablen. Freenove_WS2812B_Controller Farbe(I2C_ADDRESS, LEDS_COUNT, TYPE_GRB); LiquidCrystal_I2C lcd(0x27, 16, 2); // Hier wird festgelegt, um was für einen Display es sich handelt. // In diesem Fall eines mit 16 Zeichen in 2 Zeilen und der Hex-Adresse 0*27. // Verbindung der Pins. #define ServoMotor 10 // ServoMotor wird mit dem Pin 10 verbunden. // Ultraschalsensor #define Trigger_Pin 8 #define Echo_Pin 9 # define Max_Distance 200 //NewPing Sonar(Trigger_Pin, Echo_Pin, Max_Distance); long Distance = 0; long Dauer = 0; // Tacking Sensor #define SensorPinLeft A0 #define SensorPinCenter A1 #define SensorPinRight A2 // Motors const int MotorA1 = 2; const int MotorA2 = 3; const int MotorB1 = 4; const int MotorB2 = 5; // Speed of the two Motors. Vitesse des deux moteurs. // Bereich für die Geschwindigkeit [0;255] int MotorAS = 6; int MotorBS = 11; int SpeedMA = 0; int SpeedMB = 0; // Buzzer int Piepton = 13;
Setup
Der zweite Teil wird Setup genannt.Es wird vom Board nir einmal ausgeführt und ist zwingend erforderlich für jeden Sketch,selbst wenn in diesem Bereich keine EInträge erfolgen. Im Setup wird bspw.festgelegt,welcher Pin (Steckplatz für Kabel) am Mikrocontrollerboard ein Ausgang oder ein Eingang ist. Definiert als Ausgang, kann an dem jeweiligen Pin eine Spannung ausgegeben werden und definiert als Eingang kann an dem Pin eine Spannung eingelesen werden.
void setup() {
//initialisierung. // lcd lcd.init(); lcd.init(); lcd.backlight(); lcd.setCursor(0,0); lcdprint("Schlauer Roboter"); lcd.setCursor(4,1); lcdprint("mit Arduino"); delay(1100); // Servo pinMode(ServoMotor, OUTPUT); // Servo als OUTPUT deklarieren. // Anfanswinkel. for (int angle = 70; angle <= 140; angle += 5) { servoPulse(ServoMotor, angle); } for (int angle = 140; angle >= 0; angle -= 5) { servoPulse(ServoMotor, angle); } for (int angle = 0; angle <= 70; angle += 5) { servoPulse(ServoMotor, angle); } delay(500);
// Motors // Alle Motors als OUTPUT deklarieren. pinMode(MotorA1, OUTPUT); pinMode(MotorA2, OUTPUT); pinMode(MotorB1, OUTPUT); pinMode(MotorB2, OUTPUT); pinMode(MotorAS, OUTPUT); pinMode(MotorBS, OUTPUT);
// RGB Controller. while (!Farbe.begin()); // if initialization success. Farbe.setAllLedsColor(0x00FF00); // Alle LED haben die grüne Farbe. delay(1000); Farbe.setAllLedsColor(0xFF0000); // Alle LED haben die rote Farbe delay(1000); Farbe.setAllLedsColor(255, 255, 0); // Alle LED haben die gelbe Farbe. delay(1000); Farbe.setAllLedsColor(0, 0, 0); // Licht ausmachen. delay(1000);
// Tracking Sensor. pinMode(SensorPinLeft, INPUT); pinMode(SensorPinCenter, INPUT); pinMode(SensorPinRight, INPUT);
// Ultraschalsensor. pinMode(Trigger_Pin, OUTPUT); pinMode(Echo_Pin, INPUT); Distance = ReadPing();
}
Loop
Der Bereich Loop wird vom Board kontinuierlich wiederholt und kann daher auch als Hauptteil des Sketches bezeichnet werden.Der Mikrocontroller verarbeit den Sketch einmal komplet bis zum Ende und beginnt dann erneut am Anfang des Loop-Abschnitts.
long LeftDistance = 0; long RightDistance = 0; Distance = ReadPing(); if (Distance <= 25) { // Ton, damit das Hindernis den Weg freigibt.Wenn ja, macht den Roboter weiter sonst vermiedet er das Hindernis. tone(13, 100);MoveStop(); Farbe.setAllLedsColor(0xFF0000); // Alle LED haben die rote Farbe delay(1000); noTone(13); tone(13, 200); delay(1000); noTone(13); LeftDistance = LookLeft(); delay(200); RightDistance = LookRight();delay(200); Farbe.setAllLedsColor(0, 0, 0); // Alle LED sind aus.
if ((Distance < LeftDistance) && (LeftDistance > RightDistance)) // Bedingung, um nach links zu fahren. { TurnLeft(); delay(400); MoveForward(); delay(500); TurnRight(); delay(350); MoveForward(); delay(700); TurnRight(); delay(500); MoveForward(); delay(400); //TurnLeft(); //delay(400); } if ((RightDistance > Distance) && (RightDistance > LeftDistance)) // Bedingung, um nach recht zu fahren. { TurnRight(); delay(400); MoveForward(); delay(500); TurnLeft(); delay(350); MoveForward(); delay(700); TurnLeft(); delay(500); MoveForward(); delay(400); /*TurnLeft(); delay(350); MoveForward();delay(400);*/ } } else { int Sensorwert = 0; Sensorwert = LeseSensor(); switch (Sensorwert) { /*case 0: MoveForward(); Farbe.setAllLedsColor(255, 255, 255); // weiß break;*/ case 1: TurnRight(); Farbe.setAllLedsColor(0, 255, 0); // grün break; case 2: MoveForward(); Farbe.setAllLedsColor(255, 255, 255); // weiß break; case 3: TurnRight(); Farbe.setAllLedsColor(0, 255, 0); // grün break; case 4: TurnLeft(); Farbe.setAllLedsColor(0, 0, 255); // blau break; case 5: MoveForward(); Farbe.setAllLedsColor(255, 255, 255); // weiß break; case 6: TurnLeft(); Farbe.setAllLedsColor(0, 0, 255); // blau break; case 7: MoveStop(); Farbe.setAllLedsColor(0, 0, 0); // aus break; default: Farbe.setAllLedsColor(0, 0, 0); // aus break; } }
Distance = ReadPing();
} void lcdprint(String s) // Display. print. {
for (int i = 0; i < s.length(); i++) { lcd.print(s[i]); }
} int LeseSensor() { int Sensorwert = 0;
Sensorwert = (digitalRead(SensorPinLeft) == 1 ? 1 : 0) << 2 | (digitalRead(SensorPinCenter) == 1 ? 1 : 0) << 1 | (digitalRead(SensorPinRight) == 1 ? 1 : 0) << 0; Serial.println(Sensorwert); return Sensorwert;
} /* if y = 8; var =(y<10)?30:40; dann var = 30 if y = 10; var =(y<10)?30:40; dann var = 40*//*//Serial.println(Sensorwert); return Sensorwert; }*/ /* ==============================================================
Messung der Entfernung.
- /
long ReadPing() {
/*int a = Sonar.ping_cm(); // sendet ein Ping und ergibt die Entfernung in Cm oder 0 falls es kein Hindernis gibt. if (a <= 2 || a > 200) { a = Max_Distance; } return a;*/ digitalWrite(Trigger_Pin, LOW); delay(5); digitalWrite(Trigger_Pin, HIGH); // Sendung eine Ultraschallwelle. delay(10); digitalWrite(Trigger_Pin, LOW); Dauer = pulseIn(Echo_Pin, HIGH); // Der Mikrokomtroller zählt die Zeit in Mikrosekunden,bis der Schall zum Ultraschallsensor zurückkehrt. long a = (Dauer / 2) * 0.03432; // 0.03432 entspricht die Schallgeschwindigkeit in Zentimeter/ Mikrosekunde. if(a>=200 || a<=2){a = Max_Distance;} return a;
}
/* ==============================================================
Servo Winkel.*/
void servoPulse (int pin, int angle) {
int pwm = (angle * 11) + 500; // Convert angle to microseconds digitalWrite(pin, HIGH); delayMicroseconds(pwm); digitalWrite(pin, LOW); delay(50); // Refresh cycle of servo
} /* ==============================================================
Rechte und linke Entfernung messen.
- /
long LookLeft() // linke Entfernung messen. {
lcd.clear(); lcd.setCursor(0, 0); lcdprint("Look at the Left"); delay(500); for (int Winkel = 70; Winkel <= 150; Winkel += 5) { servoPulse(ServoMotor, Winkel); } delay(300); long a = ReadPing(); delay(100); return a;
}
long LookRight() // Rechte Entfernung messen. {
lcd.clear(); lcd.setCursor(0, 0); lcdprint("Look at the Right"); delay(500); for (int Winkel = 150; Winkel >= 0; Winkel -= 5) { servoPulse(ServoMotor, Winkel); } delay(500); long a = ReadPing(); Serial.print("Right Dis:" ); Serial.println(a); delay(100); for (int Winkel = 0; Winkel <= 75; Winkel += 5) { servoPulse(ServoMotor, Winkel); } delay(300); return a;
}
void MoveStop() {
lcd.clear(); lcd.setCursor(8, 0); lcdprint("STOP"); digitalWrite(MotorA1, LOW); digitalWrite(MotorA2, LOW); digitalWrite(MotorB1, LOW); digitalWrite(MotorB2, LOW); SpeedMA = 0; SpeedMB = 0; analogWrite(MotorAS, SpeedMA); analogWrite(MotorBS, SpeedMB);
} // Vorwärts fahren. void MoveForward() {
lcd.clear(); lcd.setCursor(3, 0); lcdprint("Move Forward"); //delay(500); digitalWrite(MotorA1, HIGH); digitalWrite(MotorA2, LOW); digitalWrite(MotorB1, HIGH); digitalWrite(MotorB2, LOW); SpeedMA = 120; SpeedMB = 120; analogWrite(MotorAS, SpeedMA); analogWrite(MotorBS, SpeedMB);
} // Rückwärts fahren. void MoveBackward() {
lcd.clear(); lcd.setCursor(3, 0); lcdprint("Move Backward"); digitalWrite(MotorA1, LOW); digitalWrite(MotorA2, HIGH); digitalWrite(MotorB1, LOW); digitalWrite(MotorB2, HIGH); SpeedMA = 120; SpeedMB = 120; analogWrite(MotorAS, SpeedMA); analogWrite(MotorBS, SpeedMB);
}
void TurnRight() // Nach recht fahren. {
lcd.clear(); lcd.setCursor(3, 0); lcdprint("Turn Right"); digitalWrite(MotorA1, HIGH); digitalWrite(MotorA2, LOW); digitalWrite(MotorB1, LOW); digitalWrite(MotorB2, HIGH); SpeedMA = 150; SpeedMB = 150; analogWrite(MotorAS, SpeedMA); analogWrite(MotorBS, SpeedMB);
}
void TurnLeft() // Nach linkts fahren. {
lcd.clear(); lcd.setCursor(3, 0); lcdprint("Turn Left"); digitalWrite(MotorA1, LOW); digitalWrite(MotorA2, HIGH); digitalWrite(MotorB1, HIGH); digitalWrite(MotorB2, LOW); SpeedMA = 150; SpeedMB = 150; analogWrite(MotorAS, SpeedMA); analogWrite(MotorBS, SpeedMB);
}
Ergebnis
Der Roboter erfüllt seine Funktion und erkennt die schwarze und weiße Linie.Mithife des Ir Tracking Sensor kann die Linie erkannt werden und der Ultraschall miest die Entfernung. Außerdem erfüllt der Roboter alle oben gennanten Anforderung.
Zusammenfassung
Auch wenn die Durchführung des gesamten Projekts alleine eine umfangreiche Auseinandersetzung mit dem ganzen Thema erfragte, umfasste am Ende das Erreichen der definierten Projektziele eine besondere Erleichterung und Freude.Um dieses Projekt zu realisieren, haben wir unsere seit dem ersten Semester erworbenen Kenntnisse im Bereich der Programmierung und Elektronik genutzt.
Lessons Learned
Durch die Arbeit an dieses Projekt, haben wir unseren Kenntnisse im Bereich der Programierung und Elektroteschnik verbessern.Schließlich haben wir gelernt, ein konkretes Problem im Robotik zu lösen.Da wir in der Vergangenheit nie gelötet haben, war es für uns eine Herausforderung und Lehre zugleich
Projektunterlagen
Projektplan
YouTube Video
Weblinks
Literatur
→ zurück zur Übersicht: WS 20/21: Fachpraktikum Elektrotechnik (MTR)