Schlauer Roboter mit Arduino
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
Komponente | Beschreibung | Abbildung |
---|---|---|
Arduino UNO R3 | Wir haben der Arduino UNO benuzt, um dieses Projekt zu realisieren. Die Daten von den Sensoren ( IR Tracking Sensor und Ultraschallsensor) werden an den Arduino gegeben und dieser gibt entsprechende Signale an den Motortreiber. | |
L298N Motor Driver Module | Der L298N ist ein Dual-H-Brücken-Motortreiber, der die Drehzahl- und Richtungssteuerung von zwei DC-Motoren gleichzeitig ermöglicht. Das Modul kann DC-Motoren ansteuern, die Spannungen zwischen 5 und 35V haben, mit einem Spitzenstrom bis zu 2A.Das Modul hat einen eingebauten 5V-Regler, der mit einem Jumper entweder aktiviert oder deaktiviert wird. Wenn die Motorversorgungsspannung bis zu 12V beträgt, können wir den 5V-Regler aktivieren und der 5V-Pin kann als Ausgang verwendet werden, z.B. für die Stromversorgung unseres Arduino-Boards. Wenn die Motorspannung jedoch größer als 12V ist, müssen wir den Jumper abziehen, da diese Spannungen den onboard 5V-Regler beschädigen würden. In diesem Fall wird der 5V-Pin als Eingang verwendet, da wir ihn an eine 5V-Stromversorgung anschließen müssen, damit das IC ordnungsgemäß funktioniert. | |
DC Gear Motor | Wir haben insgesamt 4 Getriebemotoren verwendet. Sie sind Gleichstrom-Getriebemotor, einachsig, mit DC 3V Betriebsspannung und einer Drehzahl von 125R / Minute, wird dieses Getriebe für die Verfolgung von Auto oder Roboter eingesetzt. Mit Kunststoffkonstruktion und in leuchtendem Gelb gefärbt, misst der DC-Getriebemotor ca. 2,5 Zoll lang, 0,85 Zoll breit und 0,7 Zoll dick. | |
Ultraschallsensor | Damit der Roboter ein Hindernis erkennt, haben wir einen Ultraschallsensor verwendet. Er misst die Entfernung von Sensor zum Hindernis. Die Daten werden an die Mikrocontroller gegeben und dieser gibt entsprechende Signale an den Motortreiber. | |
3-Kanal Line Tracking Ir Sensor | das ist die Hauptkomponente, die den Roboter ermöglicht, die Linie zu verfolgen. | |
Servomotor | Ein Servo besteht aus einer Motorsteuerung, einem Elektromotor, einem Getriebe und einem Potentiometer zur Positionsbestimmung. Alle Komponenten sind in einem robusten Gehäuse untergebracht. Winkelsbereich [0; 180] Grad. | |
WS2812B_LED_controller und WS2812B_LED | Eine RGB-LED hat 3 LEDs in einer LED-Komponente integriert.Das ist nur, um den Roboter zu verschönern, so dass es bei jeden Aktion eine unterschielichen Farbe hat. Mithilfe WS2812B controller kann man die Farbe variieren und viele RGBs gleichzeitig steuern. | |
Solidworks Teil | Robotergehäuse |
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: Herr 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
https://www.youtube.com/watch?v=ra66s2fyIO4&ab_channel=FranckB
Weblinks
Literatur
→ zurück zur Übersicht: WS 20/21: Fachpraktikum Elektrotechnik (MTR)