Aufgaben
Einführung
In diesem Abschnitt werden unterschiedliche Aufgaben in drei Schwierigkeitskategorien beschrieben. Zu Beginn möchten wir dich in die Grundfunktionen vom Smartacus einführen. Um am Anfang Funktionen und deren Übergabeparameter besser verstehen zu können, haben wir euch ein kleines Video eingefügt.
Anfänger Aufgaben
Dieser Abschnitt führt euch in die einzelnen Bauteile des Fahrzeugs ein. Um die Aufgaben leichter lösen zu können, gibt es eine Übersicht - Einführung Software in der dir alle zur Verfügung stehenden Funktionen aufgelistet sind.
1. Aufgabe Mechaniker Scheinwerfer reparieren
Die Scheinwerfer an eurem Auto sind kaputt. Damit ihr sie reparieren könnt müsst ihr die Auto Software auf vorderman bringen. An eurem Auto sind vier LEDs eingebaut, vorne zwei weiße Frontscheinwerfer und hinten zwei rote Rücklichter.
Aufgabe: Schalte die Scheinwerfer deines Autos ein.
- Suche zunächst in der [Pinbelegung] die passenden Anschlüsse deiner vier Scheinwerfer heraus. Daraufhin startet deine setup()
- Hauptfunktion mit dem Funktionsaufruf port_expander.begin_I2C()
, sodass dieser für die folgenden Funktionen erreichbar ist.
Zuerst sollen die LEDs einfach angeschaltet werden. Dazu muss der gerade herausgesuchte Pin als Ausgang konfiguriert werden. Dazu gibt es folgende Funktion:
pinMode(pin, mode);
pin: Pinnummer, an dem die LED angeschlossen ist mode: entweder OUTPUT oder INPUT
Wenn der Pin als Ausgang konfiguriert ist, muss man noch „den Strom anschalten“. Dazu wird die untere Funktion genutzt.
digitalWrite(pin, value);
pin: Pinnummer, an dem die LED angeschlossen ist VALUE: entweder HIGH („Strom an“) oder LOW („Strom aus“).
Auf der Platine sind die LEDs an einen Port Expander angeschlossen, da ansonsten für die restlichen Bauteile nicht genug PINs verfügbar wären. Um auf diesen zuzugreifen, muss einfach ein port_expander. vor die Arduinospizifischen Funktionen geschrieben werden. Daraus folgt dann jeweils
port_expander.begin_I2C();
port_expander.pinMode(pin, mode);
port_expander.digitalWrite(pin, value);
Der Pin muss einmal im Setup als Ausgang konfiguriert werden. In der Loop kann er dann nach belieben ein und ausgeschaltet werden. Auf der Platine sind die LEDs fest mit den pins 5 bis 8 an dem Port Expander angeschlossen.
Hint
Der Fertige Code, um eine LED anschalten zu können, lautet:
void setup() { port_expander.begin_I2C(); port_expander.pinMode(5, OUTPUT); // Initialisierung des Pins 5 als output } void loop() { port_expander.digitalWrite(5, HIGH); // Schalet den Pin 5 an }
2. Aufgabe Scheinwerfer blinken lassen
Nachdem du den Scheinwerfer angeschaltet hast, kannst du nun den Scheinwerfer zyklisch an- und ausschalten.
Du kennst bereits die Funktion digitalWrite()
mit dem Übergabeparameter HIGH und nun möchtest du den Scheinwerfer ausschalten hierbei kannst du HIGH durch LOW ersetzen.
Damit dein Scheinwerfer auch eine gewisse Zeit leuchtet musst du noch die delay(500)
Funktion verwenden.
Aufgabe: Benutze die bekannten Funktionen und bringe deinen Scheinwerfer zum blinken.
Hint
Nachdem digitalWrite(HIGH)
kannst du nun delay(500)
verwenden, um kurz zu warten bevor du die LED wieder ausschaltest. Daraufhin nutzt du wiederrum digitalWrite(LOW)
und ebenfalls delay(500)
.
void setup() {
port_expander.pinMode(5, OUTPUT);
}
void loop() {
port_expander.digitalWrite(5, HIGH);
delay(500);
port_expander.digitalWrite(5, LOW);
delay(500);
}
3. Aufgabe Mechaniker Blinker reparieren (RGB LED mit Farbe Gelb)
Durch das reparieren der Scheinwerfer ist dir aufgefallen, dass die Blinker ebenfalls nicht funktionieren. Weil ihr euch aber schon mit den Scheinwerfer beschäftigt habt ist das Einstellen der Blinker für euch kein Problem mehr.
Aufgabe: Schalte zunächst einen der vier Blinker an und wieder aus. Das Vorgehen ist Ähnlich wie in der 2. Aufgabe. Nutze hierfür wie beim port_expander einen Zusatz, bevor du die eigentliche Funktion aufrufst. In diesem Fall rgb_led
.
Dir steht die begin()
Funktion für deine Setup zur Verfügung.
Für deine Loop kannst du die drei unteren Funktionen nutzen.
show()
setPixelColor(RGB LED Nummer 0-3, 0-255 für Rotanteil, 0-255 für Grünanteil, 0-255 für Blauanteil)
clear()
Hint
Zu Beginn nutzt du rgb_led.begin()
in deiner Setup()
Funktion um deine RGB LEDs zu initialisieren.
Nun steht dir die Funktion rgb_led.setPixelColor()
zur Verfügung, welche an erster Stelle eine RGB-Nummer, an zweiter Stelle einen Wert für Rot von 0-255, an dritter einen Wert für Grün von 0-255 und an vierter Stelle einen Wert für Blau von 0-255 erwartet.
Nachdem du deiner gewünschten LED eine Farbe zugeordnet hast, musst du nur noch rgb_led.show()
ausführen und deine LED leuchtet.
void setup() {
rgb_led.begin();
}
void loop() {
rgb_led.setPixelColor(0, 255, 118, 0);
rgb_led.show();
delay(500);
rgb_led.clear();
rgb_led.setPixelColor(0, 255, 118, 0);
rgb_led.show();
}
4. Aufgabe Motoren einfach ansteuern.
Um die Motoren deines Fahrzeugs ansteuern zu können, kannst du die Klasse motor
nutzen um auf alle Verfügbaren Motorfunktionen zuzugreifen.
Aufgabe: Um einmal zu sehen wie euer Fahrzeug fährt und lenkt, gibt es Funktionen aus der motor.h, welche dir demonstrieren, dass dein Auto auch fahren kann.
Versuche in der setup()
- Hauptfunktion die motor.init()
Funktion aufzurufen. Dies initialisiert deine Motoren und initialisiert ähnlich wie bei den LEDs die benötigten Pins für die Motoren.
Um die Motoren drehen zu lassen, kannst du die folgenden Funktionen in deiner loop()
- Hauptfunktion nutzen:
move()
mit den Übergabeparameter forward und einem Geschwindigkeitswert 0-255move()
motor.move()
steer()
steer()
Versuche nun auch die Parameter zu ändern. Wenn es den Parameter forward gibt wird es vermutlich auch backward und stop geben.
Hint
Benutze einen delay()
um zwischen längerem fahren und stoppen zu wechseln. Zusätzlich kannst du auch versuchen dein Fahrzeug durch einen Parkour zu navigieren.
Nutze für den start motor.move(forward, 100)
daraufhin ein kleines delay(500)
und zum Schluss motor.move(stop, 0)
.
5. Serielle Ausgabe
Nutze Serial.printf()
um auf der seriellen Schnittstelle eine Ausgabe zu machen. Diese kannst du dann auf deinem PC mit dem der ESP32 über Micro-USB verbunden bist anzeigen. Nutze hierfür das Steckersymbol in der blauen PlatformIO Leiste.
Die Syntax ist die selbe, die in den Grundlagen unter printf()
erklärt wird.
Serial.printf("Hello World! \n");
6. Ausgabe auf dem OLED Display
Damit du auch dein eigenes Kennzeichen oder Logo an deinem Auto haben kannst, gibt es das OLED Display, welches hinten am Fahrzeug von dir beschrieben werden kann. Nutze hierfür die oled_back
Klasse.
Es gibt 3 Funktionen um den Text linksbündig, rechtsbündig oder zentriert auszugeben. Benutze drawStringCentered("DeinText",0)
um „DeinText“ mittig auf dem Bildschirm auszugeben. Du kannst auch noch zwischen 8 Schriftarten wechseln. Die erste ist die 0, man kann diese Zahl bis zur Zahl 7 ersetzen um eine andere Schriftart zu benutzen.
Probiere auch die drawStringLeft("Text",0,0)
und die drawStringRight("Text",0,0)
Funktion aus.
Aufgabe: Benutze die genannten Funktionen um dir dein eigenes Kennzeichen zu erstellen.
Hint
void setup() {
}
void loop() {
}
7. Abstände abfragen mit den TOF Sensoren
Bei den TOF Sensoren handelt es sich um optische Time of Flight Sensoren. Diese können den Abstand von dem Sensor zu einem Objekt messen. Später sind diese Sensoren wichtig um Objekte erkennen zu können und Abstände einzuhalten, sodass du keine Unfälle verursachst. In dieser Aufgabe reicht es aber die Daten des Sensors auf dem OLED Display hinten auf deinem Fahrzeug auszugeben. Um auf deine Time of Flight Sensoren zugreifen zu können, musst du in deiner setup()
- Hauptfunktion die port_expander.begin_I2C()
initialisieren.
Aufgabe: Gib zuerst den Abstand eines Sensors über das Terminal aus. Wenn dies funktioniert, kannst du es auch noch auf dem OLED Display ausgeben. Falls du vier Sensoren verbaut hast, versuche daraufhin alle weiteren Abstände rund um dein Auto auszugeben.
Hint
Die Distanz erhälst du über die Funktion time_of_flight.front.getDistanceInMilliMeter()
. Für die andere Sensoren ersetzt du einfach front durch back, left, oder right.
Für das Oled kannst du displayDistance(int distance0, int distance1, int distance2, int distance3)
nutzen. Diese Funktion gibt dir auf dem Display die Werte aus, die du ihr mit den Übergabeparametern gibst.
void setup() {
oled_back.init();
}
void loop() {
oled_back.displayDistance(time_of_flight.front.getDistanceInMilliMeter(), 0, 0, 0);
}
Fortgeschrittene Aufgaben
1. Automatischer Blinker beim Lenken
Nachdem du bereits die Motoren ansteuern kannst ist es wichtig, dass dein Fahrzeug beim Einlenken auch in die gewünschte Richtung blinkt.
Aufgabe Nutze die vier RGB LEDs deines Fahrzeugs und steuer immer die passenden beiden LEDs beim Lenken an. Schreibe hierfür eine eigene Funktion über der setup()
mit dem Rückgabetyp void.
In deiner selbstgeschriebenen Funktion reicht es, wenn du die Lenkung und die RGB LEDs korrekt ansteuerst. Hierfür ist es nützlich, wenn du die benötigten Übergabeparameter für das Blinken und Lenken direkt an deine Funktion übergibst.
Hint
Deine Funktionsdeklaration könnte in etwa so aussehen: void steerAndBlink(int steering_angle)
. Der dazugehörige Rumpf muss eimal wie in Aufgabe 4. die Lenkung betätigen und den Blinker aus Aufgabe 3. verwenden. Das ganze muss sinnvoll verknüft werden. Dies könntest du mit einer for()
Schleife lösen, sodass du beim Einlenken 3-4 mal blinkst.
Wenn du nun in deiner
loop()
- Funktion deine neuesteerAndBlink()
aufrufst, sollte deine Fahrzeug beim Einlenken blinken.
2. Line-Tracking der schwarzen Linie folgen
An der Unterseite deines Autos befinden sich 5 Infrarot Sensoren. Diese können benutzt werden um eine Schwarze Linie zu erkennen. Diese können über AnalogRead() ausgelesen werden. Sollte der AnalogRead() Wert Hoch sein (maximal 4096) dann reflektiert der Infrarotsensor maximal und die Fläche auf dem das Auto gerade fährt ist höchstwarscheinlich hell und reflektierend. Sollte der AnalogRead() Wert gegen 0 gehen, dann ist das Auto auf einer Licht absorbierenden Oberfläche, zum Beispiel Schwarz. Diese Funktion deines Autos soll benutzt werden um nun die schwarze Linie zu erkennen.
Versuchsaufbau: Du benötigst einen hellen Boden um einen möglich großen Kontrast zur Linie zu erzeugen. Die Schwarze Linie darfst du am Boden aufbringen wie du möchtest, du könntest zum Beispiel eine 8 legen.
Aufgabe: Dein Auto soll es schaffen eine Schwarze Linie entlang zu fahren, ohne von dieser abzukommen.
3. Geschwindigkeitsmessung
Mit Bodenmarkierungen zeitstoppen über Arduino Funktion Millis
beim Überfahren der ersten Linie wird gestartet
beim Überfahren der zweiten Linie wird gestoppt
Daraus entsteht benötigte Zeit und die Bodenmarkierungen sind X Meter außeinander
=> Geschwindikeit ist ungefähr Strecke / Zeit
Lösungen zu allen Aufgaben befinden sich in der solution.h
Header-Datei.