Phase 2 2021/22

Website: xplore-dna.net > Die DNA des digitalen Lernens!
Kurs: M2: Technische Lösungen erweitern ET/MT
Buch: Phase 2 2021/22
Gedruckt von: Gast
Datum: Mittwoch, 8. Mai 2024, 15:38

Beschreibung

In diesem Buch sind die Teamergebnisse der FST21 in Phase 2 dokumentiert.

Inhaltsverzeichnis


Als Basic dient uns ein Modell aus Holz, die wir zunächst zusammenbauen müssen. Dieses Modell hat die Form eines Volkswagen T1 Busses mit einem offenen Dach damit es ebenfalls als Stiftebox genutzt werden kann.

Eine Alarmanlage mit einer akustischen und optischen Alarmausgabe am T1 wurde im vorherigen Projekt bereits realisiert. Durch eine Bewegungserkennung wird die Alarmanlage ausgelöst. Sobald sich jemand dem T1 nähert, blinken vier rote LED´s und gleichzeitig wird ein Ton über einen Buzzer ausgegeben. Ein Buzzer ist ein elektrisch angesteuerter Akustik-Signalgeber.  Die Bewegungserkennung und Alarmausgabe werden mit der Software "Arduino IDE" programmiert.

Die Alarmausgabe wird mit einem Infrarotsensor für die Bewegungserkennung, einen Buzzer für die akustische sowie vier LED´s für die optische Alarmausgabe realisiert. Ein Mikrocontroller ESP32 wurde verwendet, um die genannten Komponenten zu integrieren und zu programmieren. Erkennt der Bewegungssensor eine Bewegung, gibt dieser ein Signal an den Mikrocontroller. Anschließend werden Signale von dem Mikrocontroller an die LED´s und den Lautsprecher gesendet, um diese anzusteuern.


Die Idee dieses Projektes ist es ein Volkswagen T1 Modell, das eine Stiftebox in T1-Design ist, um einen Feuermelder zu erweitern. Dies wird in 3 Bereichen unterteilt: sobald sich der T1 Bus einer Flamme nähert, leuchtet die LED grün und spielt eine Melodie. Bewegt sich der Bus weiter in Richtung der Flamme, leuchtet die LED blau und eine andere Melodie ertönt. Wenn sich der Bus, der Flamme, weiterhin nähert, ändert sich die LED in rot und eine weitere Melodie ertönt.

Die additive Fertigung, ist die so genannte 3D Druck Fertigung, und beinhaltet das Dach mit dem Spoiler, die Räder und die Radkappen.



Die Datei als .fzz: ( Schaltplan )





Das Programm als .ino:  (Flammensensor)

Am Anfang gilt es eine Idee zu entwickeln, welchen Umfang die Konstruktion umfassen soll. Nachdem die Ideen zusammengetragen sind, fertigen wir Skizzen auf einen Zeichenblock an. Im Anschluss benötigen wir die Maße für die Konstruktionen, die mittels Messschieber und Gliedermaßstab ermittelt und in unsere Skizze niedergeschrieben werden. Nachdem nun alle nötigen Maße zusammengetragen sind, geht es an die Konstruktion mit dem CAD- Programm „Fusion 360“.  Beginnen wir mit dem Dach, wobei wir die Skizze mit der Länge und der Breite bemaßen. Danach wird diese Skizze extrudiert, das bedeutet, dass man aus einer 2D- Zeichnung einen Volumenkörper macht. Um dies zu erreichen, bekommt der zu konstruierende Körper ein Höhenmaß. Nun da wir unseren Volumenkörper fertig gestellt haben, bekommt dieser mittels der Funktion „Tasche“ Führungsschienen, die das Dach fixieren sowie Rillen, in den später der Spoiler gesteckt wird. Mit der Funktion Tasche entfernt man sozusagen Material aus dem vorhandenen Volumenkörper. Nachdem wir das Dach fertig gestellt haben, widmen wir uns den Rädern, den Achsen, den Spoiler und den Radkappen. Das besondere an den Radkappen ist, dass diese mittels gedrucktem M3 Gewinde in die Achsen geschraubt werden und auf der Frontseite unseren Teamnamen “A2” tragen. Das Gewinde wird mittels der Funktion „Gewinde“ modelliert und der Teamname über die „Textfunktion“, der ebenfalls extrudiert wird. Da wir nun alle Teile fertig konstruiert haben, werden diese mit der Software Cura gesliced.

Diese Software fungiert als Vermittler zwischen 3D- Modell und dem 3D- Drucker, indem es das Modell in dünne Schichten konvertiert, womit der 3D Drucker arbeiten kann.

Nachdem dies erledigt, ist werden die Dateien mittels 3D Druckers hergestellt. Bevor wir die Teile montieren, werden die hergestellten Teile mittels Schleifpapiers, Feilen und Gewindeschneiders nachbearbeitet, da die Reste des Druckes entfernt werden müssen.



Die .stl Dateien als .zip ( Konstruktion )

Funktionsnachweis T1 Flammenerkennung

Pos.

Bezeichnung

Menge

1

T1 Stiftebox Werkhaus

1

2

ESP32 DEV

1

3

Breadboardkabelset

1

4

Breadboards 270 Steckplätze

1

5

Passiver Piezo Buzzer KY-006

1

6

Flammensensor KY-026

1

7

RGB LED

1

8

Wiederstände 220Ω

3

9

Dach 3D Druck

1

10

Heckspoiler 3D Druck

1

11

Räder 3D Druck

4

12

Micro USB Kabel

1

                        

 


Wir lernen...

  • Projektplanungen durchzuführen
  • Schalpläne in Frizzing zu erstellen
  • Schaltungen auf dem Breadboard aufzubauen
  • Anbauteile zu montieren und den T1-Bus zu verkabeln
  • die Programmierung in Arduino IDE
  • Modelle in Catia V5/ Fusion 360 zu konstruieren
  • eine Projektdokumentation zu erstellen
  • Lösungswege zu ermitteln und im Team auf Probleme zu reagieren
  • Arbeitsaufteilungen zu planen
  • das Halten einer Präsentation
  • Projektterminpläne einzuhalten

Die Projektarbeit beschäftigte sich mit dem Thema T1 Sensors und dessen Erweiterung mit einen Flammensensor und Komponenten die mittels 3D-Druck hergestellt worden. Zu Beginn hat sich das Projektteam so organisiert, das sich die Teammitglieder aufgeteilt haben in elektrotechnische und in konstruktive Aufgabenbereiche.

Der konstruktive Aufgabenbereich umfasste die Herstellung der 3D-Druck Komponenten. Dabei wurden die konstruierten Bauteile teils erfolgreich hergestellt. Probleme bereitet hat uns die Modellierung der M3- Innengewinde, da diese zwar in der Software „Fusion 360“ modelliert angezeigt wurden aber nach dem Druck war das Gewinde nicht ausreichend vorhanden, sodass wir das Bauteil mittels Gewindeschneider nachbearbeiten mussten. Die anderen Bauteile mussten ebenfalls mittels Schleifpapiers nachbearbeitet werden. Es mussten die Reste vom Druckbett entfernt werden, um eine bessere Oberflächenbeschaffenheit zu erhalten. Rückblickend betrachtet war der konstruktive Bereich erfolgreich, jedoch mangelt es an praktische Erfahrungen mit den CAD- Programmen.  

Im elektrotechnischen Bereich gab es beim Programmieren Schwierigkeiten, aufgrund von fehlenden Erfahrungen. Die Einbindung der gewünschten Melodien stellte die größte Herausforderung dar. Dadurch das wir eine uns unbekannte Bibliothek verwendet haben, anfangs die Funktionsweise falsch interpretiert und programmiert haben, sind uns Fehler unterlaufen. Diese Fehler konnten wir durch Recherche im Internet und in den Lehrbüchern beheben. Des Weiteren ergaben sich bei der Kalibrierung des Flammensensors kleinere Komplikationen, die mit etwas Fingerspitzengefühl am Potentiometer eingestellt werden konnten. Das Einbinden der RGB LED und des Buzzers in die Programmierung sowie der Aufbau auf dem Breadboard, stellten keine Schwierigkeiten dar. An diesen Defiziten werden wir weiterhin arbeiten und weitere Übungseinheiten durchführen.

Im Großen und Ganzen verlief die Projektarbeit sehr ausgewogen, durch die aufgetretenen Komplikationen, haben wir unseren Erfahrungen erweitert. Wir haben gelernt Probleme zielführend zu lösen und sind als Team gewachsen.


...

Integration Seifenblasenmaschine und Propeller + Neugestaltung des Frontteils

Die Basis auf dem der Auftrag aufbaut, besteht aus einem T1-Bus-Modell. Dieses Modell bildet eine Stiftebox ab, die jetzt anhand des Auftrags umfunktioniert werden soll. Die Bedingung dabei ist, die Erweiterung soll mindestens eine konstruktive und eine elektrische Erweiterung aufweisen. Da die Teams sich in der 2.Erweiterungsphase befinden, hat der Bus bereits ein Upgrade bekommen. Das T1-Modell besitzt bereits aus der 1.Erweiterungsphase ein additiv angefertigtes Dach. Dieses ist ausgestattet mit einer Soundbox und einer LED für die Beleuchtung.


Folgendes bleibt bestehen:

-additiv gefertigtes Dach
-Lichteffekte mit Hilfe der LED
-Funktion der Musikboxen wird aus Platzgründen entfernt (Soundmodul)


Ziel der zweiten Erweiterung ist es, zwei weitere Ergänzungen zu integrieren. Diese werden im Bereich der Front und des Hecks vorgenommen.

Bei der ersten Ergänzung soll eine Seifenblasenmaschine im vorderen Teil des T1-Busses integriert werden. Dafür muss die vorherige Frontkomponente entfernt und durch ein additiv angefertigtes Frontteil ersetzt werden. Dadurch soll die Front ein individuelles Design bekommen.

Bei der zweiten Ergänzung soll ein Propeller am Heck des T1-Modells einen Platz bekommen. Dieser soll sich in beide Richtungen rotieren können und dem Bus nochmal einen dynamischeren Look verleihen.




Front:

Die Konstruktion des Frontteils wurde mit dem Konstruktionsprogramm Catia V5 erstellt. Mit Hilfe dieses Programms können komplexe Geometrien bzw. Bauteile konstruiert werden, um dann später diese über einen 3D-Drucker ausdrucken zu können. Vor der Erstellung der neuen Front, musste der vordere Bereich des Busses vermessen werden. Das ist notwendig, um eine Grundlage für die Erstellung des Bauteils am Computer zu schaffen. Dieser Punkt ist wichtig, um später ein passgenaues Einbauen des ausgedruckten Bauteils zu gewährleisten. Die Hauptmerkmale für das Design des Frontteils, liegen in der Gestaltung der Scheinwerfer, dem VW-Logo und dem Stoßfänger. Der Wunsch unserer Gruppe war hierbei, diese Front moderner, und somit identischer zum neuen ID-Buzz zu gestalten. Ebenfalls wurde die Front mit einer zusätzlichen Öffnung, leicht unterhalb des VW-Logos versehen. Über diese Öffnung sollte, mittels des erzeugten Windes, die Seifenblasen generiert werden.





Gedruckte Front:

Beim Konstruieren des Frontteils lag die Herausforderung darin, dass neu anfertigte Teil passgenau zu entwerfen. Hierfür war es wichtig, eine genaue Vermessung des T1-Busses vorzunehmen. Dieser wichtige Schritt hat dafür gesorgt, dass das Frontteil direkt beim ersten Versuch maßgenau in den vorhandenen Bus passte. Somit war kein zweiter Druck notwendig und es mussten keine unnötigen Kosten wie Müll produziert werden. Ebenfalls war dadurch keine Nachbearbeitung des CAD-Modells notwendig, was uns im Bereich des Zeitmanagements sehr zu Gunsten kam.



Für eine optimale Bearbeitung des neuen Auftrags, war es wichtig sich vorerst einen Plan für die Umsetzung zu überlegen. Dafür haben wir uns als Team zusammengesetzt und unser Ziele und Ideen genauer definiert. Als unsere Ideen definiert waren, erstellten wir eine Skizze um diese auch bildlich zu verdeutlichen. Anhand des Ziels haben wir eine Materialliste erstellt, um noch fehlende Materialien beschaffen zu können. Ebenfalls mussten, für beide Schaltungsfunktionen, Stromlaufpläne für die elektrische Verdrahtung der Komponenten erstellt werden.  Mit der Ankunft der bestellten Materialien, konnten wir mit der praktischen Umsetzung beginnen. Der Propeller sollte dafür als Erstes in Betrieb genommen werden. Hardwaretechnisch mussten dafür die Komponenten, nach dem Stromlaufplan, auf das Breadboard gesteckt werden und über sogenannte Jumper Wire elektrisch verbunden werden. Da wir für beide Erweiterungen jeweils mit einem Motor als Antrieb gearbeitet haben, war es notwendig jeweils noch einen Motor-Treiber (L 298N) zwischen dem Motor und dem Microcontroller zu schalten. Gleichzeitig wurde das Programm über Arduino für die Bewegung des Motors, an dem der Propeller befestigt wurde, geschrieben.

 Als diese beiden Schritte vollendet waren konnten wir das Programm im Zusammenspiel mit der Hardware testen. Als der Propeller über die Taster zum Rotieren gebracht werden konnte, setzten wir uns an die zweite Erweiterung der Seifenblasenmaschine. Dafür organisierten wir vorerst eine Seifenblasenpistole und bauten das Innenleben dieser aus.  Für die Funktion der Seifenblasenmaschine musste ebenfalls ein Motor, mit Hilfe desselben Motor-Treibers (L   298N), zum Rotieren gebracht werden. Dieser Motor erzeugt über ein Rohr und einem kleineren Propeller einen Luftstrom. Dieser Luftstrom soll im Nachhinein das Pusten eines Menschen für die Bildung der Seifenblasen ersetzen. Wie beim Propeller zuvor, konnte auch hier zeitgleich das Programm für das Rotieren des Motors geschrieben werden.

Bei beiden Programmierungen war stets darauf zu achten konzentriert zu arbeiten, um mögliche Flüchtigkeitsfehler zu vermeiden. Klein Unaufmerksamkeiten wie z.B. die falschen Ein- und Ausgänge im Programm zu verwenden oder falsch Adressierungen, folgen zur Inkonsistenz des Programms oder der Bauteile. Deshalb war es auch vorteilhaft neben jeder Zeile einen Kommentar zu schreiben, in dem kurz beschrieben wurde was genau in dieser Zeile geschieht. Um den Datenerhalt zu gewährleisten, war es ebenfalls wichtig, nach jeder geschriebenen Zeile das Programm zwischenzuspeichern.

Parallel zur Programmierung und der Installation kümmerte sich der Mechaniker unserer Gruppe um die 3D-Druck-Erweiterung.

Die Konstruktion des Frontteils wurde mit dem Konstruktionsprogramm Catia V5 erstellt. Mit Hilfe dieses Programms können komplexe Geometrien bzw. Bauteile konstruiert werden, um dann später diese über einen 3D-Drucker ausdrucken zu können. Vor der Erstellung der neuen Front, musste der vordere Bereich des Busses vermessen werden. Das ist notwendig, um eine Grundlage für die Erstellung des Bauteils am Computer zu schaffen. Dieser Punkt ist wichtig, um später ein passgenaues Einbauen des ausgedruckten Bauteils zu gewährleisten. Die Hauptmerkmale für das Design des Frontteils, liegen in der Gestaltung der Scheinwerfer, dem VW-Logo und dem Stoßfänger. Der Wunsch unserer Gruppe war hierbei, diese Front moderner, und somit identischer zum neuen ID-Buzz zu gestalten. Ebenfalls wurde die Front mit einer zusätzlichen Öffnung, leicht unterhalb des VW-Logos versehen. Über diese Öffnung sollte, mittels des erzeugten Windes, die Seifenblasen generiert werden.

Für die Erweiterung des Propellers, musste noch mit Hilfe eines Lasercutters[4] ein Loch ins Heckteil des Busses geschnitten werden. Durch diese Öffnung soll mittels einer Antriebsstange der Propeller mit dem im Innenraum liegenden Servomotor verbunden werden.

Als alle Anfertigungen, elektrisch so wie mechanisch, fertiggestellt waren, konnten wir uns um die Integration dieser Erweiterungen in den Bus kümmern. Dafür haben wir vorerst die Frontteile des alten Busses entfernt und durch die neu angefertigte Front getauscht. Anschließend musste Platz für die neuen zwei Motoren und dem Gebläse der Seifenblasenmaschine geschaffen werden. Als alle Komponente im Bus Platz gefunden hatten, mussten wir leider feststellen, dass es zu einer unglücklichen Neigung des Gebläses zur Öffnung an der Frontlippe des Busses kommt. Durch diese Neigung war es nicht mehr möglich die Seifenblasen zu erzeugen. Der erzeugte Luftstrom konnte nicht sauber aus dem Loch in der Front gepustet werden. Somit war es für uns notwendig die Komponenten nochmals umzustrukturieren. Dabei hat der Propeller an der vorderen Öffnung seinen neunen Platz bekommen und die Seifenblasenmaschine wurde ans Heck platziert. Die Einbindung des Propellers lief reibungslos ab. Die Antriebsstange ließ sich auch hier problemlos durch die Öffnung der Front schieben, um so die Verbindung zwischen Motor und Propeller zu gewährleisten. Das Einbinden der Seifenblasenmaschine war dann doch mit etwas mehr Aufwand verbunden. Am Heck musste für die Veränderung die bereits bestehende Öffnung vergrößert werden. Ebenfalls mussten wir ein weiteres kleines Loch beifügen.

Durch das obere kleinere Loch wird der Schlauch für den Transport der Seifenflüssigkeit gewährleistet. Das größere der beiden Löcher befindet sich genau auf der Höhe des Gebläses. Wenn der Motor gestartet wird, tritt die Flüssigkeit aus dem kleineren Loch aus und benetzet die Öffnung des größeren Loches. Gleichzeitig wird durch das Anschalten des Motors, das sich im Innenraum befindende Gebläse aktiviert. Der dadurch erzeugte Luftstrom pustet gegen die mit Seife beschichtete Öffnung, wodurch die Seifenblasen entstehen.  Für diese Funktion, musste noch ein Behälter für die flüssige Seife in den Innenraum des Busses platziert werden.

Final konnte noch das Dach aus der ersten Erweiterung auf den T1 aufgesetzt werden, um den Umbau des Busses komplett zu machen.



Endprodukt Propeller




Endprodukt Seifenblasenmaschine



Link zu Videos

Zusammenfassend lässt sich sagen, dass wir erfolgreich unsere Kompetenzen in den Bereichen der Konstruktion, dem 3D-Druck und der Programmierung mit Arduino erweitern und verbessern konnten. Die Aufgaben wurden alle als Team bewältigt. Gerade im Umgang vom Lösen der Probleme, konnten wir uns sehr gut ergänzen. Es herrschte stets eine gute Kommunikation untereinander, was viele Arbeitsschritte vereinfachte. Im Vergleich zur ersten Erweiterung, konnten wir aufgrund der angeeigneten Qualifikationen im Bereich des Projektmanagements, viel strukturierter und effektiver arbeiten.


Projektbeschreibung

  • Einführung
  • Auftrag
  • Vorausschau
  • Projektmanagement
  • Konstruktion
  • 3D-Druck
  • Lasercutten
  • Montage

Im Rahmen der berufsbegleitenden Technikerschule zum Staatlich geprüften Techniker für Maschinentechnik gibt es mehrere Projektaufgaben rund um den VW-Bus T1.

Im Unterrichtsfach TLERW (Modul 2 Technische Lösungen erweitern) haben wir den Auftrag erhalten, Erweiterungen für eine VW-Bus T1 Stiftebox zu entwickeln und zu konstruieren.

Als Basis für das Projekt wird uns ein Materialset und eine VW-Bus T1 Stiftebox zur Verfügung gestellt. Zudem stützt sich das Projekt auf die Ergebnisse des Projektzeitraums aus der ersten Erweiterung. Hier liegt uns ein Alarmanlagensystem das durch einen Infrarotsensor angesteuert wird und das bei Auslösung Geräusche erzeugt. Der Sensor ist hierbei auf einem 3D gedruckten Halter auf dem Dach des T1 Busses montiert.

Die Aufgaben und Teilprojekte ist nach Themen und Fachbereichen sortiert und persönlich den Teammitgliedern zugeordnet. Dadurch werden die Aufgaben koordiniert abgearbeitet. In der Beschreibung jeder Teilaufgabe wird der aktuelle Stand, vorhandene Probleme, die benötigten Ressourcen, die nachfolgenden Schritte und das Ergebnis festgehalten.

Der Sollzustand des zweiten Projektabschnittes findet sich in den Projektannahmen wieder. Der T1 Bus soll mit einer elektrischen Heckklappe und der Alarmanlage erweitert werden. Zusätzlich sollen Beleuchtungskomponenten und ein 3D gedrucktes Dach ergänzt werden.


Der Projektauftrags ist die Entwicklung, Planung, Konstruktion, Fertigung und Anschluss der Erweiterungskomponenten.


Das Dach des T1 Busses wird nach einer Vermessung des T1 Grundmodells geplant und nach den Vorgaben mit der CATIA V5 Software konstruiert. Anschließend soll das Bauteil mit dem 3D-Drucker gefertigt werden.

Die Ausschnitte für die Fenster sollen mithilfe eines Lasercutters in das T1 Modell geschnitten werden. In die Rahmen sollen passende Fenster aus transparentem Filament montiert werden.

Der Ausschnitt für die Heckklappe soll durch den Lasercutter gefertigt werden. Die Heckklappe soll am oberen Rand mittels eines Scharniers befestigt werden. Ein Servomotor soll die Heckklappe öffnen bzw. schließen.

Die Beleuchtungseinrichtung soll in der Front, im Heck und Innenraum angebraucht werden. Die dazugehörige Steuerung soll der eigens dafür programmierte ESP32 übernehmen.


Die Vorgehensweise bezüglich der Organisation des Projektes richtet sich nach dem klassischen Projektmanagement.

Einzelne Aufgaben innerhalb des Projektes werden im Todays Task Board aufgelistet und der Fortschritt im Verlauf des Projektes stetig dokumentiert. So kann für alle Teammitglieder transparent die Projektsituation dargestellt werden. Die einzelnen Termine sind zeitlich terminiert und können mit einer Erledigungsmarkierung vollständig abgeschlossen werden.

Die Aufgaben und Teilprojekte werden nach Themen und Fachbereichen sortiert und persönlich den Teammitgliedern zugeordnet. Dadurch werden die Aufgaben koordiniert abgearbeitet. In der Beschreibung jeder Teilaufgabe wird der aktuelle Stand, vorhandene Probleme, die benötigten Ressourcen, die nachfolgenden Schritte und das Ergebnis festgehalten.

CAD Modell Dach T1Anhand der Bauteilplanung konnte das Dach für den T1 Bus konstruiert werden.

3D-Druck T1 Dach

Nach der Konstruktion des Daches und dem Slicen der Datei konnte das Bauteil von einem 3D-Drucker gefertigt werden.

Nach dem Lasercutten gab es den ersten Zusammenbau der T1 Karosserie.

Mithilfe eines Lasercutters konnten Ausschnitte in die Seitenteile des T1 Busses gefertigt werden.

Nach dem 3D-Druck der Fenster konnten diese eingeklebt werden.



Die Heckklappe und das dazugehörige Scharnier konnten nach der Nachbearbeitung des Hechausschnittes problemlos montiert werden.


Hier sieht man die Programmierung der Alarmanlage und der steuerbaren Heckklappe

Hier sieht man den dazugehörigen Schaltplan zu der passenden Programmierung

Wir konnten uns in folgenden Punkten verbessern und unser Wissen erweitern:

-Projektmanagement
-Teamorganisation
-Tools bei Microsoft Teams
-Problemlöseverhalten
-Vertiefung in die Programme Arduino IDE, Catia

Steffen: „Ein einzigartiges und umfangreiches Projekt, bei dem ich viel Wissen und Fähigkeiten erlangt habe“

Christopher: „Es hat sehr Spaß gemacht, da es ein selbst ausgedachtes Projekt aufbauend auf dem vorherigen war. Die Gruppe hat auch hier wie immer super  harmoniert.“

Hannes: „Tolles weiterführendes Projekt, um sich in die Programmierung tiefergehend einzuarbeiten“


Gliederung

4.1 Projektbeschreibung

        4.1.1 Einführung

        4.1.2 Auftrag

        4.1.3 Vorausschau

        4.1.4 Inhalte

        4.1.5 Kompetenzen

        4.1.6 Projektablauf

        4.1.7 Materialliste

        4.1.8 Motivationsfaktoren

4.2 Funktionsbeschreibung

4.3 Elektrotechnik/ Elektronik

4.4 Microcontroller programmieren

4.5 App

4.6 3D-Konstruktion und rapid prototyping

4.7 Projektmanagement und Teamfähigkeit

4.8 Projektpräsentation

4.1.1 Einführung

Uns wurde der Auftrag einer zweiten Erweiterung im Anlass für die zweite Phase des Projektrahmens „T1“ erteilt. Im ersten Projekt konnten wir uns zwischen acht verschiedenen Projekten entscheiden. Wir haben uns dazu entschieden den Stiftehalter mit einem Fahrwerk auszustatten und dieses mit Hilfe einer App zu steuern. Das Fahrwerk wurde mit Hilfe von 3D Druckern gefertigt. Die Steuerung des Fahrwerks erfolgt über den Mikrokontroller ESP32. Dieser wird über Bluetooth mit einem Smartphone verbunden und mit einer selbst programmierten App gesteuert. In unserem folgenden Projekt sollen wir uns eine Erweiterung für den T1 Bus ausdenken und realisieren.


4.1.2 Auftrag

Unser Auftrag besteht im Folgendem daraus das T1-Modell um ein selbst konstruiertes Dach, sowie einem Notbremsassistenten und einen Soundgenerator zu erweitern. Der Notbremsassistent wir über einen Näherungssensor realisiert. Für diesen Sensor muss eine Sensorhalterung konstruiert und gedruckt werden. Der Sensorhalter und die benötigte Powerbank werden auf dem Dach untergebracht.


4.1.3 Vorausschau

Vorläufige Projektbeschreibung


4.1.4 Inhalte

Das Projekt beinhaltet die Punkte des Projektmanagements. Dazu gehört vorerst eine durchdachte Planung. Da das Vorprojekt nicht wie gewünscht funktioniert hat ist eine Fehleranalyse notwendig um kritische Punkte zu ermitteln und auszubessern. Anschließend kann die eigentliche Durchführung des Projektes beginnen. Dazu wird die App umdesignt und das Programm zum Mikrokontroller ergänzt. Die grundlegende Steuerung wurde aus dem Vorprojekt (Smart Device, T1-Basic) entnommmen. Der Konstruktionstechnische Teil besteht aus der Konstruktion eines Sensorhalters für den Ultraschallsensor und einem Dach.


4.1.5 Kompetenzen

Um diese Aufgabe zu bewältigen benötigt es Fach- und Methodenkompetenzen. Dazu mussten wir uns im Vorfeld Gedanken zum generellen Projektablauf machen. Die Kompetenzen zum Projektmanagement waren gegeben, waren aber jedoch ausbaufähig. Spürbar wurde es am Zeitmanagement innerhalb der Projektaufgaben. Fachkompetenzen waren unsererseits gegeben. Die 3D-Konstruktion und die additive Fertigung waren im ersten Augenblick eine Herausforderung, dennoch konnten diese Aufgaben alle erfüllt werden.
Generell wurden alle Kompetenzen in dieser Projektaufgabe erweitert.


4.1.6 Projektablauf

Es müssen Bauteile und Materialien beschafft werden (siehe Materialliste). Die Bauteile aus der Fehleranalyse werden umkonstruiert bzw. neu benötigte Bauteile werden neu konstruiert. Die App muss angepasst und überarbeitet werden. Außerdem muss die Programmierung zur Steuerung des Mikrokontrollers ergänzt werden.


4.1.7 Materialliste

Materialliste


4.1.8 Motivationsfaktoren

Da unser erstes Projekt die Erstellung und Steuerung eines Fahrwerks für das T1-Modell war, war es naheliegend die Fernsteuerung zu erweitern. Um das Modell realistischer wirken zu lassen, wollten wir mit einem Soundmodul einen Motorsound abspielen. Dieser soll selbstverständlich, trotz nicht gegebener Leistung, sehr überwältigend klingen. Um unser Fahrzeug während der Fahrt nicht zu beschädigen wollten wir einen Notbremsassistenten implementieren damit unter keinen Umständen ein Unfall provoziert wird.

Der Umfang dieses Projektes liegt in einem Notbremsassistenten und einem Soundmodul, welches einen Motorsound bei starten der App abspielt. Bei der App handelt es sich um eine mit “MIT App Inventor” selbst programmierte Android-Smartphone-App.

Um diese Bedingungen zu erfüllen wird die App zur Steuerung des Mikrocontrollers ESP32 überarbeitet. In dieser App wird die Funktion zur Steuerung freigeschaltet, indem ein Start-Knopf, welcher einen Motorsound abspielt, gedrückt wird. In der App gibt es außerdem die Möglichkeit den T1 auch ohne Motorsound zu starten. Zusätzlich wird eine Option bereitgestellt, wodurch sich die Lenkung mit einer Touch-Steuerung über einen Slider manövrieren lässt bzw. mit einer Gyro-Steuerung, was im Grunde die Steuerung über die Neigung des Mobilgeräts bedeutet. Eine vor- und zurück Bewegung wird mit zwei Tasten in der App ermöglicht.

Der Mikrocontroller ermittelt mit dem verwendeten Ultraschallsensor dauerhaft einen Wert zu dem sich vor dem T1 befindenden Hindernissen. Wenn dieser Wert einen Soll-Wert von 10 cm unterschreitet wird der Motor gestoppt und das Fahrzeug kommt zum Stillstand.

Die Verkabelung des Breadboardes findet sich in der .fzz Datei.

Anmerkungen:

  •  der Pulldown Widerstand kann von 100kΩ bis 1MΩ betragen.
  • bei uns gab es Probleme bei der Spannungsversorgung weshalb man drauf achten muss das man ausreichend Leistung bereitstellt. (5V 2,1A Powerbank hatte nicht gereicht) 
  • Lautsprecher können bis zu 3 W Leistung haben.
  • auf den Schulrechnern ist Fritzing zu alt deshalb ist der Ultraschallsensor nach dem öffnen weg.

Es gibt 3 Programme, das Erste:

ist ein Programm das Bluethooth Nachrichten in der Monitor Funktion von Arduino anzeigt und die Verarbeitung überprüft. Das Programm ist nur notwendig wenn man was an der App ändern möchte.

Das Zweite ist ein Programm, um mit einer App die Endanschläge und den Gradeauslauf festzustellen. Die festgestellten Werte muss man dann im Hauptprogramm ändern( Zeile 145 -153)

Das Hauptprogramm ist das Programm was zum Fahren mit der App benutzt wird


Es wurden hier insgesamt vier verschiedene Bauteile gedruckt. Alle Bauteile wurden mit schwarzem oder weißem PLA-Filament gedruckt. Das Dach wurde in hoher Qualität gedruckt. Für die restlichen Bauteile reichen durchschnittliche Einstellungen aus. Jedes Bauteil wurde zusätzlich mit einem Brim gedruckt. Die Datei für die Motorhalterung ist leider nicht mehr verfügbar. Die Datei der Motorachse lässt sich nicht in der Schule öffnen, da die Datei mit einer neueren Version von Catia erstellt wurde. Die .stl- Dateien von dem Dach und dem Sonsorhalter mussten als .zip Datein hochgeladen werden. 

  1. Motorachse (CATPart)
  2. Dach (CATPart)
  3. Sensorhalterung (CATPart)

Es sind nur die .aia Datein diese können auf der Internetseite vom MIT APPINVENTOR zu Projekte umgewandelt werden. Diese Projekte kann man dann zu APK umwandeln die man auf Android Geräten installieren kann, solange man die unbekannten Quellen akzeptiert.

Die Lenkungsapp ist zum anlernen der Lenkung.

Und die T1app ist zum Steuern des T1.

Um dieses Projekt absolvieren zu können bedarf es Projektmanagementkompetenzen und gute Zusammenarbeit im Team.

Das Kommunikation und Aufgabenverteilung im Team verlief sehr gut. Jeder kannte die Stärken und Schwächen des anderen, wodurch Aufgaben bestens verteilt werden konnten.

Das Projekt unterlief dem Prinzip des klassischen Projektmanagements. Es wurden die einzelnen Punkte der Vorbereitung, Planung, Durchführung und Abschluss abgearbeitet. Zunächst wurde das Vorprojekt kritisch betrachtet. Es wurden Punkte ermittelt, die es vorerst zu verbessern gilt. Zudem wurde der Umfang besprochen und einzelne Aufgaben erstellt. Dokumente wie die Materialliste wurden dementsprechend angepasst. Im Anschluss wurden die eigentlichen Aufgaben bearbeitet. Dazu zählt grob gesagt die Anpassung der App, Erweiterung des Programms für den Mikrocontroller und der 3D-Konstruktion.

Platzhalter Projektpräsentation

Projektbeschreibung

  • Einführung
  • Auftrag
  • Vorausschau
  • Inhalte
  • Kompetenzen
  • Projektablauf
  • Materialplanung
  • Motivationsfaktoren

Funktionsbeschreibung

Elektrotechnik/ Elektronik

Microcontroller programmieren

3D-Konstruktion und rapid prototyping

Projektmanagement und Teamfähigkeit

Projektpräsentation


Einführung: 

Der bereits aus Phase 1 erweiterte T1 Bus wird mit verschiedenen LEDs zur Abstandsanzeige und einer sich verändernden Tonfrequenz durch den Buzzer in Phase 2 erweitert. Dazu kommt eine Dachhalterung mit 3D-Druck und die Montage des Gleichstrommotors mit Fahrwerk, das beim Programmierten erreichten Abstand den Bus vor dem Hindernis zum stehen bringt und ausweicht.

Auftrag:

Der Auftrag war es den Bus zu erweitern. Der Bus sollte Hindernisse erkennen und dementsprechend auf diese reagieren und ausweichen. Dazu benötigte der Bus außerdem ein Fahrwerk sowie eine Lenkung.


Inhalte:

Für das Projekt wurde musste eine Ausführliche Planung erfolgen. Dort haben wir die Funktionen und Erweiterungen nochmal genau durchgesprochen. Das Fahrwerk mit Lenkung und Antriebsmotor sowie die Reifen musste mit Hilfe von 3D-Druck Konstruiert werden. Des weiteren kam später noch eine Dachhalterung für die Powerbank sowie eine Halterung der LED´s hinzu. Außerdem musste die Programmierung von Antrieb, Lenkung, Ansteuerung von LED´s und Reagieren auf Hindernisse erstellt werden.

 Kompetenzen:

Zu den Kompetenzen zählt der 3D-Druck sowie die Programmierung mit Arduino. 

 Programmablauf:

Es mussten neue Bauteile erstellt werden mit dem 3D Druck. Außerdem musste die erweiterte Programmierung geschrieben werden. Am Ende wurde alles verdrahtet, zusammengebaut und getestet.

Materialliste

Motivationsfaktoren:

Unser bereits bestehendes Programm bestand aus einer Erkennung und Abstandsmessung von Teilen. Daher kamen wir auf die Idee, dass sich das Fahrzeug statt die Teile sich bewegt. Dazu sind uns viele weitere Ideen eingefallen, welche wir dann in das Projekt implementiert haben.


 Wird die Powerbank durch das Micro-USB Kabel mit dem ESP 32 verbunden, startet dadurch die Stromversorgung aller Komponenten. Der auf einem Fahrwerk aufgebaute T1, welches mit einem 3D-Drucker hergestellt wurde fährt bei bodenkontakt der Hinterreifen mit dem Boden geradeaus los. Hindernisse die dem T1 im weg sind werden vom Ultraschallsensor erfasst. Die Daten des Ultraschallsensors werden an den ESP32 weitergegeben und verarbeitet. Welcher dann bei Näherung zu einem Hindernis zuerst eine Blaue LED, dann zwei Grüne, dann zwei Gelbe und bei sehr gering leuchten die beiden roten LEDs aktiviert. Parallel zu den leuchten LEDs gibt der Buzzer eine sich verändernde Tonfrequenz ab welche in geringeren abständen aktiviert wird je näher das Hindernis ist und bei Erreichen eines Abstands von 30 cm stoppt der Motor und dreht rückwärts. Bei Erreichen des Grenzwertes von 30 cm wird zudem der Servomotor angesteuert, welcher durch Einstellen auf einen Wert, die Achse im Lenkwinkel verändert. Nach Ablauf von 5 Sekunden bleibt der Motor stehen und stellt den Servomotor in seine Ursprungsposition zurück, sodass der Bus wieder geradeaus fährt.

 Nun misst der Ultraschallsensor erneut den Abstand und fährt bei einer Entfernung von über 30 cm zum nächsten Hindernis wieder vorwärts. Die LEDs werden mit einer 3D gedruckten Dachhalterung befestigt. Zudem wird eine Dachhalterung für eine Powerbank gefertigt, welche dafür sorgt, dass die Stromversorgung des ESPs platzsparend verbaut ist. Für das Fahrwerk werden zusätzlich Reifen gedruckt, welche dafür sorgen, dass sich der Bus fortbewegen und Hindernissen ausweichen kann.

Um den Bus zum Stehen zu bringen muss der ESP 32 von der Stromversorgung getrennt werden. Wodurch alle Komponente ihre Funktion beenden.    


HC-SR04
Ultraschallsensor

  • Sendet Ultraschallwelle an Umgebung
  • Welle reflektiert an einem Hindernis
  • Erfassung der Zeit der Welle
  • Berechnung Abstand des Hindernisses

ESP 32
Microcontroller

Steuerung und Vernetzung von z.B. Sensoren
Kenndaten:

  • Betriebsspannung 3,3 V oder 5,0 V
  • Betriebstemperaturbereich: –40°C to bis 125°C
  • RAM (Arbeitsspeicher): 512 Kilobyte
  • CPU (Prozessor) aus 2 Kernen mit einer Taktfrequenz von 240 MHz
  • WLAN-Modul
  • Bluetooth-Modul

L298N
Motortreiber

Kenndaten:

  • Chip: L298N (ST NEW)
  • Spannung: 5V
  • Laufspannung : 5V-35V
  • Strom: 0 mA-36mA
  •  Fahrstrom: 2A (MAX einzige Brücke)
  •  Max. Leistung: 25W
  •  Größe: 43 x 43 x 26mm







Programm Seite 1╰┈➤




Motorachse und Powerbank Halter



-Sicherungsring für die Motorachsen

-Dach und Powerbank Halter





Ultraschallsensor Halterung



  


-Verbesserung durch besser Anlage






LED Halterung





-Steckverbindung
-Erweitert mit   Kabelkanälen




Im Rahmen der Weiterbildung zum Techniker an der BBS2 Wolfsburg sollen fachliche Kompetenzen in der selbstständigen Umsetzung eines Projektes von Grund auf vermittelt werden. Das Modul 2: Technische Lösungen erarbeiten und erweitern stellt hier den praktischen Teil dar.

Wir werden eine „Park-Distance-Control“ umsetzen, und die Steuerung des Fahrzeuges wird über einen Infrarothandsender realisiert.  Das Fahrzeug soll sich vorwärts und rückwärts verfahren lassen und in der Vorwärtsbewegung bei Erkennung eines Objektes im Fahrweg die Geschwindigkeit reduzieren.


In diesem Kapitel werden euch die benötigten Materialien und Werkzeuge zum erfolgreichen Abschluss dieses Projektes aufgelistet. Begonnen wird mit den Materialien, die in dem Set von der BBS2 Wolfsburg zur Verfügung gestellt wurden:

  • Das T1 Fahrzeugmodell, 1 Stck
  • Der Microcontroller ESP32, 1 Stck
  • Das Breadboard mit 270 Steckplätzen, 2 Stck
  • Das Breadboardkabelset
  • Der Widerstandssatz
  • Der IR Infrarot Empfänger, 1 Stck
  • Der Getriebemotor, 1 Stck
  • Das Display mit Decoder, 1 Stck
  • Der Ultraschallsensor, 1 Stck
Die Materialien, die wir in unserer Projektgruppe zusätzlich angeschafft haben oder bereits Privat in unserem Besitz hatten sind die Folgenden:


Zusätzlich werden zur Durchführung Materialien und Werkzeuge von der Schule zur Verfügung gestellt:
  • Der 3D- Drucker
  • Die Software Catia zum Konstruieren von zu druckenden Teilen
  • Die Software Cura zum Slicen von zu druckenden Teilen
  • Das PLA/TPA/PETG Filament zum Drucken von Materialien
  • Der Lasercutter zum bearbeiten/ Nachbearbeiten von Seitenteilen des T1 Modells
  • Kleber auf Kunststoffbasis zum Verbinden von Fahrzeugkomponenten
  • Die Software Arduino zum programmieren des Mocrocontrollers mitsamt den Konfigurationsinformationen


In diesem abschnitt werden die elektronischen Komponenten und deren Funktionen beschrieben. Die Komponenten wurden allesamt in unserem Projekt verwendet.

Beschrieben werden

  1.  Der Infrarotsensor
  2.  Der Ultraschallsensor
  3.  Das Display mit Decoder
  4.  Das Soundmodul
  5.  Der Motortreiber

Der Infrarotempfänger wartet auf das Eingehen eines Infrarotsignales von dem Handsender. Im Ruhezustand liegt an dem Datenpin des Empfängers zum Mikrokontroller ein HIGH-Signal an (nichts passiert). Sobald ein Infrarotsignal vom Empfänger erkannt wird, wird der Datenpin auf LOW geschaltet und danach die Information übermittelt. Diese Information ist in binär codiert und erfordert eine Decodierung. Die Übersetzung wird von einer Bibliothek vorgenommen. Der decodierte Wert wird in einer Variable zwischengespeichert und kann zum Beispiel mit vorhandenen Tastencodes im Programm verglichen werden.

Nach dem Auslesen des Infrarotsignals kann keine Prüfung auf Plausiblität der Daten vorgenommen werden, da diese nur in eine Richtung übertragen werden. Aus diesem Grund kann es dazu kommen, das der ausgelesene Infrarotcode nicht dem richtigen Code entspricht. In diesem Falle sollte mehrfach die auszulesene Taste hintereinander betätigt werden und der am häufigsten auftrtende Code ist der zuordnenbare Code.


Hier (Datei "Vorlage_IR_Auslesen.ino") findet man ein Programmbeispiel zum auslesen des Infrarotempfängers :


#include <IRremoteESP8266.h>                              // Bibliothek zum empfang von Infrarotsignalen
#include <IRrecv.h>                                       // Bibliothek zum verarbeiten von Infrarotsignalen
#include <IRutils.h>                                      // Bibliothek für Funktionen nach Infrarotempfang


#define RECV_PIN  34                                       //Pin, an dem der Pin des IR-Empfängers angeschlossen ist

IRrecv irrecv(RECV_PIN);                                   //Eingangsbestimmung für den Infrarot-Datenstrom
decode_results results;                                    //Dekodierung in Datei schreiben
int IRcode = 0;                                            //variable für den Empfangen Tastencode

void setup()
{
  irrecv.enableIRIn();                                    // Empfänger wird ausgeführt
  Serial.begin(115200);                                   //Serielle Kommunikation starten
}

void loop()
{
  int IRcode = 0;                               //Zurücksetzen des IR-Codespeichers für das nächste auslesen
  if (irrecv.decode(&results))                  //Wenn ein IR-Signal empfangen wurde
  {
    IRcode = (results.value);                   //Das Empfangsignal in der Variable speichern
    Serial.print(IRcode, HEX);                  //Gebe den IrCode hexadezimal im Seriellen Monitor aus
    Serial.println("");
    irrecv.resume();                            //IR-Empfänger für den nächsten Wert bereit machen.
    delay(100);                                 //Verzögerung für den Empfang der nächsten Variable
  }
}



Der Ultraschallsensor verwendet Sonar, um die Entfernung zu einem Objekt zu bestimmen. Folgendes passiert: 

Der „Trig“ - Pin wird für 10 Millisekunden mit einem HIGH-Signal beschaltet, eine Messung wird initiiert. Aus dem Transmitter wird ein Ultraschallton entsendet. Der Ultraschall trifft auf ein Objekt und wird in den Receiver reflektiert. Bei Empfang durch den Receiver wird der Echo-Pin mit einem HIGH-Signal beschaltet. Die verstrichene Zeit von Senden zu empfangen wird im ESP32 erfasst und im Anschluss verarbeitet, um einen Abstand zum Objekt zu bestimmen. 

Hier (Datei "Vorlage_Ultraschallsensor.ino") ist ein Programmbeispiel für die Ausführung dieser Aufgabe:

#define echo 15                                 //Anschluss ECHO vom HC-SR04 wurde für PIN 15 festgelegt
#define trig 16                                 //Anschluss TRIG vom HC-SR04 wurde für PIN 16 festgelegt
 
int distanz1 = 0;                             //Entfernung als globale Variable anlegen



//Funktion zur Messung der Entfernung über den Ultraschallsensor HC-SR04 (mit Echo und Trigger), Ausgabe in mm
int EntfernungsMessung1 (){

  long distanz1 = 0;                                                                      //Deklaration der Variablen "distanz1"
  long zeitx1 = 0;                                                                        //Deklaration der Variablen "zeitx"
 
  digitalWrite (trig, LOW);                                                               //setzt den Zustand von trig auf LOW
  delayMicroseconds(3);                                                                   //setzt eine Pause/Unterbrechung von 3 Mikrosekunden
  noInterrupts();                                                                         //verhindert eine Unterbrechung des Vorgangs
  digitalWrite(trig, HIGH);                                                               //setzt den Zustand von trig auf HIGH
  delayMicroseconds(10);                                                                  //setzt eine Pause/Unterbrechung von 10 Mikrosekunden
  digitalWrite(trig, LOW);                                                                //setzt den Zustand von trig auf LOW
  zeitx1 = pulseIn(echo, HIGH);
  interrupts();                                                                           //lässt Vorgangsunterbrechungen erneut zu
 
  zeitx1 = (((zeitx1 * 344)/1000)/2);                                                     //vererrechnet den Wert der Zeit mit der Schallgeschwindigkeit nach der Raumtemperaur,
                                                                                          //dem Faktor für die Kommastelle und halbiert diesen wegen der doppelten strecke (hin+zurück)
  distanz1 = zeitx1;
  Serial.print("distanz1  Wert01:");                                                      //Ausgabe des Wertetyps in den seriellen Monitor
  Serial.print(distanz1);                                                                 //Ausgabe des Wertes in den serieleln Monitor
  Serial.println("");
  delay (200);                                                                            //Verzögerung zur nächsten Messung
  return (distanz1);                                                                      //Ausgabe des Wertes für die Entfernung
}
void setup()
{
  pinMode(trig, OUTPUT);      //Legt den Eingangstyp des angegebenen PINs fest
  pinMode(echo, INPUT);       //Legt den Eingangstyp des angegebenen PINs fest
}
 
 
void loop()
{
  EntfernungsMessung1 ();
}

Das Display mit Decoder stellt Werte und Variablen dar. Diese werden mithilfe einer Bibliothek, die den Datenverkehr zum Display regelt, übertragen und dargestellt. Der Pin “CLK” des Displays wird mit einem kontinuierlichen Taktsignal² beschaltet. Zur Datenübertragung muss für eine bestimmte Anzahl an Takten der Datenpin “DIO” in den HIGH-Zustand versetzt werden, um dem Decoder den Beginn einer Datenübertragung zu signalisieren. Nach einer vorgegebenen Zeit beginnt dann die Übertragung der Daten an den Decoder durch das HIGH bzw. LOW schalten des Datenpins. Nach der vollständigen Übertragung wird erneut eine HIGH-Sequenz ausgegeben, um dem Decoder das Ende der Datenübertragung mitzuteilen. Danach werden die ausgegebenen Daten auf dem Display angezeigt. Je nachdem, welche Bibliothek für das Display eingebunden wird, können Zahlen, Formen und einzelne Segmente dargestellt werden. Auch Laufschriften sind umsetzbar, werden hier aber nicht genutzt.

(Datei "Vorlage_DmDec.ino")

#include <TM1637TinyDisplay.h>                              // Bibliothek für die 7- Segment Anzeige

#define CLK       19                                        //Pin, an dem der Clock-Pin des Displays angschhlossen ist
#define DIO       5                                         //Pin, an dem der DIO-Pin des Displays angeschlossen ist

TM1637TinyDisplay display(CLK, DIO);                        //Bestimmung der Ausgänge für die 7-Segment Anzeige

int displayBrightness = 7;                                  //Standardhelligkeit für Display


const uint8_t SEG_emptyFrame_01[] = {0x00, 0x00, 0x00, 0x00}; //Leerer Frame

const uint8_t SEG_welcome_01[] = {0x00, 0x00, 0x00, 0x3c}; //Laufschrift W
const uint8_t SEG_welcome_02[] = {0x00, 0x00, 0x3c, 0x1e}; //Laufschrift W
const uint8_t SEG_welcome_03[] = {0x00, 0x3c, 0x1e, 0x79}; //Laufschrift WE
const uint8_t SEG_welcome_04[] = {0x3c, 0x1e, 0x79, 0x38}; //Laufschrift WEL
const uint8_t SEG_welcome_05[] = {0x1e, 0x79, 0x38, 0x58}; //Laufschrift WELC
const uint8_t SEG_welcome_06[] = {0x79, 0x38, 0x58, 0x5c}; //Laufschrift ELCO
const uint8_t SEG_welcome_07[] = {0x38, 0x58, 0x5c, 0x54}; //Laufschrift LCOM
const uint8_t SEG_welcome_08[] = {0x58, 0x5c, 0x54, 0x54}; //Laufschrift COM
const uint8_t SEG_welcome_09[] = {0x5c, 0x54, 0x54, 0x79}; //Laufschrift OME
const uint8_t SEG_welcome_10[] = {0x54, 0x54, 0x79, 0x00}; //Laufschrift ME
const uint8_t SEG_welcome_11[] = {0x54, 0x79, 0x00, 0x00}; //Laufschrift ME
const uint8_t SEG_welcome_12[] = {0x79, 0x00, 0x00, 0x00}; //Laufschrift E


void setup()
{
}

void loop()
{
  display.setBrightness(displayBrightness);                 //Helligkeit der 7-Segment Anzeige. Standard-Wert 7
  display.clear();
  display.setSegments(SEG_welcome_01);
  delay(100);
  display.setSegments(SEG_welcome_02);
  delay(100);
  display.setSegments(SEG_welcome_03);
  delay(100);
  display.setSegments(SEG_welcome_04);
  delay(100);
  display.setSegments(SEG_welcome_05);
  delay(100);
  display.setSegments(SEG_welcome_06);
  delay(100);
  display.setSegments(SEG_welcome_07);
  delay(100);
  display.setSegments(SEG_welcome_08);
  delay(100);
  display.setSegments(SEG_welcome_09);
  delay(100);
  display.setSegments(SEG_welcome_10);
  delay(100);
  display.setSegments(SEG_welcome_11);
  delay(100);
  display.setSegments(SEG_welcome_12);
  delay(100);
  display.setSegments(SEG_emptyFrame_01);
  delay(200);
}



Die Soundmodule werden mit Spannung versorgt. Ein jedes der Soundmodule verfügt über eine Aufnahmetaste, die bei Druck das interne Mikrofon aktiviert und die Aufnahme eines Tons zulässt. Über die Play-Taste kann der Ton wiedergegeben werden. Diese Funktion lässt sich auch über das Ansteuern des Play-ins auf dem Soundmodul durch einen Ausgangspin des Mikrokontrollers auslösen. 

âuch hierfür gibt es ein Programmbeispiel:


int Abspielen = 12;

void setup()
{
pinMode(Abspielen, OUTPUT);
}

void loop()
{

digitalWrite(Abspielen, HIGH);                                            //soll Start-Ton abgespielt werden
delay(100);
digitalWrite(Abspielen, LOW);
delay(1000);

Die H-Brücke hat die Aufgabe, den Motor in seinen zwei Drehrichtungen anzusteuern. Je nachdem welches Signal an den zwei Pins für die Drehrichtung anliegt, wird die Drehrichtung des Motors bestimmt. 


Belegung der Pins eines Motors
      Pin 1      
      Pin 2     
      Drehung Motor      
LOW LOW Keine Drehung 
HIGH LOW Drehrichtung rechts 
LOW HIGH Drehrichtung links 
HIGH HIGH Keine Drehung 


Damit die Drehung des Motors ausgeführt wird, muss gleichzeitig auch eine Ansteuerung des Freigabepins erfolgen. Diese Ansteuerung kann entweder mit einem permanenten HIGH-Signal erfolgen oder durch ein PWM- Signal. Zusätzlich wird für das Betreiben des Motors eine Spannungsquelle in Form einer 9V- Batterie benötigt. Diese liefert den benötigten Strom zum Betreiben des Motors, da die Stromquelle in Form des Mikrokontrollers nicht die benötigte Strommenge erbringen kann.


Hier (Datei "Vorlage_L298N.ino") befindet sich ein Beispiel für die Ansteuerung des Motortreibers:


// Motortreiber L298N
#define MotV 27
#define MotR 26
#define MotEna 12

//PWM Motortreiber
int Freq = 30000;
int Res = 8;
int PwmChannelMotEna = 2;
int DutyCycleMotEna = 0;                                                                  // MaximalWert: 250; Minimalwet 160;
int DutyCycleNull = 0;

void setup() {
//L298N
pinMode (MotV     , OUTPUT);                                                              // festlegen des Pins am L298N als Ausgang
pinMode (MotR     , OUTPUT);                                                              // festlegen des Pins am L298N als Ausgang
pinMode (MotEna   , OUTPUT);                                                              // festlegen des Pins am L298N als Ausgang

//PWM
ledcSetup (PwmChannelMotEna, Freq, Res);                                                  // PWM-Kanal Einstellung
ledcAttachPin (MotEna, PwmChannelMotEna);                                                 // Definition des PWM-Kanals auf den Pin
}

void loop() {
    digitalWrite (MotV , LOW);                                                            // Schreiben der Drehrichtung des Motors
    digitalWrite (MotR , LOW);                                                            // Schreiben der Drehrichtung des Motors
    DutyCycleMotEna = 200;                                                                //
    digitalWrite (MotV , HIGH);                                                           // Schreiben der Drehrichtung des Motors
    digitalWrite (MotR , LOW );
    ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                        // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
    delay (200);
    ledcWrite (PwmChannelMotEna, DutyCycleNull);                                          // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
    delay(100);
    digitalWrite (MotV , LOW);                                                            // Schreiben der Drehrichtung des Motors
    digitalWrite (MotR , HIGH );
    ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                        // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
    delay(200);
    ledcWrite (PwmChannelMotEna, DutyCycleNull);                                          // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
    digitalWrite (MotV , LOW);                                                            // Schreiben der Drehrichtung des Motors
    digitalWrite (MotR , LOW);                                                            // Schreiben der Drehrichtung des Motors

}

Für die entwicklung der Schaltpläne und der Programmierungen haben wir jede Funktion einzeln entwickelt und diese zum Schluss zusammengefügt. Da nicht eine Person für alle Schaltpläne zuständig war, sondern die Schaltpläne und die jeweilig zugehörigen Programmcodes von einzelnen Personen erstellt wurden, mussten Absprachen zu der Pinbenutzung des Microcontrolles ESP32 getroffen werden. Zudem durften aufgrund der Hardwarespezifikation nicht alle Pins für alle Funktionen genutzt weren. An dieser Stelle kommt die Website Randomnerdtoturials mit einem Hilfreichen Datenblatt zur Pinbelegung zur Hilfe. Der Link befindet sich hier.

Mit diesen Informationen lässt sich schon beim Aufbau der einzelnen Funktionen eine Fehlerquelle ausschließen.

In diesem Abschnitt finden sich folgende Schaltpläne wieder:
  • Der Schaltplan des Infrarotempfängers

  • Der Schaltplan des Ultraschallsensors


  • Der Schaltplan des Display mit Decoder


  • Der Schaltplan der Soundmodule



  • Der Schaltplan des Motortreibers


Auch für den Proogrammcode wurden alle Funktionen einzeln entwickelt. Die Funktionen wurden so geschrieben, das sie als einzelne Abschnitte in einem Programm aufgerufen werden und somit der Programmcode, der in den Loop geschrieben wird, übersichtlich und gegliedert ist. Zudem wird eine jede Programmzeile und ein jeder Programmabschnitt zur besseren nachvollziehbarkeit kommentiert und sinnvoll ausformuliert. So sind die Programme für die elektronischen Komponenten entstanden:

  1. Der Infrarotempfänger
  2. Der Ultraschallsensor
  3. Das Display mit Decoder
  4. Die Soundmodule
  5. Der Motortreiber
Nach der Erstellung dieser Programmabschnitte wurden einzelne Abschnitte des Programms auf den entwickelten Funktionen aufgebaut:

  1. Die Park Distance Control- Funktion
  2. Die Fahrzeugbewegung Vor- und Rückwärts
  3. Der Positioniermodus
  4. Der Stoppmodus
Nachdem auch diese Funktionen einzeln aufgebaut wurden, können die Funktionen zusammengefasst werden
  1. Die Zusammenführug des Programmcodes

Die Funktion der Park Distance Control soll sicherstellen, das ein Fahrzeug, das geparkt wird, nicht mit objekten vor dem Fahrzeug kollidiert. Es erfasst objekte, die der Fahrer möglicherweise nicht sehen kann, weil sie sich im toten Winkel befinden.

Über die Taste „5“ des Infrarothandsenders wird die PDC aktiviert. Die PDC gibt grafisch über das Display mit Decoder und akustisch über die Soundmodule die Distanz zu einem erfassten Objekt aus.  Diese Erfassung ist standardmäßig auf den mittleren Wertebereich eingestellt. Der Wertebereich lässt sich durch Druck auf die „Channel Minus“ - Taste in den Cluster „nah“ und durch Druck auf die „Channel Plus“ - Taste in den Cluster „fern“ verändern. Je nach Entfernung zum Objekt verändert sich die Grafik auf dem Display und die Töne der Soundmodule verändert sich.  Durch Druck auf die „Power“ - Taste wird der PDC-Modus wieder verlassen. Ebenfalls wird der Modus wieder verlassen, wenn einer der anderen Modi des Fahrzeugs angewählt wird. 

Hier (Datei "Vorlage_PDC.ino") befindet sich der Programmcode für die Funktion:

//Infrarotsensor
#include <IRremoteESP8266.h>                                                              // Bibliothek zum Empfang von Infrarotsignalen
#include <IRrecv.h>                                                                       // Bibliothek zum Empfang von Infrarotsignalen
#include <IRutils.h>                                                                      // Bibliothek für Funktionen nach Infrarotempfang
#define RECV_PIN  34                                                                      // Pin, an dem der Pin des IR-Empfängers angeschlossen ist
IRrecv irrecv(RECV_PIN);                                                                  // Eingangsbestimmung für den Infrarot-Datenstrom
decode_results results;                                                                   // Dekodierung in Datei schreiben

//Hexcodes für die Tasten des Infrarothandsenders
// Angabe von '0x' vor dem eigentlichen Hexcode
//         Bezeichnung                  HEX-Code
int button_Power          =             0xECDF8084;                                       // zurücksetzen auf den ursprungszustand
int button_Down           =             0x7F984248;                                       // keine Zuordnung in diesem Programm
int button_Up             =             0xC5F76D04;                                       // keine Zuordnung in diesem Programm
//int button_01             =             0x3138F3E0;                                       // keine Zuordnung in diesem Programm
//int button_02             =             0xBF33DC80;                                       // keine Zuordnung in diesem Programm
//int button_03             =             0xABB78D20;                                       // keine Zuordnung in diesem Programm
//int button_04             =             0x4A86A8C0;                                       // keine Zuordnung in diesem Programm
int button_05             =             0xC0134580;                                       // Modus PDC optische akustische Signale
//int button_06             =             0xBA1256C4;                                       // keine Zuordnung in diesem Programm
//int button_07             =             0x52A2DA24;                                       // keine Zuordnung in diesem Programm
//int button_08             =             0xB74C8420;                                       // keine Zuordnung in diesem Programm
//int button_09             =             0xE3172C20;                                       // keine Zuordnung in diesem Programm
//int button_VolumePlus     =             0xF62981E4;                                       // keine Zuordnung in diesem Programm
//int button_00             =             0x2F9EF384;                                       // keine Zuordnung in diesem Programm
int button_ChannelPlus    =             0x9C7C29E0;                                       // Änderung Wertebereich für optische akustische Signale nach oben
//int button_VolumeMinus    =             0x973C68E0;                                       // keine Zuordnung in diesem Programm
//int button_Enter          =             0x3C1BB180;                                       // keine Zuordnung in diesem Programm
int button_ChannelMinus   =             0x1B433B24;                                       // Änderung Wertebereich für optische akustische Signale nach unten
int IRcode = 0x00000000;                                                                  // variable für den Empfangenen Tastencode
int merker_Power          =  0;
int merker_Down           =  0;
int merker_Up             =  0;
//int merker_01             =  0;
//int merker_02             =  0;
//int merker_03             =  0;
//int merker_04             =  0;
int merker_05             =  0;
//int merker_06             =  0;
//int merker_07             =  0;
//int merker_08             =  0;
//int merker_09             =  0;
//int merker_VolumePlus     =  0;
//int merker_00             =  0;
int merker_ChannelPlus    =  0;
//int merker_VolumeMinus    =  0;
//int merker_Enter          =  0;
int merker_ChannelMinus   =  0;

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//Ultraschallsensor
#define echo 15                                                                           // Anschluss ECHO vom HC-SR04 wurde für PIN 15 festgelegt
#define trig 18                                                                           // Anschluss TRIG vom HC-SR04 wurde für PIN 18 festgelegt

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//Display mit Controller
#include <TM1637TinyDisplay.h>                                                            // Bibliothek für die 7- Segment Anzeige
#define CLK 21                                                                            // Anschluss CLK von der 7- Segment Anzeige wurde für PIN 21 festgelegt
#define DIO 19                                                                            // Anschluss DIO von der 7- Segment Anzeige wurde für PIN 19 festgelegt
TM1637TinyDisplay display(CLK, DIO);
const uint8_t SEG_PDC_NORMAL[] =         {0x39, 0x00, 0x00, 0x00,};
const uint8_t SEG_PDC_VOR[]    =         {0x3f, 0x39, 0x00, 0x00,};
const uint8_t SEG_PDC_END[]    =         {0x3f, 0x3f, 0x39, 0x00,};
const uint8_t SEG_PDC_NOT[]    =         {0x3f, 0x3f, 0x3f, 0x39,};
const uint8_t SEG_PDC_STOP[]   =         {0x7f, 0x7f, 0x7f, 0x7f,};
const uint8_t SEG_VEH_STOP[]   =         {0x6d, 0x78, 0x3f, 0x73,};

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Pins der Soundmodule
#define Sound1 14
#define Sound2 32
#define Sound3 25
#define Sound4 33

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//allgemeine Variablen, die in verschiedenen Programmabläufen aufgerufen werden
int merker_PdcMode = 2;                                                                   // Wertespeicher für den PDC Modus. Ursprung ist mit 2 = normal
int distanz1 =0;                                                                          // erste errechnete Distanz zum Ultraschallsensor. Für die Geschwindigkeitserrechnung
int zeitx1 = 0;                                                                           // Deklaration der Variablen "zeitx"
int vResNull_230 = 0;                                                                     // Merker für die Geschwindigkeitsreduzierung


//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Programmabschnitt 1: Errechnung der ersten Distanz zum Objekt
int EntfernungsMessung1 (){

  long distanz1 = 0;                                                                      //Deklaration der Variablen "distanz1"
  long zeitx1 = 0;                                                                        //Deklaration der Variablen "zeitx"
 
  digitalWrite (trig, LOW);                                                               //setzt den Zustand von trig auf LOW
  delayMicroseconds(3);                                                                   //setzt eine Pause/Unterbrechung von 3 Mikrosekunden
  noInterrupts();                                                                         //verhindert eine Unterbrechung des Vorgangs
  digitalWrite(trig, HIGH);                                                               //setzt den Zustand von trig auf HIGH
  delayMicroseconds(10);                                                                  //setzt eine Pause/Unterbrechung von 10 Mikrosekunden
  digitalWrite(trig, LOW);                                                                //setzt den Zustand von trig auf LOW
  zeitx1 = pulseIn(echo, HIGH);
  interrupts();                                                                           //lässt Vorgangsunterbrechungen erneut zu
  Serial.print("Zeitx1 PulseIn:");
  Serial.print(zeitx1);
  Serial.println("");
  zeitx1 = (((zeitx1 * 344)/1000)/2);                                                     //vererrechnet den Wert der Zeit mit der Schallgeschwindigkeit nach der Raumtemperaur,
                                                                                          //dem Faktor für die Kommastelle und halbiert diesen wegen der doppelten strecke (hin+zurück)
  distanz1 = zeitx1;
  Serial.print("distanz1  Wert01:");                                                      //Ausgabe des Wertes über den seriellen Monitor
  Serial.print(distanz1);
  Serial.println("");
  return (distanz1);                                                                      //Ausgabe des Wertes für die Entfernung
}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Programmabschnitt: Programmcode PDC mit Wertebereichanpassung

int PdcMode (){
  if (merker_05 == 0 )                                                                    //einmalige Anzeige des Modus
  {
    Serial.println ("Modus: Optische akustische Signale (Park Distance Control)");        //Ausgabe des Modus über den seriellen Monitor
  }
  merker_05 = 1;                                                                          //Aktivierung des Merkers für den Programmabschnitt, damit er automatisch wiederholt wird
  merker_Up = 0;                                                                          // Nullsetzung der anderen Modusmerker
  merker_Down = 0;
  if(IRcode == button_05)
  {
    IRcode = 0x00000000;                                                                  //Zurücksetzen des IR-Codespeichers
    Serial.println ("IrCode gelöscht");
  }
  if (IRcode == button_ChannelPlus && merker_PdcMode <= 2)                                //Anpassung des Abstandes über Taster
    {
    merker_PdcMode ++;                                                                    //erhöhen des Abstandes
    Serial.print("Merker PDC-Mode:");                                                     
    Serial.print(merker_PdcMode);                                                         //Ausabe des aktuellen Abstandsmodus über den seriellen Monitor
    Serial.println("");
    IRcode = 0x00000000;                                                                  //Zurücksetzen des IR-Codespeichers
    }
  if (IRcode == button_ChannelMinus && merker_PdcMode >= 2)                               //Anpassung des Abstandes über Taster
    {
    merker_PdcMode --;                                                                    //verringern des Abstandes
    Serial.print("Merker PDC-Mode:");                                                     
    Serial.print(merker_PdcMode);                                                         //Ausabe des aktuellen Abstandsmodus über den seriellen Monitor
    Serial.println("");
    IRcode = 0x00000000;                                                                  //Zurücksetzen des IR-Codespeichers
    }
  distanz1 = EntfernungsMessung1  ();                                                     //errechnen der Distanz
  distanz1 = distanz1 / 10;

  Serial.print("Distanz 1 PDC ");
  Serial.print(distanz1);
  Serial.print("cm");
  Serial.println ("");

  if (merker_05 == 1 && merker_PdcMode == 1)                                              //Abfrage nach dem Distanzbereich 1 (nah)
    {
    PDC1 ();
    }
  if (merker_05 == 1 && merker_PdcMode == 2)                                              //Abfrage nach dem Distanzbereich 2 (mittel)
    {
    PDC2 ();
    }
  if (merker_05 == 1 && merker_PdcMode == 3)                                              //Abfrage nach dem Distanzbereich 3 (weit)
    {
    PDC3 ();
    }
  }


//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Programmabschnitt: Erfassen eines Infrarotsignals
int IRCodeAuslesen (){
if (irrecv.decode(&results))                                                              // Wenn ein IR-Signal empfangen wurde
  {
  IRcode = (results.value);                                                               // Das Empfangsignal in der Variable speichern

  if(IRcode == 0xFFFFFFFF)                                                                // Wenn eine Taste lange gedrückt wird, soll der Code gelöscht werden, um nicht im seriellen Monitor bzw. im Programm aufzutauchen
  {
    IRcode = 0x00000000;                                                                  // schreiben des default-Wertes in die Variable des IrCodes
  }
  Serial.print(IRcode, HEX);                                                              // Gebe empfangenen Code hexadezimal im seriellen Monitor aus
  Serial.println("");
  irrecv.resume();                                                                        // IR-Empfänger für den nächsten Wert bereit machen.
  }
}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Programmabschnitt: PDC Nah

int PDC1 ()
{
  if ((distanz1 <= 20) && (distanz1 >= 15))                                               // Abstandsbedingungen für Abstandsberech 1
  {
  display.setSegments(SEG_PDC_VOR);                                                       // Anzeige des Abstandes über das Display
  digitalWrite(Sound1, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.1
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound1, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls
  }
 
  else if ((distanz1 <= 15) && (distanz1 >= 10))                                          // Abstandsbedingung für Abstandsbereich 2
  {
  display.setSegments(SEG_PDC_END);                                                       // Anzeige des Abstandes über das Display
  digitalWrite(Sound2, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.2
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound2, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls
  }
 
  else if ((distanz1 <= 10) && (distanz1 >= 6))                                           // Abstandsbedingungen für Abstandsberech 3
  {
  display.setSegments(SEG_PDC_NOT);                                                       // Anzeige des Abstandes über das Display
  digitalWrite(Sound3, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.3
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound3, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls
  }
 
  else if (distanz1 <= 5)                                                                 // Abstandsbedingungen für Abstandsberech 4
  {
  display.setSegments(SEG_PDC_STOP);                                                      // Anzeige des Abstandes über das Display
  digitalWrite(Sound4, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.4
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound4, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls
  }
 
  else                                                                                    // Abstandsbedingungen für Abstandsberech 0
  {
  display.setSegments(SEG_PDC_NORMAL);                                                    // Anzeige des Abstandes über das Display
  }  
}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Programmabschnitt: PDC Mittel

int PDC2 ()
{
  if ((distanz1 <= 55) && (distanz1 >= 51))                                               // Abstandsbedingungen für Abstandsberech 1
  {
  display.setSegments(SEG_PDC_VOR);                                                       // Anzeige des Abstandes über das Display
  digitalWrite(Sound1, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.1
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound1, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls   
  }
 
  else if ((distanz1 <= 50) && (distanz1 >= 46))                                          // Abstandsbedingungen für Abstandsberech 2
  {
  display.setSegments(SEG_PDC_END);                                                       // Anzeige des Abstandes über das Display
  digitalWrite(Sound2, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.2
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound2, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls   
  }
 
  else if ((distanz1 <= 45) && (distanz1 >= 41))                                          // Abstandsbedingungen für Abstandsberech 3
  {
  display.setSegments(SEG_PDC_NOT);                                                       // Anzeige des Abstandes über das Display
  digitalWrite(Sound3, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.3
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound3, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls  
  }
 
  else if (distanz1 <= 40)                                                                // Abstandsbedingungen für Abstandsberech 4
  {
  display.setSegments(SEG_PDC_STOP);                                                      // Anzeige des Abstandes über das Display
  digitalWrite(Sound4, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.4
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound4, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls
  }
 
  else                                                                                    // Abstandsbedingungen für Abstandsberech 0
  {
  display.setSegments(SEG_PDC_NORMAL);                                                    // Anzeige des Abstandes über das Display      
  }
}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Programmabschnitt: PDC Weit

int PDC3 ()
{
  if ((distanz1 <= 85) && (distanz1 >= 81))                                               // Abstandsbedingungen für Abstandsberech 1
  {
  display.setSegments(SEG_PDC_VOR);                                                       // Anzeige des Abstandes über das Display
  digitalWrite(Sound1, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.1
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound1, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls
  }
 
  else if ((distanz1 <= 80) && (distanz1 >= 76))                                          // Abstandsbedingungen für Abstandsberech 2
  {
  display.setSegments(SEG_PDC_END);                                                       // Anzeige des Abstandes über das Display
  digitalWrite(Sound2, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.2
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound2, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls
  }
 
  else if ((distanz1 <= 75) && (distanz1 >= 71))                                          // Abstandsbedingungen für Abstandsberech 3
  {
  display.setSegments(SEG_PDC_NOT);                                                       // Anzeige des Abstandes über das Display
  digitalWrite(Sound3, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.3
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound3, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls
  }
 
  else if (distanz1 <= 70)                                                                // Abstandsbedingungen für Abstandsberech 4
  {
  display.setSegments(SEG_PDC_STOP);                                                      // Anzeige des Abstandes über das Display
  digitalWrite(Sound4, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.4
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound4, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls
  }
 
  else                                                                                    // Abstandsbedingungen für Abstandsberech 0
  {
  display.setSegments(SEG_PDC_NORMAL);                                                    // Anzeige des Abstandes über das Display
  }
}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Programmabschnitt 7: Fahrzeugstopp
int StopMode (){
    merker_Up   = 0;                                                                      // Zurücksetzen der Modusmerker
    merker_Down = 0;
    merker_05   = 0;
    Serial.println ("Power Button gedrückt, Fahrzeugfunktionen Stopp");                   // Ausgabe über den seriellen Monitor
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
    display.setSegments (SEG_VEH_STOP);
  }

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void setup() {
//Infrarotempfänger
irrecv.enableIRIn();                                                                      // Empfänger wird ausgeführt

//Display TM1637
display.setBrightness(7);

//Ultraschallsensor
pinMode (echo     , INPUT );                                                              // festlegen des Pins am Ultraschallsensor als Eingang
pinMode (trig     , OUTPUT);                                                              // festlegen des Pins am Ultraschallsensor als Ausgang

//Soundmodule
pinMode (Sound1     , OUTPUT);                                                            // festlegen der Pins der Soundmodule als Ausgänge
pinMode (Sound2     , OUTPUT);
pinMode (Sound3     , OUTPUT);
pinMode (Sound4     , OUTPUT);
}

void loop() {
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Modus: PDC mit veränderbarem Abstandsbereich

if (IRcode == button_05 || merker_05 == 1)                                                // Modus: PDC mit veränderbarem Abstandsbereich
  {
  PdcMode ();
  }

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Modus: allgemeiner Funktionsstopp

if (IRcode == button_Power)                                                               // Bedingung für Funktion: Allgemeiner Fahrzeugstopp
  {
  StopMode ();
  }
}

Die Bedienung des Fahrzeugmodells wird mit dem Infrarothandsender ausgeführt. Durch Druck auf die „Hoch“ - Taste fährt das Fahrzeug mit 50% der Maximalgeschwindigkeit nach vorne los. Durch erneutes Betätigen der „Hoch“ - Taste lässt sich die Geschwindigkeit des Fahrzeuges in 10er Schritten bis zum Maximum von 100% erhöhen. Wird die „Runter“ -Taste auf dem Infrarothandsender betätigt, wird die Geschwindigkeit in 10er Schritten bis zum Stillstand des Fahrzeugs reduziert. Das Fahrzeug lässt sich durch den Druck auf Die „Power“ - Taste auch sofort stoppen. Wenn das Fahrzeug stillsteht und die „Runter“ - Taste betätigt wird, fährt es mit 50% der Maximalgeschwindigkeit nach hinten los. Auch hier wird durch erneutes Betätigen der „Runter“ - Taste die Geschwindigkeit erhöht, durch betätigen der „Hoch“ - Taste die Geschwindigkeit verringert und mit der „Power“ - Taste die Fahrtbewegung gestoppt.


Hier (Datei "Vorlage_Fahrzeugverfahren_vor_zur_ck.ino") befindet sich der Programmcode zu der Funktion:

//Infrarotsensor
#include <IRremoteESP8266.h>                                                              // Bibliothek zum Empfang von Infrarotsignalen
#include <IRrecv.h>                                                                       // Bibliothek zum Empfang von Infrarotsignalen
#include <IRutils.h>                                                                      // Bibliothek für Funktionen nach Infrarotempfang
#define RECV_PIN  34                                                                      // Pin, an dem der Pin des IR-Empfängers angeschlossen ist
IRrecv irrecv(RECV_PIN);                                                                  // Eingangsbestimmung für den Infrarot-Datenstrom
decode_results results;                                                                   // Dekodierung in Datei schreiben

//Hexcodes für die Tasten des Infrarothandsenders
// Angabe von '0x' vor dem eigentlichen Hexcode
//         Bezeichnung                  HEX-Code
int button_Power          =             0xECDF8084;                                       // zurücksetzen auf den ursprungszustand
int button_Down           =             0x7F984248;                                       // keine Zuordnung in diesem Programm
int button_Up             =             0xC5F76D04;                                       // keine Zuordnung in diesem Programm
//int button_01             =             0x3138F3E0;                                       // keine Zuordnung in diesem Programm
//int button_02             =             0xBF33DC80;                                       // keine Zuordnung in diesem Programm
//int button_03             =             0xABB78D20;                                       // keine Zuordnung in diesem Programm
//int button_04             =             0x4A86A8C0;                                       // keine Zuordnung in diesem Programm
int button_05             =             0xC0134580;                                       // Modus PDC optische akustische Signale
//int button_06             =             0xBA1256C4;                                       // keine Zuordnung in diesem Programm
//int button_07             =             0x52A2DA24;                                       // keine Zuordnung in diesem Programm
//int button_08             =             0xB74C8420;                                       // keine Zuordnung in diesem Programm
//int button_09             =             0xE3172C20;                                       // keine Zuordnung in diesem Programm
//int button_VolumePlus     =             0xF62981E4;                                       // keine Zuordnung in diesem Programm
//int button_00             =             0x2F9EF384;                                       // keine Zuordnung in diesem Programm
int button_ChannelPlus    =             0x9C7C29E0;                                       // Änderung Wertebereich für optische akustische Signale nach oben
//int button_VolumeMinus    =             0x973C68E0;                                       // keine Zuordnung in diesem Programm
//int button_Enter          =             0x3C1BB180;                                       // keine Zuordnung in diesem Programm
int button_ChannelMinus   =             0x1B433B24;                                       // Änderung Wertebereich für optische akustische Signale nach unten
int IRcode = 0x00000000;                                                                  // variable für den Empfangenen Tastencode
int merker_Power          =  0;
int merker_Down           =  0;
int merker_Up             =  0;
//int merker_01             =  0;
//int merker_02             =  0;
//int merker_03             =  0;
//int merker_04             =  0;
int merker_05             =  0;
//int merker_06             =  0;
//int merker_07             =  0;
//int merker_08             =  0;
//int merker_09             =  0;
//int merker_VolumePlus     =  0;
//int merker_00             =  0;
int merker_ChannelPlus    =  0;
//int merker_VolumeMinus    =  0;
//int merker_Enter          =  0;
int merker_ChannelMinus   =  0;


// Motortreiber L298N
#define MotV 27
#define MotR 26
#define MotEna 12

//PWM Motortreiber
int Freq = 30000;
int Res = 8;
int PwmChannelMotEna = 2;
int DutyCycleMotEna = 0;                                                                  // MaximalWert: 250; Minimalwet 160;
int DutyCycleNull = 0;

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//allgemeine Variablen, die in verschiedenen Programmabläufen aufgerufen werden
int distanz1 =0;                                                                          // erste errechnete Distanz zum Ultraschallsensor. Für die Geschwindigkeitserrechnung
int zeitx1 = 0;                                                                           // Deklaration der Variablen "zeitx"

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Modus: Fahrzeug fährt Rückwärts

int FahrzeugRueckwaerts()
{
  if (merker_Down == 0 )                                                                  // einmalige Anzeige des Modus
    {
    Serial.println ("Modus: Fahrzeug fährt Rückwärts");                                   // Ausgabe des Modus über den seriellen Monitor
                                                                                          // Festlegen des Startwerts, Mitte zwischen Minimum und Maximum
    DutyCycleMotEna = 200;                                                                // Minimal 160, maximal 255 bei DutyCycleMotEna
    ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                        // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
    digitalWrite (MotV , LOW  );                                                          // Schreiben der Drehrichtung des Motors
    digitalWrite (MotR , HIGH );
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
    }
  merker_Down = 1;                                                                        // Aktivierung des Merkers für den Programmabschnitt, damit er automatisch wiederholt wird
  merker_Up = 0;                                                                          // Nullsetzung der anderen Modusmerker
  ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                          // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
  if (IRcode == button_Down && DutyCycleMotEna < 241)                                     // Bedingungen für die Geschwindigkeitserhöhung
    {
    DutyCycleMotEna = DutyCycleMotEna +10;                                                // Erhöhung der Geschwindigkeit
    Serial.print ("DutyCycleMotEna Anhebung auf:");                                       // Ausgabe über den seriellen Monitor
    Serial.print (DutyCycleMotEna);
    Serial.println("");
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
    }
  if (IRcode == button_Up && DutyCycleMotEna > 169)                                       // Bedingung für die Geschwindigkeitsverringerung
    {
    DutyCycleMotEna = DutyCycleMotEna -10;                                                // Verringerung der Geschwindigkeit
    Serial.print ("DutyCycleMotEna Senkung auf:");                                        // Ausgabe über den seriellen Monitor
    Serial.print (DutyCycleMotEna);
    Serial.println("");
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
    }
  if (IRcode == button_Up && DutyCycleMotEna == 160)                                      // Stoppen des Fahrzeugs bei minimalem Geschwindigkeitswert
    {
    IRcode = button_Power;                                                                // Ansteuern des Stoppmodus
    }
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Programmabschnitt 7: Fahrzeugstopp
int StopMode (){
    merker_Up   = 0;                                                                      // Zurücksetzen der Modusmerker
    merker_Down = 0;
    merker_05   = 0;
    Serial.println ("Power Button gedrückt, Fahrzeugfunktionen Stopp");                   // Ausgabe über den seriellen Monitor
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
    DutyCycleMotEna = 0;
    ledcWrite (PwmChannelMotEna, DutyCycleNull);                                          // Nullsetzen des PWM-Ausgangs
    digitalWrite (MotV , LOW );                                                           // Nullsetzen der Motordrehrichtung
    digitalWrite (MotR , LOW );
  }


//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Modus: Fahrzeug fährt vorwärts

int FahrzeugVorwaerts (){
  if (merker_Up == 0 )                                                                    // einmalige Anzeige des Modus
  {
    Serial.println ("Modus: Fahrzeug fährt vorwärts");                                    // Ausgabe des Modus über den seriellen Monitor
                                                                                          // Festlegen des Startwerts, Mitte zwischen Minimum und Maximum
    DutyCycleMotEna = 200;                                                                // Minimal 160, maximal 255 bei DutyCycleMotEna
    digitalWrite (MotV , HIGH);                                                           // Schreiben der Drehrichtung des Motors
    digitalWrite (MotR , LOW );
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
  }
  merker_Up = 1;                                                                          // Aktivierung des Merkers für den Programmabschnitt, damit er automatisch wiederholt wird
  merker_Down = 0;                                                                        // Nullsetzung der anderen Modusmerker
  ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                          // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang

  if (IRcode == button_Up && DutyCycleMotEna < 241)                                       // Bedingungen für die Geschwindigkeitserhöhung
    {
    DutyCycleMotEna = DutyCycleMotEna +10;                                                // Erhöhung der Geschwindigkeit
    Serial.print ("DutyCycleMotEna Anhebung auf:");                                       // Ausgabe über den seriellen Monitor
    Serial.print (DutyCycleMotEna);
    Serial.println("");
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
    }
  if (IRcode == button_Down && DutyCycleMotEna >169)                                      // Bedingung für die Geschwindigkeitsverringerung
    {
    DutyCycleMotEna = DutyCycleMotEna -10;                                                // Verringerung der Geschwindigkeit
    Serial.print ("DutyCycleMotEna Senkung auf:");                                        // Ausgabe über den seriellen Monitor
    Serial.print (DutyCycleMotEna);
    Serial.println("");
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
    }
  if (IRcode == button_Down && DutyCycleMotEna == 160)                                    // Stoppen des Fahrzeugs bei minimalem Geschwindigkeitswert
    {
    IRcode = button_Power;                                                                // Ansteuern des Stoppmodus
    }
}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Programmabschnitt: Erfassen eines Infrarotsignals
int IRCodeAuslesen (){
if (irrecv.decode(&results))                                                              // Wenn ein IR-Signal empfangen wurde
  {
  IRcode = (results.value);                                                               // Das Empfangsignal in der Variable speichern

  if(IRcode == 0xFFFFFFFF)                                                                // Wenn eine Taste lange gedrückt wird, soll der Code gelöscht werden, um nicht im seriellen Monitor bzw. im Programm aufzutauchen
  {
    IRcode = 0x00000000;                                                                  // schreiben des default-Wertes in die Variable des IrCodes
  }
  Serial.print(IRcode, HEX);                                                              // Gebe empfangenen Code hexadezimal im seriellen Monitor aus
  Serial.println("");
  irrecv.resume();                                                                        // IR-Empfänger für den nächsten Wert bereit machen.
  }
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void setup() {
//Infrarotempfänger
irrecv.enableIRIn();                                    // Empfänger wird ausgeführt


//L298N
pinMode (MotV     , OUTPUT);                                                              // festlegen des Pins am L298N als Ausgang
pinMode (MotR     , OUTPUT);                                                              // festlegen des Pins am L298N als Ausgang
pinMode (MotEna   , OUTPUT);                                                              // festlegen des Pins am L298N als Ausgang

//PWM
ledcSetup (PwmChannelMotEna, Freq, Res);                                                  // PWM-Kanal Einstellung
ledcAttachPin (MotEna, PwmChannelMotEna);                                                 // Definition des PWM-Kanals auf den Pin

Serial.begin(115200);                                                                     // Seriellen Monitor mit einer Baudrate von 115200 starten
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void loop() {
IRCodeAuslesen      ();
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Modus: Fahrzeug fährt vorwärts

if ((IRcode == button_Up && merker_Down == 0)|| merker_Up == 1)                           // Bedingungen für Modus: Fahrzeug fährt vorwärts
{
  FahrzeugVorwaerts();
}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Modus: Fahrzeug fährt rückwärts

if ((IRcode == button_Down && merker_Up == 0)|| merker_Down == 1 )                        // Bedingungen für Modus: Fahrzeug fährt rückwärts
{
  FahrzeugRueckwaerts();
}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Modus: allgemeiner Funktionsstopp

if (IRcode == button_Power)                                                               // Bedingung für Funktion: Allgemeiner Fahrzeugstopp
  {
  StopMode ();
  }


}

Die Funktion des vor- und zurückfahrens wird um einen Positioniermodus erweitert. Wenn das Fahrzeug vorwärts oder rückwärts fährt, wird auf dem Display mit Decoder die Distanz zu dem nächsten erfassten Objekt ausgegeben. In der Vorwärtsfahrt wird die Distanz zum Objekt genutzt, um das Fahrzeug zu einem sicheren Halt zu bringen. Die Geschwindigkeit wird nach und nach bis zum Stillstand vor dem Objekt reduziert. Sobald das Fahrzeug steht, wechselt es in den Positioniermodus. Dieser Modus erlaubt es, die Distanz zum erkannten Objekt durch einmaligen Druck auf die „Channel Plus“ - bzw. „Channel Minus“ - Taste um 5 Centimeter zu verändern. Das Fahrzeug verfährt nach Betätigung selbstständig auf den neuen Wert und hält an. Diesen Modus kann man nur durch Betätigung der „Power“ - Taste verlassen.  


Hier (Datei "Vorlage_Fahrzeugverfahren_VZ_Posi.ino") der zugehörige Programmcode:



//Infrarotsensor
#include <IRremoteESP8266.h>                                                              // Bibliothek zum Empfang von Infrarotsignalen
#include <IRrecv.h>                                                                       // Bibliothek zum Empfang von Infrarotsignalen
#include <IRutils.h>                                                                      // Bibliothek für Funktionen nach Infrarotempfang
#define RECV_PIN  34                                                                      // Pin, an dem der Pin des IR-Empfängers angeschlossen ist
IRrecv irrecv(RECV_PIN);                                                                  // Eingangsbestimmung für den Infrarot-Datenstrom
decode_results results;                                                                   // Dekodierung in Datei schreiben


// Angabe von '0x' vor dem eigentlichen Hexcode
//         Bezeichnung                  HEX-Code
int button_Power          =             0xECDF8084;                                       // zurücksetzen auf den ursprungszustand
int button_Down           =             0x7F984248;                                       // keine Zuordnung in diesem Programm
int button_Up             =             0xC5F76D04;                                       // keine Zuordnung in diesem Programm
//int button_01             =             0x3138F3E0;                                       // keine Zuordnung in diesem Programm
//int button_02             =             0xBF33DC80;                                       // keine Zuordnung in diesem Programm
//int button_03             =             0xABB78D20;                                       // keine Zuordnung in diesem Programm
//int button_04             =             0x4A86A8C0;                                       // keine Zuordnung in diesem Programm
int button_05             =             0xC0134580;                                       // Modus PDC optische akustische Signale
//int button_06             =             0xBA1256C4;                                       // keine Zuordnung in diesem Programm
//int button_07             =             0x52A2DA24;                                       // keine Zuordnung in diesem Programm
//int button_08             =             0xB74C8420;                                       // keine Zuordnung in diesem Programm
//int button_09             =             0xE3172C20;                                       // keine Zuordnung in diesem Programm
//int button_VolumePlus     =             0xF62981E4;                                       // keine Zuordnung in diesem Programm
//int button_00             =             0x2F9EF384;                                       // keine Zuordnung in diesem Programm
int button_ChannelPlus    =             0x9C7C29E0;                                       // Änderung Wertebereich für optische akustische Signale nach oben; Fahrzeug in Positionierung nach vorne verfahren
//int button_VolumeMinus    =             0x973C68E0;                                       // keine Zuordnung in diesem Programm
//int button_Enter          =             0x3C1BB180;                                       // keine Zuordnung in diesem Programm
int button_ChannelMinus   =             0x1B433B24;                                       // Änderung Wertebereich für optische akustische Signale nach unten; Fahrzeug in Positionierung nach hinten verfahren
int IRcode = 0x00000000;                                                                  // variable für den Empfangenen Tastencode
int merker_Power          =  0;
int merker_Down           =  0;
int merker_Up             =  0;
//int merker_01             =  0;
//int merker_02             =  0;
//int merker_03             =  0;
//int merker_04             =  0;
int merker_05             =  0;
//int merker_06             =  0;
//int merker_07             =  0;
//int merker_08             =  0;
//int merker_09             =  0;
//int merker_VolumePlus     =  0;
//int merker_00             =  0;
int merker_ChannelPlus    =  0;
//int merker_VolumeMinus    =  0;
//int merker_Enter          =  0;
int merker_ChannelMinus   =  0;


//Ultraschallsensor
#define echo 15                                                                           //Anschluss ECHO vom HC-SR04 wurde für PIN 15 festgelegt
#define trig 18                                                                           //Anschluss TRIG vom HC-SR04 wurde für PIN 18 festgelegt


//Display mit Controller
#include <TM1637TinyDisplay.h>                                                            // Bibliothek für die 7- Segment Anzeige
#define CLK 21                                                                            //Anschluss CLK von der 7- Segment Anzeige wurde für PIN 21 festgelegt
#define DIO 19                                                                            //Anschluss DIO von der 7- Segment Anzeige wurde für PIN 19 festgelegt
TM1637TinyDisplay display(CLK, DIO);
const uint8_t SEG_PDC_NORMAL[]  =         {0x39, 0x00, 0x00, 0x00,};
const uint8_t SEG_PDC_VOR[]     =         {0x3f, 0x39, 0x00, 0x00,};
const uint8_t SEG_PDC_END[]     =         {0x3f, 0x3f, 0x39, 0x00,};
const uint8_t SEG_PDC_NOT[]     =         {0x3f, 0x3f, 0x3f, 0x39,};
const uint8_t SEG_PDC_STOP[]    =         {0x7f, 0x7f, 0x7f, 0x7f,};
const uint8_t SEG_Modus_MS[]    =         {0x54, 0x44, 0x52, 0x6d,};
const uint8_t SEG_Modus_kmh[]   =         {0x78, 0x54, 0x44, 0x74,};
const uint8_t SEG_VEH_STOP[]    =         {0x6d, 0x78, 0x3f, 0x73,};
const uint8_t SEG_VEH_VPlus[]   =         {0x1c, 0x46, 0x40, 0x00,};
const uint8_t SEG_VEH_VMinus[]  =         {0x1c, 0x40, 0x40, 0x00,};

//Pins der Soundmodule
#define Sound1 12
#define Sound2 13
#define Sound3 14
#define Sound4 27

// Motortreiber L298N
#define MotV 27
#define MotR 26
#define MotEna 12

//PWM Motortreiber
int Freq = 30000;
int Res = 8;
int PwmChannelMotEna = 2;
int DutyCycleMotEna = 0;                                                                  // MaximalWert: 250; Minimalwet 160;
int DutyCycleNull = 0;

//allgemeine Variablen, die in verschiedenen Programmabläufen aufgerufen werden
int merker_PdcMode = 2;                                                                   //Wertespeicher für den PDC Modus. Ursprung ist mit 2 = normal
int distanz1 =0;                                                                          //erste errechnete Distanz zum Ultraschallsensor. Für die Geschwindigkeitserrechnung
int zeitx1 = 0;                                                                           //Deklaration der Variablen "zeitx"
int vResNull_230 = 0;                                                                     //Merker für die Geschwindigkeitsreduzierung
int vResNull_220 = 0;
int vResNull_210 = 0;
int vResNull_200 = 0;
int vResNull_190 = 0;
int vResNull_180 = 0;
int vResNull_170 = 0;
int vResNull_160 = 0;
int merker_positionierungsmodi = 0;
int merker_Verfahrweg = 0;

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Programmabschnitt 1: Errechnung der ersten Distanz zum Objekt
int EntfernungsMessung1 (){

  long distanz1 = 0;                                                                      //Deklaration der Variablen "distanz1"
  long zeitx1 = 0;                                                                        //Deklaration der Variablen "zeitx"
 
  digitalWrite (trig, LOW);                                                               //setzt den Zustand von trig auf LOW
  delayMicroseconds(3);                                                                   //setzt eine Pause/Unterbrechung von 3 Mikrosekunden
  noInterrupts();                                                                         //verhindert eine Unterbrechung des Vorgangs
  digitalWrite(trig, HIGH);                                                               //setzt den Zustand von trig auf HIGH
  delayMicroseconds(10);                                                                  //setzt eine Pause/Unterbrechung von 10 Mikrosekunden
  digitalWrite(trig, LOW);                                                                //setzt den Zustand von trig auf LOW
  zeitx1 = pulseIn(echo, HIGH);
  interrupts();                                                                           //lässt Vorgangsunterbrechungen erneut zu
//  Serial.print("Zeitx1 PulseIn:");
//  Serial.print(zeitx1);
//  Serial.println("");
  zeitx1 = (((zeitx1 * 344)/1000)/2);                                                     //vererrechnet den Wert der Zeit mit der Schallgeschwindigkeit nach der Raumtemperaur,
                                                                                          //dem Faktor für die Kommastelle und halbiert diesen wegen der doppelten strecke (hin+zurück)
  distanz1 = zeitx1;
//  Serial.print("distanz1  Wert01:");                                                      //Ausgabe des Wertes über den seriellen Monitor
//  Serial.print(distanz1);
//  Serial.println("");
  return (distanz1);                                                                      //Ausgabe des Wertes für die Entfernung
}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Programmabschnitt 2: Erfassen eines Infrarotsignals
int IRCodeAuslesen (){
if (irrecv.decode(&results))                                                              //Wenn ein IR-Signal empfangen wurde
  {
  IRcode = (results.value);                                                               //Das Empfangsignal in der Variable speichern

  Serial.print(IRcode, HEX);                                                              //Gebe empfangenen Code hexadezimal im seriellen Monitor aus
  Serial.println("");
  irrecv.resume();                                                                        //IR-Empfänger für den nächsten Wert bereit machen.
  if(IRcode == 0xFFFFFFFF)
  {
    IRcode = 0x00000000;
  }
  }
}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Programmabschnitt 7: Fahrzeugstopp
int StopMode (){
    merker_Up   = 0;                                                                      // Zurücksetzen der Modusmerker
    merker_Down = 0;
    merker_05   = 0;
    Serial.println ("Power Button gedrückt, Fahrzeugfunktionen Stopp");                   // Ausgabe über den seriellen Monitor
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
    DutyCycleMotEna = 200;
    ledcWrite (PwmChannelMotEna, DutyCycleNull);                                          // Nullsetzen des PWM-Ausgangs
    digitalWrite (MotV , LOW );                                                           // Nullsetzen der Motordrehrichtung
    digitalWrite (MotR , LOW );
    display.setSegments (SEG_VEH_STOP);
    vResNull_230 = 0;                                                                     // Merker für die Geschwindigkeitsreduzierung
    vResNull_220 = 0;
    vResNull_210 = 0;
    vResNull_200 = 0;
    vResNull_190 = 0;
    vResNull_180 = 0;
    vResNull_170 = 0;
    vResNull_160 = 0;
    merker_positionierungsmodi = 0;
    merker_ChannelPlus = 0;
    merker_ChannelMinus = 0;
    
  }

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Modus: Fahrzeug fährt vorwärts

int FahrzeugVorwaerts (){
  if (merker_Up == 0 )                                                                    // einmalige Anzeige des Modus
  {
    Serial.println ("Modus: Fahrzeug fährt vorwärts");                                    // Ausgabe des Modus über den seriellen Monitor
                                                                                          // Festlegen des Startwerts, Mitte zwischen Minimum und Maximum
    DutyCycleMotEna = 200;                                                                // Minimal 160, maximal 255 bei DutyCycleMotEna
    digitalWrite (MotV , HIGH);                                                           // Schreiben der Drehrichtung des Motors
    digitalWrite (MotR , LOW );
    display.setSegments (SEG_VEH_VPlus);
    delay(500);
    display.clear();
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
  }
  merker_Up = 1;                                                                          // Aktivierung des Merkers für den Programmabschnitt, damit er automatisch wiederholt wird
  merker_Down = 0;                                                                        // Nullsetzung der anderen Modusmerker
  ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                          // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
  distanz1 = EntfernungsMessung1   ();                                                    // errechnen der Distanz
  distanz1 = distanz1 / 10;                                                               // Umformen der Distanz zu Cm
//  Serial.print("Distanz zu Objekt ");                                                   // Ausgabe der Distanz über den seriellen Monitor
//  Serial.print(distanz1);
//  Serial.print("cm");
//  Serial.println ("");
  display.showNumber (distanz1);                                                          // Ausgabe des Wertes der Distanz auf dem Display mit Decoder
  if (IRcode == button_Up && DutyCycleMotEna < 241 && distanz1 >= 50)                     // Bedingungen für die Geschwindigkeitserhöhung
    {
    DutyCycleMotEna = DutyCycleMotEna +10;                                                // Erhöhung der Geschwindigkeit über den Wert des DutyCycles
    Serial.print ("DutyCycleMotEna Anhebung auf:");                                       // Ausgabe über den seriellen Monitor
    Serial.print (DutyCycleMotEna);
    Serial.println("");
    vResNull_230 = 0;                                                                     //Merker für die Geschwindigkeitsreduzierung
    vResNull_220 = 0;
    vResNull_210 = 0;
    vResNull_200 = 0;
    vResNull_190 = 0;
    vResNull_180 = 0;
    vResNull_170 = 0;
    vResNull_160 = 0;
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
    }
  if (IRcode == button_Down && DutyCycleMotEna >169)                                      // Bedingung für die Geschwindigkeitsverringerung
    {
    DutyCycleMotEna = DutyCycleMotEna -10;                                                // Verringerung der Geschwindigkeit über den Wert des DutyCycles
    Serial.print ("DutyCycleMotEna Senkung auf:");                                        // Ausgabe über den seriellen Monitor
    Serial.print (DutyCycleMotEna);
    Serial.println("");
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
    }
  if (IRcode == button_Down && DutyCycleMotEna == 160)                                    // Stoppen des Fahrzeugs bei minimalem Geschwindigkeitswert
    {
    IRcode = button_Power;                                                                // Ansteuern des Stoppmodus
    }
//Abschnitt Geschwindigkeitsreduzierung bei Objekterkennung
  if (distanz1 < 50 && DutyCycleMotEna > 230&& vResNull_230 == 0 && merker_positionierungsmodi == 0)
    {                                                                                     // Reduzierung schrittweise
    DutyCycleMotEna = 230;                                                                // Schreiben des kleineren Wertes in den DutyCycle
    ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                        // Schreiben des DutyCycles in den Ausgang
    Serial.println ("eduzierung Geschwindigkeit Näherung zu Objekt V230");                // Ausgabe über den seriellen Monitor
    vResNull_230 = 1;
    }
  if (distanz1 < 47 && DutyCycleMotEna > 220 && vResNull_220 == 0 && merker_positionierungsmodi == 0)
    {                                                                                     // Reduzierung schrittweise
    DutyCycleMotEna = 220;                                                                // Schreiben des kleineren Wertes in den DutyCycle
    ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                        // Schreiben des DutyCycles in den Ausgang
    Serial.println ("eduzierung Geschwindigkeit Näherung zu Objekt V220");                // Ausgabe über den seriellen Monitor
    vResNull_220 = 1;
    }
  if (distanz1 < 44 && DutyCycleMotEna > 210 && vResNull_210 == 0 && merker_positionierungsmodi == 0)
    {                                                                                     // Reduzierung schrittweise
    DutyCycleMotEna = 210;                                                                // Schreiben des kleineren Wertes in den DutyCycle
    ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                        // Schreiben des DutyCycles in den Ausgang
    Serial.println ("eduzierung Geschwindigkeit Näherung zu Objekt V210");                // Ausgabe über den seriellen Monitor
    vResNull_210 = 1;
    }
  if (distanz1 < 41 && DutyCycleMotEna > 200 && vResNull_200 == 0 && merker_positionierungsmodi == 0)
    {                                                                                     // Reduzierung schrittweise
    DutyCycleMotEna = 200;                                                                // Schreiben des kleineren Wertes in den DutyCycle
    ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                        // Schreiben des DutyCycles in den Ausgang
    Serial.println ("eduzierung Geschwindigkeit Näherung zu Objekt V200");                // Ausgabe über den seriellen Monitor
    vResNull_200 = 1;
    }
  if (distanz1 < 38 && DutyCycleMotEna > 190 && vResNull_190 == 0 && merker_positionierungsmodi == 0)
    {                                                                                     // Reduzierung schrittweise
    DutyCycleMotEna = 190;                                                                // Schreiben des kleineren Wertes in den DutyCycle
    ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                        // Schreiben des DutyCycles in den Ausgang
    Serial.println ("eduzierung Geschwindigkeit Näherung zu Objekt V190");                // Ausgabe über den seriellen Monitor
    vResNull_190 = 1;
    }
  if (distanz1 < 35 && DutyCycleMotEna > 180 && vResNull_180 == 0 && merker_positionierungsmodi == 0)
    {                                                                                     // Reduzierung schrittweise
    DutyCycleMotEna = 180;                                                                // Schreiben des kleineren Wertes in den DutyCycle
    ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                        // Schreiben des DutyCycles in den Ausgang
    Serial.println ("eduzierung Geschwindigkeit Näherung zu Objekt V180");                // Ausgabe über den seriellen Monitor
    vResNull_180 = 1;
    }
  if (distanz1 < 32 && DutyCycleMotEna > 170 && vResNull_170 == 0 && merker_positionierungsmodi == 0)
    {                                                                                     // Reduzierung schrittweise
    DutyCycleMotEna = 170;                                                                // Schreiben des kleineren Wertes in den DutyCycle
    ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                        // Schreiben des DutyCycles in den Ausgang
    Serial.println ("eduzierung Geschwindigkeit Näherung zu Objekt V170");                // Ausgabe über den seriellen Monitor
    vResNull_170 = 1;
    }
  if (distanz1 < 29 && DutyCycleMotEna > 160 && vResNull_160 == 0 && merker_positionierungsmodi == 0)
    {                                                                                     // Reduzierung schrittweise
    DutyCycleMotEna = 160;                                                                // Schreiben des kleineren Wertes in den DutyCycle
    ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                        // Schreiben des DutyCycles in den Ausgang
    Serial.println ("eduzierung Geschwindigkeit Näherung zu Objekt V160");                // Ausgabe über den seriellen Monitor
    vResNull_160 = 1;
    }
  if (distanz1 < 26 && DutyCycleMotEna == 160 && vResNull_160 == 1 && merker_positionierungsmodi == 0)
    {                                                                                     // Bis zum Stillstand vor dem Objekt und dem Wechsel in den Abstandsmodus
    DutyCycleMotEna = 0;                                                                  // Schreiben des kleineren Wertes in den DutyCycle
    ledcWrite (PwmChannelMotEna, DutyCycleNull);                                          // Schreiben des DutyCycles in den Ausgang
    delay(1000);
    digitalWrite (MotV , LOW );                                                           // zurücksetzen der Drehrichtung des Motors
    digitalWrite (MotR , LOW  );
    merker_positionierungsmodi = 1;                                                       // Aktivieren des Merkers für die Positionierung
    merker_Verfahrweg = distanz1;
    Serial.println("Fahrzeug gestoppt, Positioniermodus aktiviert");                      // Ausgabe über den seriellen Monitor
    }    
}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Modus: Positionierung vor Objekt stehend

int Positionierung (){
    distanz1 = EntfernungsMessung1   ();                                                  // errechnen der Distanz
    distanz1 = distanz1 / 10;                                                             // Umrechnen des Wertes in Cm
    display.showNumber (distanz1);                                                        // Ausgabe des wertes auf dem Display mit Decoder
    if (IRcode == button_ChannelPlus || merker_ChannelPlus ==1)                           // Bedingung für das Verfahren nach vorne
      {
      if (merker_ChannelPlus == 0)                                                        // Einmal Ausführung des Schreibens der Motorwerte
        {
        digitalWrite (MotV , HIGH );                                                      // Schreiben der Drehrichtung des Motors
        digitalWrite (MotR , LOW  );
        DutyCycleMotEna = 200;                                                            // Starten mit einem initialwert, damit der motor sich dreht
        ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                    // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
        delay(20);
        DutyCycleMotEna = 180;                                                            // Schrittweises Absenken der Drehgeschwindigkeit
        ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                    // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
        delay(20);
        DutyCycleMotEna = 160;                                                            // Bis zur Minimalfrequenz
        ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                    // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
        merker_ChannelPlus = 1;
        merker_Verfahrweg = distanz1;
        merker_Verfahrweg = merker_Verfahrweg -5;
        Serial.print ("Distanz 1 ");
        Serial.println (distanz1);
        Serial.print ("merker_Verfahrweg ");
        Serial.println (merker_Verfahrweg);
        Serial.println ("ChannelPlus betätigt, Anpassung nach vorne angefordert");
        IRcode = 0x00000000;                                                              // Zurücksetzen des IR-Codespeichers
        }
      if (distanz1 < merker_Verfahrweg)
        {
        digitalWrite (MotV , LOW  );                                                      // Schreiben der Drehrichtung des Motors
        digitalWrite (MotR , LOW  );
        DutyCycleMotEna = 0;
        ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                    // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
        merker_ChannelPlus = 0;
        Serial.println ("ChannelPlus betätigt, Anpassung nach vorne wurde abgeschlossen");
        IRcode = 0x00000000;                                                              // Zurücksetzen des IR-Codespeichers
        }
      }
    if (IRcode == button_ChannelMinus || merker_ChannelMinus ==1)
      {
      if (merker_ChannelMinus == 0)
        {
        digitalWrite (MotV , LOW  );                                                      // Schreiben der Drehrichtung des Motors
        digitalWrite (MotR , HIGH );
        DutyCycleMotEna = 200;
        ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                    // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
        delay(20);
        DutyCycleMotEna = 180;
        ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                    // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
        delay(20);
        DutyCycleMotEna = 160;
        ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                    // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
        merker_ChannelMinus = 1;
        merker_Verfahrweg = merker_Verfahrweg +5;
        Serial.print ("ChannelPlus betätigt, Anpassung nach hinten angefordert");
        IRcode = 0x00000000;                                                              // Zurücksetzen des IR-Codespeichers
        }
      if (distanz1 > merker_Verfahrweg)
        {
        digitalWrite (MotV , LOW  );                                                      // Schreiben der Drehrichtung des Motors
        digitalWrite (MotR , LOW  );
        DutyCycleMotEna = 0;
        ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                    // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
        merker_ChannelMinus = 0;
        Serial.print ("ChannelPlus betätigt, Anpassung nach hinten wurde abgeschlossen");
        IRcode = 0x00000000;                                                              // Zurücksetzen des IR-Codespeichers
        }
      }    
    }


//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Modus: Fahrzeug fährt Rückwärts

int FahrzeugRueckwaerts()
{
  distanz1 = EntfernungsMessung1   ();                                                    // errechnen der Distanz
  distanz1 = distanz1 / 10;  
  display.showNumber (distanz1);                                                          // Ausgabe des Wertes der Distanz auf dem Display mit Decoder

  if (merker_Down == 0 )                                                                  // einmalige Anzeige des Modus
    {
    Serial.println ("Modus: Fahrzeug fährt Rückwärts");                                   // Ausgabe des Modus über den seriellen Monitor
                                                                                          // Festlegen des Startwerts, Mitte zwischen Minimum und Maximum
    DutyCycleMotEna = 200;                                                                // Minimal 160, maximal 255 bei DutyCycleMotEna
    ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                        // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
    digitalWrite (MotV , LOW  );                                                          // Schreiben der Drehrichtung des Motors
    digitalWrite (MotR , HIGH );
    display.setSegments (SEG_VEH_VMinus);
    delay(500);
    display.clear();
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
    }
  merker_Down = 1;                                                                        // Aktivierung des Merkers für den Programmabschnitt, damit er automatisch wiederholt wird
  merker_Up = 0;                                                                          // Nullsetzung der anderen Modusmerker
  ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                          // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
  if (IRcode == button_Down && DutyCycleMotEna < 241)                                     // Bedingungen für die Geschwindigkeitserhöhung
    {
    DutyCycleMotEna = DutyCycleMotEna +10;                                                // Erhöhung der Geschwindigkeit
    Serial.print ("DutyCycleMotEna Anhebung auf:");                                       // Ausgabe über den seriellen Monitor
    Serial.print (DutyCycleMotEna);
    Serial.println("");
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
    }
  if (IRcode == button_Up && DutyCycleMotEna > 169)                                       // Bedingung für die Geschwindigkeitsverringerung
    {
    DutyCycleMotEna = DutyCycleMotEna -10;                                                // Verringerung der Geschwindigkeit
    Serial.print ("DutyCycleMotEna Senkung auf:");                                        // Ausgabe über den seriellen Monitor
    Serial.print (DutyCycleMotEna);
    Serial.println("");
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
    }
  if (IRcode == button_Up && DutyCycleMotEna == 160)                                      // Stoppen des Fahrzeugs bei minimalem Geschwindigkeitswert
    {
    IRcode = button_Power;                                                                // Ansteuern des Stoppmodus
    }
}


//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void setup() {
//Infrarotempfänger
irrecv.enableIRIn();                                    // Empfänger wird ausgeführt

//Display TM1637
display.setBrightness(7);

//Ultraschallsensor
pinMode (echo     , INPUT );                                                              //festlegen des Pins am Ultraschallsensor als Eingang
pinMode (trig     , OUTPUT);                                                              //festlegen des Pins am Ultraschallsensor als Ausgang

//Soundmodule
pinMode (Sound1     , OUTPUT);                                                            // festlegen der Pins der Soundmodule als Ausgänge
pinMode (Sound2     , OUTPUT);
pinMode (Sound3     , OUTPUT);
pinMode (Sound4     , OUTPUT);

//L298N
pinMode (MotV     , OUTPUT);                                                              // festlegen des Pins am L298N als Ausgang
pinMode (MotR     , OUTPUT);                                                              // festlegen des Pins am L298N als Ausgang
pinMode (MotEna   , OUTPUT);                                                              // festlegen des Pins am L298N als Ausgang

//PWM
ledcSetup (PwmChannelMotEna, Freq, Res);                                                  // PWM-Kanal Einstellung
ledcAttachPin (MotEna, PwmChannelMotEna);                                                 // Definition des PWM-Kanals auf den Pin

Serial.begin(115200);                                                                     //Seriellen Monitor mit einer Baudrate von 115200 starten

}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void loop() {

//EntfernungsMessung1 ();
IRCodeAuslesen      ();
//StopMode            ();
//FahrzeugVorwaerts   ();
//FahrzeugRueckwaerts ();


//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Modus: Fahrzeug fährt vorwärts + Objekterkennung und Stoppbereichanpassung
                                                                                          // Bedingungen für Modus: Fahrzeug fährt vorwärts
if ((IRcode == button_Up && merker_Down == 0)|| merker_Up == 1 && merker_positionierungsmodi == 0)                           
  {
  FahrzeugVorwaerts();
  }
if (merker_positionierungsmodi == 1)
  {
  Positionierung ();
  }
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Modus: Fahrzeug fährt rückwärts
                                                                                          // Bedingungen für Modus: Fahrzeug fährt rückwärts
if ((IRcode == button_Down && merker_Up == 0)|| merker_Down == 1 && merker_positionierungsmodi == 0)                        
{
  FahrzeugRueckwaerts();
}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Modus: allgemeiner Funktionsstopp

if (IRcode == button_Power)                                                               // Bedingung für Funktion: Allgemeiner Fahrzeugstopp
  {
  StopMode ();
  }
}

Im Merge wurden alle Programmabschnitte in einem Programmcode zusammengeführt:



//Infrarotsensor
#include <IRremoteESP8266.h>                                                              // Bibliothek zum Empfang von Infrarotsignalen
#include <IRrecv.h>                                                                       // Bibliothek zum Empfang von Infrarotsignalen
#include <IRutils.h>                                                                      // Bibliothek für Funktionen nach Infrarotempfang
#define RECV_PIN  34                                                                      // Pin, an dem der Pin des IR-Empfängers angeschlossen ist
IRrecv irrecv(RECV_PIN);                                                                  // Eingangsbestimmung für den Infrarot-Datenstrom
decode_results results;                                                                   // Dekodierung in Datei schreiben


// Angabe von '0x' vor dem eigentlichen Hexcode
//         Bezeichnung                  HEX-Code
int button_Power          =             0xECDF8084;                                       // zurücksetzen auf den ursprungszustand
int button_Down           =             0x7F984248;                                       // keine Zuordnung in diesem Programm
int button_Up             =             0xC5F76D04;                                       // keine Zuordnung in diesem Programm
//int button_01             =             0x3138F3E0;                                       // keine Zuordnung in diesem Programm
//int button_02             =             0xBF33DC80;                                       // keine Zuordnung in diesem Programm
//int button_03             =             0xABB78D20;                                       // keine Zuordnung in diesem Programm
//int button_04             =             0x4A86A8C0;                                       // keine Zuordnung in diesem Programm
int button_05             =             0xC0134580;                                       // Modus PDC optische akustische Signale
//int button_06             =             0xBA1256C4;                                       // keine Zuordnung in diesem Programm
//int button_07             =             0x52A2DA24;                                       // keine Zuordnung in diesem Programm
//int button_08             =             0xB74C8420;                                       // keine Zuordnung in diesem Programm
//int button_09             =             0xE3172C20;                                       // keine Zuordnung in diesem Programm
//int button_VolumePlus     =             0xF62981E4;                                       // keine Zuordnung in diesem Programm
//int button_00             =             0x2F9EF384;                                       // keine Zuordnung in diesem Programm
int button_ChannelPlus    =             0x9C7C29E0;                                       // Änderung Wertebereich für optische akustische Signale nach oben; Fahrzeug in Positionierung nach vorne verfahren
//int button_VolumeMinus    =             0x973C68E0;                                       // keine Zuordnung in diesem Programm
//int button_Enter          =             0x3C1BB180;                                       // keine Zuordnung in diesem Programm
int button_ChannelMinus   =             0x1B433B24;                                       // Änderung Wertebereich für optische akustische Signale nach unten; Fahrzeug in Positionierung nach hinten verfahren
int IRcode = 0x00000000;                                                                  // variable für den Empfangenen Tastencode
int merker_Power          =  0;
int merker_Down           =  0;
int merker_Up             =  0;
//int merker_01             =  0;
//int merker_02             =  0;
//int merker_03             =  0;
//int merker_04             =  0;
int merker_05             =  0;
//int merker_06             =  0;
//int merker_07             =  0;
//int merker_08             =  0;
//int merker_09             =  0;
//int merker_VolumePlus     =  0;
//int merker_00             =  0;
int merker_ChannelPlus    =  0;
//int merker_VolumeMinus    =  0;
//int merker_Enter          =  0;
int merker_ChannelMinus   =  0;


//Ultraschallsensor
#define echo 15                                                                           //Anschluss ECHO vom HC-SR04 wurde für PIN 15 festgelegt
#define trig 18                                                                           //Anschluss TRIG vom HC-SR04 wurde für PIN 18 festgelegt


//Display mit Controller
#include <TM1637TinyDisplay.h>                                                            // Bibliothek für die 7- Segment Anzeige
#define CLK 21                                                                            //Anschluss CLK von der 7- Segment Anzeige wurde für PIN 21 festgelegt
#define DIO 19                                                                            //Anschluss DIO von der 7- Segment Anzeige wurde für PIN 19 festgelegt
TM1637TinyDisplay display(CLK, DIO);
const uint8_t SEG_PDC_NORMAL[]  =         {0x39, 0x00, 0x00, 0x00,};
const uint8_t SEG_PDC_VOR[]     =         {0x3f, 0x39, 0x00, 0x00,};
const uint8_t SEG_PDC_END[]     =         {0x3f, 0x3f, 0x39, 0x00,};
const uint8_t SEG_PDC_NOT[]     =         {0x3f, 0x3f, 0x3f, 0x39,};
const uint8_t SEG_PDC_STOP[]    =         {0x7f, 0x7f, 0x7f, 0x7f,};
const uint8_t SEG_Modus_MS[]    =         {0x54, 0x44, 0x52, 0x6d,};
const uint8_t SEG_Modus_kmh[]   =         {0x78, 0x54, 0x44, 0x74,};
const uint8_t SEG_VEH_STOP[]    =         {0x6d, 0x78, 0x3f, 0x73,};
const uint8_t SEG_VEH_VPlus[]   =         {0x1c, 0x46, 0x40, 0x00,};
const uint8_t SEG_VEH_VMinus[]  =         {0x1c, 0x40, 0x40, 0x00,};

//Pins der Soundmodule
#define Sound1 12
#define Sound2 13
#define Sound3 14
#define Sound4 27

// Motortreiber L298N
#define MotV 27
#define MotR 26
#define MotEna 12

//PWM Motortreiber
int Freq = 30000;
int Res = 8;
int PwmChannelMotEna = 2;
int DutyCycleMotEna = 0;                                                                  // MaximalWert: 250; Minimalwet 160;
int DutyCycleNull = 0;

//allgemeine Variablen, die in verschiedenen Programmabläufen aufgerufen werden
int merker_PdcMode = 2;                                                                   //Wertespeicher für den PDC Modus. Ursprung ist mit 2 = normal
int distanz1 =0;                                                                          //erste errechnete Distanz zum Ultraschallsensor. Für die Geschwindigkeitserrechnung
int zeitx1 = 0;                                                                           //Deklaration der Variablen "zeitx"
int vResNull_230 = 0;                                                                     //Merker für die Geschwindigkeitsreduzierung
int vResNull_220 = 0;
int vResNull_210 = 0;
int vResNull_200 = 0;
int vResNull_190 = 0;
int vResNull_180 = 0;
int vResNull_170 = 0;
int vResNull_160 = 0;
int merker_positionierungsmodi = 0;
int merker_Verfahrweg = 0;

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Programmabschnitt 1: Errechnung der ersten Distanz zum Objekt
int EntfernungsMessung1 (){

  long distanz1 = 0;                                                                      //Deklaration der Variablen "distanz1"
  long zeitx1 = 0;                                                                        //Deklaration der Variablen "zeitx"
 
  digitalWrite (trig, LOW);                                                               //setzt den Zustand von trig auf LOW
  delayMicroseconds(3);                                                                   //setzt eine Pause/Unterbrechung von 3 Mikrosekunden
  noInterrupts();                                                                         //verhindert eine Unterbrechung des Vorgangs
  digitalWrite(trig, HIGH);                                                               //setzt den Zustand von trig auf HIGH
  delayMicroseconds(10);                                                                  //setzt eine Pause/Unterbrechung von 10 Mikrosekunden
  digitalWrite(trig, LOW);                                                                //setzt den Zustand von trig auf LOW
  zeitx1 = pulseIn(echo, HIGH);
  interrupts();                                                                           //lässt Vorgangsunterbrechungen erneut zu
//  Serial.print("Zeitx1 PulseIn:");
//  Serial.print(zeitx1);
//  Serial.println("");
  zeitx1 = (((zeitx1 * 344)/1000)/2);                                                     //vererrechnet den Wert der Zeit mit der Schallgeschwindigkeit nach der Raumtemperaur,
                                                                                          //dem Faktor für die Kommastelle und halbiert diesen wegen der doppelten strecke (hin+zurück)
  distanz1 = zeitx1;
//  Serial.print("distanz1  Wert01:");                                                      //Ausgabe des Wertes über den seriellen Monitor
//  Serial.print(distanz1);
//  Serial.println("");
  return (distanz1);                                                                      //Ausgabe des Wertes für die Entfernung
}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Programmabschnitt 2: Erfassen eines Infrarotsignals
int IRCodeAuslesen (){
if (irrecv.decode(&results))                                                              //Wenn ein IR-Signal empfangen wurde
  {
  IRcode = (results.value);                                                               //Das Empfangsignal in der Variable speichern

  Serial.print(IRcode, HEX);                                                              //Gebe empfangenen Code hexadezimal im seriellen Monitor aus
  Serial.println("");
  irrecv.resume();                                                                        //IR-Empfänger für den nächsten Wert bereit machen.
  if(IRcode == 0xFFFFFFFF)
  {
    IRcode = 0x00000000;
  }
  }
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Programmabschnitt 3: Programmcode PDC mit Wertebereichanpassung

int PdcMode (){
  if (merker_05 == 0 )                                                                    //einmalige Anzeige des Modus
  {
    Serial.println ("Modus: Optische akustische Signale (Park Distance Control)");        //Ausgabe des Modus über den seriellen Monitor
  }
  merker_05 = 1;                                                                          //Aktivierung des Merkers für den Programmabschnitt, damit er automatisch wiederholt wird
  merker_Up = 0;                                                                          // Nullsetzung der anderen Modusmerker
  merker_Down = 0;
  if(IRcode == button_05)
  {
    IRcode = 0x00000000;                                                                  //Zurücksetzen des IR-Codespeichers
    Serial.println ("IrCode gelöscht");
  }
  if (IRcode == button_ChannelPlus && merker_PdcMode <= 2)                                //Anpassung des Abstandes über Taster
    {
    merker_PdcMode ++;                                                                    //erhöhen des Abstandes
    Serial.print("Merker PDC-Mode:");                                                     
    Serial.print(merker_PdcMode);                                                         //Ausabe des aktuellen Abstandsmodus über den seriellen Monitor
    Serial.println("");
    IRcode = 0x00000000;                                                                  //Zurücksetzen des IR-Codespeichers
    }
  if (IRcode == button_ChannelMinus && merker_PdcMode >= 2)                               //Anpassung des Abstandes über Taster
    {
    merker_PdcMode --;                                                                    //verringern des Abstandes
    Serial.print("Merker PDC-Mode:");                                                     
    Serial.print(merker_PdcMode);                                                         //Ausabe des aktuellen Abstandsmodus über den seriellen Monitor
    Serial.println("");
    IRcode = 0x00000000;                                                                  //Zurücksetzen des IR-Codespeichers
    }
  distanz1 = EntfernungsMessung1  ();                                                     //errechnen der Distanz
  distanz1 = distanz1 / 10;

//  Serial.print("Distanz 1 PDC ");
//  Serial.print(distanz1);
//  Serial.print("cm");
//  Serial.println ("");

  if (merker_05 == 1 && merker_PdcMode == 1)                                              //Abfrage nach dem Distanzbereich 1 (nah)
    {
    PDC1 ();
    }
  if (merker_05 == 1 && merker_PdcMode == 2)                                              //Abfrage nach dem Distanzbereich 2 (mittel)
    {
    PDC2 ();
    }
  if (merker_05 == 1 && merker_PdcMode == 3)                                              //Abfrage nach dem Distanzbereich 3 (weit)
    {
    PDC3 ();
    }
  }
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Programmabschnitt 4: PDC Nah

int PDC1 ()
{
  if ((distanz1 <= 20) && (distanz1 >= 15))                                               // Abstandsbedingungen für Abstandsberech 1
  {
  display.setSegments(SEG_PDC_VOR);                                                       // Anzeige des Abstandes über das Display
  digitalWrite(Sound1, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.1
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound1, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls
  }
 
  else if ((distanz1 <= 15) && (distanz1 >= 10))                                          // Abstandsbedingung für Abstandsbereich 2
  {
  display.setSegments(SEG_PDC_END);                                                       // Anzeige des Abstandes über das Display
  digitalWrite(Sound2, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.2
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound2, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls
  }
 
  else if ((distanz1 <= 10) && (distanz1 >= 6))                                           // Abstandsbedingungen für Abstandsberech 3
  {
  display.setSegments(SEG_PDC_NOT);                                                       // Anzeige des Abstandes über das Display
  digitalWrite(Sound3, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.3
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound3, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls
  }
 
  else if (distanz1 <= 5)                                                                 // Abstandsbedingungen für Abstandsberech 4
  {
  display.setSegments(SEG_PDC_STOP);                                                      // Anzeige des Abstandes über das Display
  digitalWrite(Sound4, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.4
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound4, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls
  }
 
  else                                                                                    // Abstandsbedingungen für Abstandsberech 0
  {
  display.setSegments(SEG_PDC_NORMAL);                                                    // Anzeige des Abstandes über das Display
  }  
}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Programmabschnitt 5: PDC Mittel

int PDC2 ()
{
  if ((distanz1 <= 55) && (distanz1 >= 51))                                               // Abstandsbedingungen für Abstandsberech 1
  {
  display.setSegments(SEG_PDC_VOR);                                                       // Anzeige des Abstandes über das Display
  digitalWrite(Sound1, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.1
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound1, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls   
  }
 
  else if ((distanz1 <= 50) && (distanz1 >= 46))                                          // Abstandsbedingungen für Abstandsberech 2
  {
  display.setSegments(SEG_PDC_END);                                                       // Anzeige des Abstandes über das Display
  digitalWrite(Sound2, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.2
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound2, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls   
  }
 
  else if ((distanz1 <= 45) && (distanz1 >= 41))                                          // Abstandsbedingungen für Abstandsberech 3
  {
  display.setSegments(SEG_PDC_NOT);                                                       // Anzeige des Abstandes über das Display
  digitalWrite(Sound3, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.3
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound3, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls  
  }
 
  else if (distanz1 <= 40)                                                                // Abstandsbedingungen für Abstandsberech 4
  {
  display.setSegments(SEG_PDC_STOP);                                                      // Anzeige des Abstandes über das Display
  digitalWrite(Sound4, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.4
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound4, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls
  }
 
  else                                                                                    // Abstandsbedingungen für Abstandsberech 0
  {
  display.setSegments(SEG_PDC_NORMAL);                                                    // Anzeige des Abstandes über das Display      
  }
}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Programmabschnitt 6: PDC Weit

int PDC3 ()
{
  if ((distanz1 <= 85) && (distanz1 >= 81))                                               // Abstandsbedingungen für Abstandsberech 1
  {
  display.setSegments(SEG_PDC_VOR);                                                       // Anzeige des Abstandes über das Display
  digitalWrite(Sound1, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.1
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound1, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls
  }
 
  else if ((distanz1 <= 80) && (distanz1 >= 76))                                          // Abstandsbedingungen für Abstandsberech 2
  {
  display.setSegments(SEG_PDC_END);                                                       // Anzeige des Abstandes über das Display
  digitalWrite(Sound2, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.2
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound2, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls
  }
 
  else if ((distanz1 <= 75) && (distanz1 >= 71))                                          // Abstandsbedingungen für Abstandsberech 3
  {
  display.setSegments(SEG_PDC_NOT);                                                       // Anzeige des Abstandes über das Display
  digitalWrite(Sound3, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.3
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound3, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls
  }
 
  else if (distanz1 <= 70)                                                                // Abstandsbedingungen für Abstandsberech 4
  {
  display.setSegments(SEG_PDC_STOP);                                                      // Anzeige des Abstandes über das Display
  digitalWrite(Sound4, HIGH);                                                             // Wiedergabetrigger des Sounds aus Soundmodul Nr.4
  delay (2);                                                                              // kurze Verzögerung zur sicheren Ansteuerung des Soundmoduls
  digitalWrite(Sound4, LOW);                                                              // zurücksetzen des Wiedergabetrigger des Soundmoduls
  }
 
  else                                                                                    // Abstandsbedingungen für Abstandsberech 0
  {
  display.setSegments(SEG_PDC_NORMAL);                                                    // Anzeige des Abstandes über das Display
  }
}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Programmabschnitt 7: Fahrzeugstopp
int StopMode (){
    merker_Up   = 0;                                                                      // Zurücksetzen der Modusmerker
    merker_Down = 0;
    merker_05   = 0;
    Serial.println ("Power Button gedrückt, Fahrzeugfunktionen Stopp");                   // Ausgabe über den seriellen Monitor
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
    DutyCycleMotEna = 200;
    ledcWrite (PwmChannelMotEna, DutyCycleNull);                                          // Nullsetzen des PWM-Ausgangs
    digitalWrite (MotV , LOW );                                                           // Nullsetzen der Motordrehrichtung
    digitalWrite (MotR , LOW );
    display.setSegments (SEG_VEH_STOP);
    vResNull_230 = 0;                                                                     // Merker für die Geschwindigkeitsreduzierung
    vResNull_220 = 0;
    vResNull_210 = 0;
    vResNull_200 = 0;
    vResNull_190 = 0;
    vResNull_180 = 0;
    vResNull_170 = 0;
    vResNull_160 = 0;
    merker_positionierungsmodi = 0;
    merker_ChannelPlus = 0;
    merker_ChannelMinus = 0;
    
  }

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Modus: Fahrzeug fährt vorwärts

int FahrzeugVorwaerts (){
  if (merker_Up == 0 )                                                                    // einmalige Anzeige des Modus
  {
    Serial.println ("Modus: Fahrzeug fährt vorwärts");                                    // Ausgabe des Modus über den seriellen Monitor
                                                                                          // Festlegen des Startwerts, Mitte zwischen Minimum und Maximum
    DutyCycleMotEna = 200;                                                                // Minimal 160, maximal 255 bei DutyCycleMotEna
    digitalWrite (MotV , HIGH);                                                           // Schreiben der Drehrichtung des Motors
    digitalWrite (MotR , LOW );
    display.setSegments (SEG_VEH_VPlus);
    delay(500);
    display.clear();
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
  }
  merker_Up = 1;                                                                          // Aktivierung des Merkers für den Programmabschnitt, damit er automatisch wiederholt wird
  merker_Down = 0;                                                                        // Nullsetzung der anderen Modusmerker
  ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                          // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
  distanz1 = EntfernungsMessung1   ();                                                    // errechnen der Distanz
  distanz1 = distanz1 / 10;                                                               // Umformen der Distanz zu Cm
//  Serial.print("Distanz zu Objekt ");                                                   // Ausgabe der Distanz über den seriellen Monitor
//  Serial.print(distanz1);
//  Serial.print("cm");
//  Serial.println ("");
  display.showNumber (distanz1);                                                          // Ausgabe des Wertes der Distanz auf dem Display mit Decoder
  if (IRcode == button_Up && DutyCycleMotEna < 241 && distanz1 >= 50)                     // Bedingungen für die Geschwindigkeitserhöhung
    {
    DutyCycleMotEna = DutyCycleMotEna +10;                                                // Erhöhung der Geschwindigkeit über den Wert des DutyCycles
    Serial.print ("DutyCycleMotEna Anhebung auf:");                                       // Ausgabe über den seriellen Monitor
    Serial.print (DutyCycleMotEna);
    Serial.println("");
    vResNull_230 = 0;                                                                     //Merker für die Geschwindigkeitsreduzierung
    vResNull_220 = 0;
    vResNull_210 = 0;
    vResNull_200 = 0;
    vResNull_190 = 0;
    vResNull_180 = 0;
    vResNull_170 = 0;
    vResNull_160 = 0;
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
    }
  if (IRcode == button_Down && DutyCycleMotEna >169)                                      // Bedingung für die Geschwindigkeitsverringerung
    {
    DutyCycleMotEna = DutyCycleMotEna -10;                                                // Verringerung der Geschwindigkeit über den Wert des DutyCycles
    Serial.print ("DutyCycleMotEna Senkung auf:");                                        // Ausgabe über den seriellen Monitor
    Serial.print (DutyCycleMotEna);
    Serial.println("");
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
    }
  if (IRcode == button_Down && DutyCycleMotEna == 160)                                    // Stoppen des Fahrzeugs bei minimalem Geschwindigkeitswert
    {
    IRcode = button_Power;                                                                // Ansteuern des Stoppmodus
    }
//Abschnitt Geschwindigkeitsreduzierung bei Objekterkennung
  if (distanz1 < 50 && DutyCycleMotEna > 230&& vResNull_230 == 0 && merker_positionierungsmodi == 0)
    {                                                                                     // Reduzierung schrittweise
    DutyCycleMotEna = 230;                                                                // Schreiben des kleineren Wertes in den DutyCycle
    ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                        // Schreiben des DutyCycles in den Ausgang
    Serial.println ("eduzierung Geschwindigkeit Näherung zu Objekt V230");                // Ausgabe über den seriellen Monitor
    vResNull_230 = 1;
    }
  if (distanz1 < 47 && DutyCycleMotEna > 220 && vResNull_220 == 0 && merker_positionierungsmodi == 0)
    {                                                                                     // Reduzierung schrittweise
    DutyCycleMotEna = 220;                                                                // Schreiben des kleineren Wertes in den DutyCycle
    ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                        // Schreiben des DutyCycles in den Ausgang
    Serial.println ("eduzierung Geschwindigkeit Näherung zu Objekt V220");                // Ausgabe über den seriellen Monitor
    vResNull_220 = 1;
    }
  if (distanz1 < 44 && DutyCycleMotEna > 210 && vResNull_210 == 0 && merker_positionierungsmodi == 0)
    {                                                                                     // Reduzierung schrittweise
    DutyCycleMotEna = 210;                                                                // Schreiben des kleineren Wertes in den DutyCycle
    ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                        // Schreiben des DutyCycles in den Ausgang
    Serial.println ("eduzierung Geschwindigkeit Näherung zu Objekt V210");                // Ausgabe über den seriellen Monitor
    vResNull_210 = 1;
    }
  if (distanz1 < 41 && DutyCycleMotEna > 200 && vResNull_200 == 0 && merker_positionierungsmodi == 0)
    {                                                                                     // Reduzierung schrittweise
    DutyCycleMotEna = 200;                                                                // Schreiben des kleineren Wertes in den DutyCycle
    ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                        // Schreiben des DutyCycles in den Ausgang
    Serial.println ("eduzierung Geschwindigkeit Näherung zu Objekt V200");                // Ausgabe über den seriellen Monitor
    vResNull_200 = 1;
    }
  if (distanz1 < 38 && DutyCycleMotEna > 190 && vResNull_190 == 0 && merker_positionierungsmodi == 0)
    {                                                                                     // Reduzierung schrittweise
    DutyCycleMotEna = 190;                                                                // Schreiben des kleineren Wertes in den DutyCycle
    ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                        // Schreiben des DutyCycles in den Ausgang
    Serial.println ("eduzierung Geschwindigkeit Näherung zu Objekt V190");                // Ausgabe über den seriellen Monitor
    vResNull_190 = 1;
    }
  if (distanz1 < 35 && DutyCycleMotEna > 180 && vResNull_180 == 0 && merker_positionierungsmodi == 0)
    {                                                                                     // Reduzierung schrittweise
    DutyCycleMotEna = 180;                                                                // Schreiben des kleineren Wertes in den DutyCycle
    ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                        // Schreiben des DutyCycles in den Ausgang
    Serial.println ("eduzierung Geschwindigkeit Näherung zu Objekt V180");                // Ausgabe über den seriellen Monitor
    vResNull_180 = 1;
    }
  if (distanz1 < 32 && DutyCycleMotEna > 170 && vResNull_170 == 0 && merker_positionierungsmodi == 0)
    {                                                                                     // Reduzierung schrittweise
    DutyCycleMotEna = 170;                                                                // Schreiben des kleineren Wertes in den DutyCycle
    ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                        // Schreiben des DutyCycles in den Ausgang
    Serial.println ("eduzierung Geschwindigkeit Näherung zu Objekt V170");                // Ausgabe über den seriellen Monitor
    vResNull_170 = 1;
    }
  if (distanz1 < 29 && DutyCycleMotEna > 160 && vResNull_160 == 0 && merker_positionierungsmodi == 0)
    {                                                                                     // Reduzierung schrittweise
    DutyCycleMotEna = 160;                                                                // Schreiben des kleineren Wertes in den DutyCycle
    ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                        // Schreiben des DutyCycles in den Ausgang
    Serial.println ("eduzierung Geschwindigkeit Näherung zu Objekt V160");                // Ausgabe über den seriellen Monitor
    vResNull_160 = 1;
    }
  if (distanz1 < 26 && DutyCycleMotEna == 160 && vResNull_160 == 1 && merker_positionierungsmodi == 0)
    {                                                                                     // Bis zum Stillstand vor dem Objekt und dem Wechsel in den Abstandsmodus
    DutyCycleMotEna = 0;                                                                  // Schreiben des kleineren Wertes in den DutyCycle
    ledcWrite (PwmChannelMotEna, DutyCycleNull);                                          // Schreiben des DutyCycles in den Ausgang
    delay(1000);
    digitalWrite (MotV , LOW );                                                           // zurücksetzen der Drehrichtung des Motors
    digitalWrite (MotR , LOW  );
    merker_positionierungsmodi = 1;                                                       // Aktivieren des Merkers für die Positionierung
    merker_Verfahrweg = distanz1;
    Serial.println("Fahrzeug gestoppt, Positioniermodus aktiviert");                      // Ausgabe über den seriellen Monitor
    }    
}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Modus: Positionierung vor Objekt stehend

int Positionierung (){
    distanz1 = EntfernungsMessung1   ();                                                  // errechnen der Distanz
    distanz1 = distanz1 / 10;                                                             // Umrechnen des Wertes in Cm
    display.showNumber (distanz1);                                                        // Ausgabe des wertes auf dem Display mit Decoder
    if (IRcode == button_ChannelPlus || merker_ChannelPlus ==1)                           // Bedingung für das Verfahren nach vorne
      {
      if (merker_ChannelPlus == 0)                                                        // Einmal Ausführung des Schreibens der Motorwerte
        {
        digitalWrite (MotV , HIGH );                                                      // Schreiben der Drehrichtung des Motors
        digitalWrite (MotR , LOW  );
        DutyCycleMotEna = 200;                                                            // Starten mit einem initialwert, damit der motor sich dreht
        ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                    // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
        delay(20);
        DutyCycleMotEna = 180;                                                            // Schrittweises Absenken der Drehgeschwindigkeit
        ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                    // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
        delay(20);
        DutyCycleMotEna = 160;                                                            // Bis zur Minimalfrequenz
        ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                    // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
        merker_ChannelPlus = 1;
        merker_Verfahrweg = distanz1;
        merker_Verfahrweg = merker_Verfahrweg -5;
        Serial.print ("Distanz 1 ");
        Serial.println (distanz1);
        Serial.print ("merker_Verfahrweg ");
        Serial.println (merker_Verfahrweg);
        Serial.println ("ChannelPlus betätigt, Anpassung nach vorne angefordert");
        IRcode = 0x00000000;                                                              // Zurücksetzen des IR-Codespeichers
        }
      if (distanz1 < merker_Verfahrweg)
        {
        digitalWrite (MotV , LOW  );                                                      // Schreiben der Drehrichtung des Motors
        digitalWrite (MotR , LOW  );
        DutyCycleMotEna = 0;
        ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                    // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
        merker_ChannelPlus = 0;
        Serial.println ("ChannelPlus betätigt, Anpassung nach vorne wurde abgeschlossen");
        IRcode = 0x00000000;                                                              // Zurücksetzen des IR-Codespeichers
        }
      }
    if (IRcode == button_ChannelMinus || merker_ChannelMinus ==1)
      {
      if (merker_ChannelMinus == 0)
        {
        digitalWrite (MotV , LOW  );                                                      // Schreiben der Drehrichtung des Motors
        digitalWrite (MotR , HIGH );
        DutyCycleMotEna = 200;
        ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                    // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
        delay(20);
        DutyCycleMotEna = 180;
        ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                    // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
        delay(20);
        DutyCycleMotEna = 160;
        ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                    // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
        merker_ChannelMinus = 1;
        merker_Verfahrweg = merker_Verfahrweg +5;
        Serial.print ("ChannelPlus betätigt, Anpassung nach hinten angefordert");
        IRcode = 0x00000000;                                                              // Zurücksetzen des IR-Codespeichers
        }
      if (distanz1 > merker_Verfahrweg)
        {
        digitalWrite (MotV , LOW  );                                                      // Schreiben der Drehrichtung des Motors
        digitalWrite (MotR , LOW  );
        DutyCycleMotEna = 0;
        ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                    // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
        merker_ChannelMinus = 0;
        Serial.print ("ChannelPlus betätigt, Anpassung nach hinten wurde abgeschlossen");
        IRcode = 0x00000000;                                                              // Zurücksetzen des IR-Codespeichers
        }
      }    
    }


//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Modus: Fahrzeug fährt Rückwärts

int FahrzeugRueckwaerts()
{
  distanz1 = EntfernungsMessung1   ();                                                    // errechnen der Distanz
  distanz1 = distanz1 / 10;  
  display.showNumber (distanz1);                                                          // Ausgabe des Wertes der Distanz auf dem Display mit Decoder

  if (merker_Down == 0 )                                                                  // einmalige Anzeige des Modus
    {
    Serial.println ("Modus: Fahrzeug fährt Rückwärts");                                   // Ausgabe des Modus über den seriellen Monitor
                                                                                          // Festlegen des Startwerts, Mitte zwischen Minimum und Maximum
    DutyCycleMotEna = 200;                                                                // Minimal 160, maximal 255 bei DutyCycleMotEna
    ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                        // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
    digitalWrite (MotV , LOW  );                                                          // Schreiben der Drehrichtung des Motors
    digitalWrite (MotR , HIGH );
    display.setSegments (SEG_VEH_VMinus);
    delay(500);
    display.clear();
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
    }
  merker_Down = 1;                                                                        // Aktivierung des Merkers für den Programmabschnitt, damit er automatisch wiederholt wird
  merker_Up = 0;                                                                          // Nullsetzung der anderen Modusmerker
  ledcWrite (PwmChannelMotEna, DutyCycleMotEna);                                          // Schreiben des Wertes für die Pwm Ausgabe in den Ausgang
  if (IRcode == button_Down && DutyCycleMotEna < 241)                                     // Bedingungen für die Geschwindigkeitserhöhung
    {
    DutyCycleMotEna = DutyCycleMotEna +10;                                                // Erhöhung der Geschwindigkeit
    Serial.print ("DutyCycleMotEna Anhebung auf:");                                       // Ausgabe über den seriellen Monitor
    Serial.print (DutyCycleMotEna);
    Serial.println("");
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
    }
  if (IRcode == button_Up && DutyCycleMotEna > 169)                                       // Bedingung für die Geschwindigkeitsverringerung
    {
    DutyCycleMotEna = DutyCycleMotEna -10;                                                // Verringerung der Geschwindigkeit
    Serial.print ("DutyCycleMotEna Senkung auf:");                                        // Ausgabe über den seriellen Monitor
    Serial.print (DutyCycleMotEna);
    Serial.println("");
    IRcode = 0x00000000;                                                                  // Zurücksetzen des IR-Codespeichers
    }
  if (IRcode == button_Up && DutyCycleMotEna == 160)                                      // Stoppen des Fahrzeugs bei minimalem Geschwindigkeitswert
    {
    IRcode = button_Power;                                                                // Ansteuern des Stoppmodus
    }
}


//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void setup() {
//Infrarotempfänger
irrecv.enableIRIn();                                    // Empfänger wird ausgeführt

//Display TM1637
display.setBrightness(7);

//Ultraschallsensor
pinMode (echo     , INPUT );                                                              //festlegen des Pins am Ultraschallsensor als Eingang
pinMode (trig     , OUTPUT);                                                              //festlegen des Pins am Ultraschallsensor als Ausgang

//Soundmodule
pinMode (Sound1     , OUTPUT);                                                            // festlegen der Pins der Soundmodule als Ausgänge
pinMode (Sound2     , OUTPUT);
pinMode (Sound3     , OUTPUT);
pinMode (Sound4     , OUTPUT);

//L298N
pinMode (MotV     , OUTPUT);                                                              // festlegen des Pins am L298N als Ausgang
pinMode (MotR     , OUTPUT);                                                              // festlegen des Pins am L298N als Ausgang
pinMode (MotEna   , OUTPUT);                                                              // festlegen des Pins am L298N als Ausgang

//PWM
ledcSetup (PwmChannelMotEna, Freq, Res);                                                  // PWM-Kanal Einstellung
ledcAttachPin (MotEna, PwmChannelMotEna);                                                 // Definition des PWM-Kanals auf den Pin

Serial.begin(115200);                                                                     //Seriellen Monitor mit einer Baudrate von 115200 starten

}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void loop() {

//EntfernungsMessung1 ();
IRCodeAuslesen      ();
//PdcMode             ();
//PDC1                ();
//PDC2                ();
//PDC3                ();
//StopMode            ();
//FahrzeugVorwaerts   ();
//FahrzeugRueckwaerts ();

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Modus: PDC mit veränderbarem Abstandsbereich

if (IRcode == button_05 || merker_05 == 1)                                                //Modus: PDC mit veränderbarem Abstandsbereich
  {
  PdcMode ();
  }

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Modus: Fahrzeug fährt vorwärts + Objekterkennung und Stoppbereichanpassung
                                                                                          // Bedingungen für Modus: Fahrzeug fährt vorwärts
if ((IRcode == button_Up && merker_Down == 0)|| merker_Up == 1 && merker_positionierungsmodi == 0)                           
  {
  FahrzeugVorwaerts();
  }
if (merker_positionierungsmodi == 1)
  {
  Positionierung ();
  }
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Modus: Fahrzeug fährt rückwärts
                                                                                          // Bedingungen für Modus: Fahrzeug fährt rückwärts
if ((IRcode == button_Down && merker_Up == 0)|| merker_Down == 1 && merker_positionierungsmodi == 0)                        
{
  FahrzeugRueckwaerts();
}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Modus: allgemeiner Funktionsstopp

if (IRcode == button_Power)                                                               // Bedingung für Funktion: Allgemeiner Fahrzeugstopp
  {
  StopMode ();
  }
}


In diesem Abschnitt wird die Konstruktion der Komponenten für unser Projekt. dokumentiert. Wir haben für den Druck des Fahrwerks die bereits vorgefertigten Konstruktionsdateien aus dem Projekt T1- Smart Device by Jakob genutzt. Die Halterung des Ultraschallsensors und die Halterung für das Display mit Decoder, sowie für das Regal zum halten der Soundmodule wurden selber entwickelt.

Der Halter für den Ultraschallsensor wurde in CATIA selber designed und später gedruckt. Für das Prototyping und für das später genutzte Modell wurden die niedrigsten Druckeinstellungen genutzt. Der Halter wird anstelle der Frontscheibe des VW Bus Modells eingesetzt und identisch befestigt.




Datei "Frontscheibe Ultaschallsensor V4.CATPart"

Auch der Halter für das Display mit Decoder wurde auf den niedrigsten Druckeinstellungen gedruckt. Die Fixierung erfolgt über die vier Einstanzungen an dem Display und die vier herausstehenden Stifte.



Datei "Halterung 7_Segment Anzeige V1.3.stl"


Die Durchführung dieses Abschnittes kann für andere Projektgruppen optional sein. Für uns war dies jedoch von Nöten. Die Räder aus der ursprünglichen Fahrwerkskonstruktion sollten sich auf der Welle befestigen lassen. Die Drehung des Rades würde durch die freie Bewegung im Achsschenkel realisiert werden. Doch aufgrund von Fertigungstoleranzen war die Verbindung zwischen Achsschenkel und Welle fest und ließ sich nicht bewegen.

Unsere Lösung für das Problem stellte die Neukonstruktion der Räder der Vorderachse dar. Diese sollten sich durch eine Hülse auf der Welle frei drehen lassen.

Bei der Konstruktion der Felge wurde die Außenbemaßung der Originalfelge in Durchmesser und Höhe übernommen, um die originale Maßhaltigkeit zu gewährleisten.



Dateien "SET Felge Achse vorne 1 V1.CATPart" und "SET Felge Achse vorne 2 V1.CATPart"

Für den Druck aller Bauteile haben wir die schlechteste Auflösung von 0,28mm genutzt. Alle bauteile haben eine anteilige Füllung bekommen, um Material und zeit zu sparen. Die Temperatur, mit der das Material aus der Düse kommt, beträgt 200°C und die des Druckbetts 65°C. Der Lüfter zum kühlen der Düse arbeitet mit 100% und es wird eine Supportstruktur in Form eines "Brim" kreiert.

Bei dem Druck des Halters des Ultraschallsensors ist auf die Lage zu achten. am wenigsten Probleme mit dem Druck bzw. nach dem Druck bekommt man, wenn der Druck auf der Frontfläche angefertigt wird:

Für den Druck des Displayhalters wird die fogende Position empfohlen:


Die Räder und die Hülsen sollten mit der schmalen Seite bzw. der Öffnung nach Oben gedruckt werden:


Die regalböden werden allesamt flach auf den Boden gelegt und danach hochgezogen.


1. Die perforierten Reifenflächen der Voderachse müssen herausgebrochen werden, genauso wie die Kreisflächen direkt über der Hinterachse. Diese dienen dazu, die Achsen des Motors in Position zu halten und platz für die Lenkachse zu schaffen.

2. Der Halter des Getriebemotors wird angeklebt. dazu wird zunächst die Lage des Motorhalters mittels der Achsen und einem Zollstock bestimmt. Danach wird dieser mit etwas Klebstoff fixiert.

3. an der Position, an der sich die vorderachse befindet, werden im Boden zwei perforierte Kreisflächen herausgetrennt. mittels der wei gedruckten Wellen, die später zur montage der Achsschenkel in der gedruckten Vorderachse dienen, wird die lage von selbiger bestimmt und mit klebstoff fixiert.

 



Die Frontscheibe, die als Halter für den Ultraschallsensor dient, wird als alternative zu der originalen Frontscheibe verbaut und mit den Gummibändern fixiert. Der Ultraschallsensor wird von der Rüchseite hereingeschoben und hält seine Position eigenständig. Der Halter für das Display mit Decoder wird auf die mittlere Tennwand aufgesteckt und das Display aufgelegt, genauso wi das Breadboard.

 


Die Regale zur aufbewahrung der Soundmodule wurden in den Trennwänden fixiert. die Löcher für die Fixierung wurden mit dem Lasercutter erstellt und höndisch nachbearbeitet. Ebenfalls wurden Löcher angefertigt, die der Durchführung der Leitungen zwischen soundmodulen und dem MiKrocontroller dienen. Der Motortreiber mit der 9V Blockbatterie wird im hinteren Teil des Busses eingelegt und nicht zusätzlich fixiert. Die Leitungen zwischen dem Motortreiber und dem Getriebemotor wurden angelötet. Ebenfalls wurden die Stecker der Lautsprecher an die zugehörigen Leitungen zu den Soundmodulen gelötet.

 



Wir haben unsere Erfahrungen mit dem Programm Arduino stark vertiefen können. Der durchaus komplexe Programmablauf wurde im Laufe des Projektes einfacher und nachvollziehbarer, was letztendlich auch für anfänger auf dem Gebiet ein gutes Verständnis erzeugt. Der Umgang mit den Programmen Catia und Cura wurde durch die erfolgreiche Konstruktion von Bauteilen ebenfalls verbessert.

Die Park Distance control könnte Softwaretechnisch noch etwas detailierter aufgelöst werden. beispielsweise könnte man eine Schrittweise Annäherung an ein erkanntes Objekt durch die Betätigung einer Taste als Offset anwählen, oder dieselbe Funktion mit einer Prozentualen Annäherung umsetzen. In unserem Projekt wurde keine Lenkung des Fahrzeuges umgesetzt, allerdings sind dafür alle Vorbereitungen getroffen worden.

T1‐Distance Control  Phase ll

Dieses Projekt beinhaltet ein T1 Bus Modell, welches eigenständig, durch einen DC-Motor gesteuert, fährt. Mithilfe eines Ultraschallsensors wird der Abstand zu anderen Objekten erkannt und bei einem vorgegeben programmierten Abstand das T1 Bus Modell zum Abbremsen bringt. Zusätzlich wird dieser Vorgang akustisch mittels eines passiven Summers dargestellt und der erfasste Wert wird auf einer integrierten 7- Segment-Anzeige angezeigt. Gesteuert wird alles über einen Mikrocontroller, den ESP32. Dieser ist mittels eines Mikro-USB-Kabels mit dem Computer verbunden, welcher ihn mit Spannung versorgt, sowie das programmierte Arduino Projekt auf den Mikrocontroller lädt.

 Ziel dieses Projektes ist es, dass der im Bus vorhandene DC-Motor eigenständig sein Drehmoment reguliert, bis ein zu geringer Abstand mittels Ultraschallsensor erkannt und darauffolgend zum Abbremsen gebracht wird. Zusätzlich möchten wir realisieren, dass der Bus über zwei Schalter verfügt, wobei der eine als Spannungsversorgung und der andere als Zündung dient. Als Spannungsversorgung heißt, dass über diesen Schalter der Bus sozusagen „auf- und zugeschlossen wird, welches durch das An- und Ausgehen der LEDs realisiert wird. Der Schalter für die Zündung schaltet dann eben den Motor je nach Bedarf sowohl ein als auch aus. Dadurch wird das Prinzip Coming Home/ Leaving Home verwirklicht. Ebenso möchten wir LEDs nutzen, die als Bremslichter und Frontscheinwerfer fungieren


T1-Bus

Dieses Projekt beinhaltet ein T1 Bus Modell, welches eigenständig, durch einen DCMotor gesteuert, fährt. Mithilfe eines Ultraschallsensors wird der Abstand zu anderen Objekten erkannt und bei einem vorgegeben programmierten Abstand das T1 Bus Modell zum Abbremsen bringt. Zusätzlich wird dieser Vorgang akustisch mittels eines passiven Summers dargestellt und der erfasste Wert wird auf einer integrierten 7- Segment-Anzeige angezeigt. Gesteuert wird alles über einen Mikrocontroller, den ESP32. Dieser ist mittels eines Mikro-USB-Kabels mit dem Computer verbunden, welcher ihn mit Spannung versorgt, sowie das programmierte Arduino Projekt auf den Mikrocontroller lädt. Ziel dieses Projektes ist es, dass der im Bus vorhandene DC-Motor eigenständig sein Drehmoment reguliert, bis ein zu geringer Abstand mittels Ultraschallsensor erkannt und darauffolgend zum Abbremsen gebracht wird. Zusätzlich möchten wir realisieren, dass der Bus über zwei Schalter verfügt, wobei der eine als Spannungsversorgung und der andere als Zündung dient. Als Spannungsversorgung heißt, dass über diesen Schalter der Bus sozusagen „auf- und zugeschlossen wird, welches durch das An- und Ausgehen der LEDs realisiert wird. Der Schalter für die Zündung schaltet dann eben den Motor je nach Bedarf sowohl ein als auch aus. Dadurch wird das Prinzip Coming Home/ Leaving Home verwirklicht. Ebenso möchten wir LEDs nutzen, die als Bremslichter und Frontscheinwerfer fungieren

Als Orientierung zur Durchführung waren auf der Lernplattform der Schule Beispielprojekte, welche ebenfalls die Konstruktion und Programmierung eines T1 Bus Modells beinhalteten, zur Verfügung gestellt. Zusätzlich wurde ein Bauset mit allen für das Projekt benötigten Bauteilen zur Verfügung gestellt, mit welchem unterschiedliche Funktionen getestet werden konnten. Es wurden eigenständig Teams gebildet, welche die Schwerpunkte Maschinentechnik und Elektrotechnik abdecken sollten und somit die Aufgaben entsprechend verteilt werden können. Bei Problemen, Schwierigkeiten und Fragen war jederzeit ein Ansprechpartner zur Verfügung. Zusätzlich bestand die Möglichkeit den 3D-Drucker in der Schule zu benutzen, um Bauteile für das Modell zu konstruieren, sowie verschiedene Softwares (u.a. Fritzing, Arduino, CATIA und Ultimaker Cura) zu nutzen. In der Projektphase II hatten wir zudem bereits Grundkenntnisse zu den genannten Softwares, sowie den Umgang mit dem 3D-Drucker erlernt und auch Erfahrungen gesammelt, wie man so ein Projekt fristgerecht umzusetzen hat. Für die Projektphase II war ebenfalls ein Zeitplan vorgegeben, an dem wir uns orientieren mussten.

Da wir in unserem Team von der ersten Projektphase geblieben sind, blieb das Kennenlernen aus und wir konnten direkt mit den Vorbereitungen starten. Zu Beginn der Projektphase II stellten wir zunächst Überlegungen an, welche Funktionen unser T1 Bus in dieser Phase am Ende umsetzen soll und wie wir dies realisieren. Nachdem der Austausch im Team stattgefunden hat, entschieden wir uns dazu, unseren T1 Bus mit seinen bisherigen Funktionen so zu erhalten und diesen dann nur um zusätzliche Funktionen zu erweitern. Nach dem Abgleich der Hauptmaterialliste, wurde eine zusätzliche eigene Materialliste für das Projekt erstellt. Hierbei haben wir festgestellt, dass wir zur Realisierung unserer Funktionen Bauteile benötigten, die nicht im Bauset des T1-Busses vorhanden waren und demnach erst einmal bestellt werden mussten. Das waren zum einen die H-Brücke (Motortreiber) zur Ansteuerung des DC-Motors, eine 9V-Batterie, die als Spannungsversorgung für unseren Mikrocontroller fungieren sollte, einen Anschluss für die 9V-Batterie mit Netzstecker und zusätzliche Jumper Kabel und einen Kippschalter. Des Weiteren wurde die Informationsbeschaffung eingeleitet, wofür wir unter anderem die Lernplattform der Schule, Unterrichtsmaterial sowie bereits erlerntes Wissen aus der ersten Projektphase, die Recherche im Internet und Fachbücher nutzten. Es wurde sich mit der Funktionsweise der einzelnen benötigten Bauteile sowie den Softwares auseinandergesetzt und anschließend in Form eines Gantt- Diagramms ein teameigener Zeitplan erstellt. Zusätzlich wurden zeitgleich die einzelnen Aufgaben im Team aufgeteilt.

In der Realisierungsphase wurde mit der Programmierung gestartet, dazu wurde die Software Arduino genutzt. Da wir die Programmierung des Ultraschallsensors, der 7-Segmentanzeige und die des Summers schon in der ersten Projektphase realisiert hatten, mussten wir in dieser Phase lediglich den DC-Motor, den Zündung Schalter und die hinzugefügten LEDs programmieren. Nachdem die Programmierung abgeschlossen war, wurde mit dem Erstellen der dazugehörigen Schaltpläne mittels Fritzingsoftware begonnen. Danach wurden die einzelnen Bauteile implementiert, wofür wir das zur Verfügung gestellte Bauset und unsere bestellten Materialien nutzten. Hierbei wurde ersichtlich, dass wir neue Achsen für den T1 Bus benötigen, da die in Phase I genutzten Achsen nur als Übergangslösung fungierten und wir zudem in Phase II einen DC-Motor integrieren wollten, den wir beim Drucken der Achsen mitberücksichtigen mussten. Diese Achsen konstruierten wir dann mithilfe der Software Catia und konnten mit der daraus entstandenen STL-Datei die gCodes mittels der Software Slicing erstellen. Die gCodes konnten wir dann wiederum für den 3D-Druck nutzen. Um die Coming Home/Leaving Home-Funktion zu verwirklichen, haben wir dann zwei Schalter integriert. Mit den restlichen Bauteilen konnte die Konstruktion des Modells fertiggestellt werden. Nachdem das Programm auf den Mikrocontroller geladen und mehrere Versuche durchgeführt wurden, konnte man behaupten, dass das Modell nach den eigenen Vorstellungen und Planungen funktionierte.

Abstandssensor

Der HC-SR04 ist ein Ultraschallsensor mit den wir den Abstand zu einem Objekt messen können. Abbildung: Ultraschallsensor HC-SR04 Quelle: BBS2 Wolfsburg An Pin 1 (VCC) des Ultraschallsensors benötigt man eine Spannung von +5V. Um den Stromkreis zu schließen und den Sensor mit Spannung zu versorgen wird an Pin 4 (Gnd) die Masse angelegt. Damit der Sensor die Messung startet benötigt er ein High-Signal bzw. eine fallende Flanke an Pin 2 (Trig). Nach ca. 250 µs sendet der HC-SR04 ein Burst-Signal mit 40 kHz aus für die Dauer von 200 µs. Der Ausgang Pin 3 (Echo) geht auf High-Pegel und wartet auf den Empfang des akustischen Echos. Wenn das Echo erfolgreich registriert wurde, fällt der Ausgang auf Low-Pegel. Nach 20 ms kann die nächste Messung durchgeführt werden. Wenn das High Signal länger als 200 ms am Ausgang Pin 3 (Echo) anliegt, dann wurde kein Hindernis vom Sensor erkannt (außer Reichweite).


#define echo 25                        //Anschluss ECHO vom HC-SR04 wurde für PIN 25 festgelegt

#define trig 33                          //Anschluss TRIG vom HC-SR04 wurde für PIN 33 festgelegt

//Entfernung als globale Variable anlegen

int entfernung = 0;

//Funktion zur Messung der Entfernung über den Ultraschallsensor HC-SR04 (mit Echo und Trigger), Einheit: cm

int getEntfernung()

{

  long entfernung = 1;

  long zeitx = 0;

 

  digitalWrite (trig, LOW);           //setzt den Zustand von trig auf LOW

  delayMicroseconds(3);             //setzt eine Pause/Unterbrechung von 3 Mikrosekunden

  noInterrupts();                         //keine Unterbrechung

  digitalWrite(trig, HIGH);            //setzt den Zustand von trig auf HIGH

  delayMicroseconds(10);           //setzt eine Pause/Unterbrechung von 10 Mikrosekunden

  digitalWrite(trig, LOW);            //setzt den Zustand von trig auf LOW

  zeitx = pulseIn(echo, HIGH);    //setzt den Zustand von echo auf HIGH

  interrupts();                             //unterbricht den Vorgang

  zeitx = (zeitx / 2);                     //teilt die Zeit durch 2

  entfernung = zeitx / 29.1;        //teilt die Restzeit durch die Geschwindigkeit des Schalls

  return (entfernung);                 //gibt die berechnete Entfernung zurück

}

void setup()

{

  pinMode(trig, OUTPUT);                      //Legt den Eingangstyp des angegebenen PINs fest

  pinMode(echo, INPUT);                       //Legt den Eingangstyp des angegebenen PINs fest

}

void loop()

{

    entfernung = getEntfernung();           //Aufruf der Funktion zum Messen der Entfernung

}



Ein passiver Summer ist ein Lautsprecher, welcher im Gegensatz zum aktiven Summer keine interne Elektronik, wie z.B. einen Oszillator, der eine hörbare Frequenz erzeugt, besitzt. Vom Ausgang, dem Mikrocontroller, geht beim passiven Summer die Frequenz aus, somit wird diesem ermöglicht mehrere Töne und ganze Melodien zu erzeugen. Im Vergleich zum passiven Summer kann der aktive Summer nur eine bestimmte Frequenz erzeugen. Im optischen Vergleich besitzt der aktive Summer unterschiedliche Ausgänge, während dies beim passiven Summer nicht der Fall ist. Beide Summer ähneln sich stark, weshalb es dringend nötig ist die Anschlüsse zu beachten.


#define passiver_buzzer 27       //Der PIN für den passiven Summer wurde auf 27 festgelegt

// Funktion zur Tonsteuerung ---> mit geringer werdendem Abstand soll sich die Tonfrequenz höher werden

void sound(int entfernung)

{

  // die Entfernungsabstände können beliebig angepasst werden

  if ((entfernung <= 50) && (entfernung >= 25))

  {

    ledcWriteTone(1, 300);

    delay(10);

  }

 

  else if ((entfernung <= 24) && (entfernung >= 15))

  {

    ledcWriteTone(1, 800);

    delay(5);

  }

 

  else if ((entfernung <= 14) && (entfernung >= 6))

  {

    ledcWriteTone(1, 1300);

    delay(2);

  }

 

  else if (entfernung <= 5)

  {

    ledcWriteTone(1, 1700);

    delay(1);

  }

 

  else

  {

    ledcWriteTone(1, 0);

    delay(1);

  }

}

void setup()

{

pinMode(passiver_buzzer, OUTPUT);    //Legt den Eingangstyp des angegebenen PINs fest

}

void loop()

{

    sound(entfernung);                             //Aufruf der Funktion zum Ansteuern des passiven Buzzers

  }



7-Segment-Anzeige

Damit man den gemessenen Abstand des HC-SR04 Ultraschallsensor auslesen kann, benötigen wir das 7-Segment Display. Das 7-Segment Display besitzt insgesamt 12 Kontakte, die auf der Rückseite, sechs oben, sechs unten jeweils verteilt sind. Dabei gehören 4 dieser Kontakte zu einer Ziffer. Die anderen 8 Kontakte, die noch übrig bleiben gehören jeweils zu einem Segment und dem dazugehörigen Punkt, der neben der Ziffer ist. Die üblichen 7- Segment Anzeigen die 1 oder 2 Ziffern anzeigen, steuern die Ziffern einzeln an. Bei 7- Segment Anzeigen die 4 oder mehr Ziffern anzeigen ist diese Methode unmöglich, da es sonst zu einem sehr großen Kabelaufwand kommen würde. Deshalb greift man auf das sogenannte "Multiplexing" zu. Darunter versteht man, dass wenn alle Ziffern gleichzeitig angezeigt werden sollen, diese schnell hintereinander angesteuert werden. Für das bloße Auge ist dies jedoch nicht sichtbar, weshalb man denkt, dass alle Ziffern gleichzeitig angesteuert werden. Bei den Anschlüssen CLK und DIO handelt es sich jeweils um digitale Eingänge, die die Informationen des Microcontrollers aufnehmen, bearbeiten und letztendlich umsetzen. Der Anschluss GND bedeutet nichts anderes als Ground und VCC stellt die Spannungsversorgung für das Display sicher.


#include <TM1637Display.h>     // Bibliothek für die 7- Segment Anzeige

#define display_clk 16               //Anschluss CLK von der Anzeige wurde für PIN 16 festgelegt

#define display_dio 13              //Anschluss DIO von der Anzeige wurde für PIN 13 festgelegt

TM1637Display display(display_clk, display_dio);

void loop()

{

//Einstellungen für die 7 Segment Anzeige

  display.setBrightness(7);

  display.showNumberDec(entfernung);

  delay(20);

}





DC-Motor

In einem DC Motor ist ein Dauermagnet sowie ein drehbares Eisenteil. Diese sind zwischen dem Dauermagneten gelagert und von einer isolierten Spule aus Kupfer umwickelt. Die Spule baut ein Magnetfeld auf und der Eisenkern wird zum Elektromagneten sobald Gleichstrom durch die Spule fließt. Der Elektromotor richtet sich so aus, dass immer ungleiche Pole sich gegenüberstehen. Diese Stellung hält der Elektromagnet, bis man den Strom abgeschaltet wird. Dies liegt an den magnetischen Kräften, die wirken. Jedoch muss der Elektromagnet sich drehen. Dies geht in dem es zu einer Umpolung der magnetischen Ausrichtung kommt. Dies kann ganz einfach erreicht werden, indem man die Stromrichtung in der Spule ändert. Mithilfe eines Koll Mithilfe eines Kollektors wird die Änderung der Stromrichtung realisiert. Der Kollektor ist dabei mit der Spule verbunden und versorgt diese mit Spannung. Wenn der Elektromagnet sich dreht und fast die optimale Ausrichtung mit dem Dauermagneten erreicht, wird der Strom über den Kollektor abgeschaltet und dann wieder eingeschaltet. jedoch mit einer umgekehrten Polung. Durch diese Umpolung kommt es dazu, dass sich die gleichen Magnetpole vom Dauermagneten abstoßen.



Eine vereinfachte Darstellung der H-Brücke findest du hier.

Eine H-Brücke fungiert als Steuerung von Gleichstrom Motoren. Durch die Ansteuerung von bestimmten Schaltern/Transistoren, kann ein DC-Motor umgepolt und somit die Drehrichtung bestimmt werden. Die Verschaltung ist in Form eines H´s realisiert, woher auch der Name stammt. Zusätzlich kann der Motor mit dieser Brücke ebenfalls gebremst und die Geschwindigkeit mittels PWM (=Pulsweitenmodulation) bestimmt werden. Die H-Brücke besteht aus vier Schaltern, die je nach Schalterstellung den Motor in Rechts- oder Linkslauf versetzen.

//Pinbelegung für die H-Brücke

int inc1 = 18;

int inc2 = 19;

int motor = 17;

//Pulsweitenmodulation

const int freq = 30000;

const int resolution = 8;

// Funktion zur Antriebssteuerung ---> mit geringer werdendem Abstand soll der Motor langsamer laufen

void antrieb(int entfernung)

{

  if ((entfernung <= 50) && (entfernung >= 25))

  {

    digitalWrite(inc1, LOW);                                //Laufrichtung einstellen

    digitalWrite(inc2, HIGH);                                //

    ledcWrite(2, 230);                                         // Sendet ein Signal an den Channel 2 mit einem Duty Cyle(Auslastungsgrad) von 230

  }

 

  else if ((entfernung <= 24) && (entfernung >= 5))

  {

    digitalWrite(inc1, LOW);                                //Laufrichtung einstellen

    digitalWrite(inc2, HIGH);                                //

    ledcWrite(2, 200);                                         //Sendet ein Signal an den Channel 2 mit einem Duty Cyle(Auslastungsgrad) von 200

  }

 

  else if (entfernung < 5)

  {

    digitalWrite(inc1, LOW);                                //Laufrichtung einstellen

    digitalWrite(inc2, HIGH);                                //

    ledcWrite(2, 0);                                             // Motor steht

  }

 

  else

  {

    digitalWrite(inc1, LOW);                                //Laufrichtung einstellen

    digitalWrite(inc2, HIGH);

    ledcWrite(2, 255);                                         //Sendet ein Signal an den Channel 2 mit einem Duty Cyle(Auslastungsgrad) von 255

  }

}

void setup()

{

  pinMode(motor, OUTPUT);                  //Legt den Eingangstyp des angegebenen PINs fest

  pinMode(inc1, OUTPUT);                     //Legt den Eingangstyp des angegebenen PINs fest

  pinMode(inc2, OUTPUT);                     //Legt den Eingangstyp des angegebenen PINs fest

  ledcSetup(1, freq, resolution);              // Konfigurieren der Pulsweitenmodulation für Channel Sound

  ledcAttachPin(passiver_buzzer, 1);      //passiver Buzzer mit PWM-Channel verbinden

 

  ledcSetup(2, freq, resolution);              //Konfigurieren der Pulsweitenmodulation für Channel Antrieb

  ledcAttachPin(motor, 2);                      //Motor mit dem PWM-Channel verbinden

}

void loop()

{

    antrieb(entfernung);                            //Aufruf der Funktion zum Antrieb des Motors

  }

}


(Weitere Infos zu den LEDs gibt es im Kurs Electric-Lighting)

In dieser Projektphase nutzen wir verschiedene LEDs zur optischen Darstellung. Wir nutzen insgesamt sieben LEDs, die unterschiedlichen Aufgaben symbolisieren. Wir haben zum einen zwei Frontscheinwerfer vorne in Weiß, die immer leuchten bei Benutzung des Fahrzeuges. Bei diesen LEDs haben wir keinen Vorwiderstand und somit wird die Spannung von 3,3V direkt auf die LEDs geschaltet, da sie bis zu 3,5 V beschaltet werden können. Des Weiteren haben wir vier Rückscheinwerfer in Rot, die zum einen als Bremslichter und zum anderen als Scheinwerfer hinten fungieren. Die hinteren zwei Scheinwerfer leuchten ebenso dauerhaft und haben einen 1kΩ Widerstand. Im Gegensatz zu den zwei Bremslichtern, die wiederum nur beim eigentlichen Bremsvorgang des T1 Busses leuchten und auch nur einen Widerstand von 100Ω besitzen. Die roten LEDs benötigen eine Spannung von 1,6-2,2V. Der Grund für die unterschiedlichen Widerstände ist, dass wir die LEDs für den Bremsvorgang heller leuchten lassen möchten als die LEDs die als Rückscheinwerfer fungieren. Je höher der Widerstand, desto geringer die Spannung und demnach auch die Intensität der LEDs. Herleiten kann man sich diese Regel on dem ohmschen Gesetz. Als letztes haben wir noch eine grüne LED, die als Statusanzeige für unseren externe Spannungsversorgung fungieren soll. Die LED symbolisiert unser Status, ob der Bus geöffnet oder geschlossen ist. Ist der Bus „aufgeschlossen“ leuchtet die grüne LED. Ist der Bus geschlossen, soll die LED erlischen und auch die externe Spannung ist damit ausgeschaltet. Die grüne LED benötigt eine Spannung von 1,9-2,5 V, sie ist direkt auf der Einspeise Platine vorhanden. Der Aufbau wird lediglich mit Hilfe von Jumperkabeln, die auf dem Breadboard die LEDs mit ihren Anschlüssen richtig verbinden, umgesetzt. Angesteuert werden die LEDs über unseren Mikrocontroller, dem ESP32 und die zugehörige Programmierung wird zuvor bei Arduino erstellt.

 Die Coming/Leaving Home‐Funktion beschreibt im Allgemeinen die Funktion, dass die LEDs eines Autos sowohl beim Verlassen des Hauses, also beim Aufschließen des Autos als auch beim Nachhause kommen, also beim Abschließen des Autos per Fernbedienung schon vorher bzw. beim Abschließen des Autos noch nachträglich eine gewisse Zeit leuchtet. In unserem Fall haben wir anstelle einer Fernbedienung mit integrierter Zeit, die abläuft, zwei Schalter integriert. Ein Schalter für die Spannungsversorgung, der das Auf‐ und Zuschließen des Busses mithilfe von LEDs symbolisieren soll und ein Schalter als Zündung, der den Motor entweder ein‐ oder ausschaltet. Demnach ist Coming Home/ Leaving Home bei uns so realisiert, dass wenn wir mithilfe des Schalters für die Spannungsversorgung den Bus „aufschließen“ die LEDs angehen und wenn wir den Schalter wieder in die andere Richtung betätigen, die LEDs wieder ausgehen und demnach das Abschließen des Busses verdeutlichen. Durch den im Inneren des Busses befindlichen Schalter für die Zündung, wird der Bus je nach Bedarf ein‐ oder ausgeschaltet und zum Fahren oder Stehen gebracht. 

Schaltplan bei Fritzing

#include <TM1637Display.h>     // Bibliothek für die 7- Segment Anzeige

 

#define echo 25                        //Anschluss ECHO vom HC-SR04 wurde für PIN 25 festgelegt

#define trig 33                          //Anschluss TRIG vom HC-SR04 wurde für PIN 33 festgelegt

 

#define display_clk 16               //Anschluss CLK von der Anzeige wurde für PIN 16 festgelegt

#define display_dio 13              //Anschluss DIO von der Anzeige wurde für PIN 13 festgelegt

 

#define passiver_buzzer 27       //Der PIN für den passiven Summer wurde auf 27 festgelegt

 

//Pinbelegung für die H-Brücke

int inc1 = 18;

int inc2 = 19;

int motor = 17;

 

//Entfernung als globale Variable anlegen

int entfernung = 0;

 

//schalter

int schalter = 2;

int schalterStatus = 0;

 

//Pulsweitenmodulation

const int freq = 30000;

const int resolution = 8;

 

 

//Funktion zur Messung der Entfernung über den Ultraschallsensor HC-SR04 (mit Echo und Trigger), Einheit: cm

int getEntfernung()

{

  long entfernung = 1;

  long zeitx = 0;

 

  digitalWrite (trig, LOW);           //setzt den Zustand von trig auf LOW

  delayMicroseconds(3);             //setzt eine Pause/Unterbrechung von 3 Mikrosekunden

  noInterrupts();                         //keine Unterbrechung

  digitalWrite(trig, HIGH);            //setzt den Zustand von trig auf HIGH

  delayMicroseconds(10);           //setzt eine Pause/Unterbrechung von 10 Mikrosekunden

  digitalWrite(trig, LOW);            //setzt den Zustand von trig auf LOW

  zeitx = pulseIn(echo, HIGH);    //setzt den Zustand von echo auf HIGH

  interrupts();                             //unterbricht den Vorgang

  zeitx = (zeitx / 2);                     //teilt die Zeit durch 2

  entfernung = zeitx / 29.1;        //teilt die Restzeit durch die Geschwindigkeit des Schalls

  return (entfernung);                 //gibt die berechnete Entfernung zurück

}

// Funktion zur Antriebssteuerung ---> mit geringer werdendem Abstand soll der Motor langsamer laufen

void antrieb(int entfernung)

{

  if ((entfernung <= 50) && (entfernung >= 25))

  {

    digitalWrite(inc1, LOW);                                //Laufrichtung einstellen

    digitalWrite(inc2, HIGH);                                //

    ledcWrite(2, 230);                                         // Sendet ein Signal an den Channel 2 mit einem Duty Cyle(Auslastungsgrad) von 230

  }

 

  else if ((entfernung <= 24) && (entfernung >= 5))

  {

    digitalWrite(inc1, LOW);                                //Laufrichtung einstellen

    digitalWrite(inc2, HIGH);                                //

    ledcWrite(2, 200);                                         //Sendet ein Signal an den Channel 2 mit einem Duty Cyle(Auslastungsgrad) von 200

  }

 

  else if (entfernung < 5)

  {

    digitalWrite(inc1, LOW);                                //Laufrichtung einstellen

    digitalWrite(inc2, HIGH);                                //

    ledcWrite(2, 0);                                             // Motor steht

  }

 

  else

  {

    digitalWrite(inc1, LOW);                                //Laufrichtung einstellen

    digitalWrite(inc2, HIGH);

    ledcWrite(2, 255);                                         //Sendet ein Signal an den Channel 2 mit einem Duty Cyle(Auslastungsgrad) von 255

  }

}

 

//LEDs Wann sie Leuchten in abhängigkeit der Entfernung

void bremslicht (int entfernung)

{

  if (entfernung <= 5)

  {

    digitalWrite(LED_bremslicht, HIGH);

    digitalWrite (LED_licht, HIGH);

  }

  else if (entfernung > 5)

  {

    digitalWrite(LED_bremslicht, LOW);

    digitalWrite(LED_licht, HIGH);

  }

}

// Funktion zur Tonsteuerung ---> mit geringer werdendem Abstand soll sich die Tonfrequenz höher werden

void sound(int entfernung)

{

  // die Entfernungsabstände können beliebig angepasst werden

  if ((entfernung <= 50) && (entfernung >= 25))

  {

    ledcWriteTone(1, 300);

    delay(10);

  }

 

  else if ((entfernung <= 24) && (entfernung >= 15))

  {

    ledcWriteTone(1, 800);

    delay(5);

  }

 

  else if ((entfernung <= 14) && (entfernung >= 6))

  {

    ledcWriteTone(1, 1300);

    delay(2);

  }

 

  else if (entfernung <= 5)

  {

    ledcWriteTone(1, 1700);

    delay(1);

  }

 

  else

  {

    ledcWriteTone(1, 0);

    delay(1);

  }

}

TM1637Display display(display_clk, display_dio);

 

 

void setup()

{

  pinMode(trig, OUTPUT);                      //Legt den Eingangstyp des angegebenen PINs fest

  pinMode(echo, INPUT);                       //Legt den Eingangstyp des angegebenen PINs fest

  pinMode(passiver_buzzer, OUTPUT);   //Legt den Eingangstyp des angegebenen PINs fest

  pinMode(motor, OUTPUT);                  //Legt den Eingangstyp des angegebenen PINs fest

  pinMode(inc1, OUTPUT);                     //Legt den Eingangstyp des angegebenen PINs fest

  pinMode(inc2, OUTPUT);                     //Legt den Eingangstyp des angegebenen PINs fest

  pinMode(LED_bremslicht, OUTPUT);   //Legt den Eingangstyp des angegebenen PINs fest

  pinMode(LED_ruecklicht, OUTPUT);    //Legt den Eingangstyp des angegebenen PINs fest

  pinMode(schalter, INPUT);                   //Legt den Eingangstyp des angegebenen PINs fest

 

  ledcSetup(1, freq, resolution);              // Konfigurieren der Pulsweitenmodulation für Channel Sound

  ledcAttachPin(passiver_buzzer, 1);      //passiver Buzzer mit PWM-Channel verbinden

 

  ledcSetup(2, freq, resolution);              //Konfigurieren der Pulsweitenmodulation für Channel Antrieb

  ledcAttachPin(motor, 2);                      //Motor mit dem PWM-Channel verbinden

}

 

 

void loop()

{

  schalterStatus = digitalRead(schalter); //setzen vom Schalterstatus

 

  if (schalterStatus == HIGH)                  //starten der UPs, wenn der Schalter betätigt wurde

  {

    antrieb(entfernung);                            //Aufruf der Funktion zum Antrieb des Motors

    entfernung = getEntfernung();           //Aufruf der Funktion zum Messen der Entfernung

    sound(entfernung);                             //Aufruf der Funktion zum Ansteuern des passiven Buzzers

  }

  else

  {

    digitalWrite(inc1, LOW);                     //Laufrichtung einstellen  

    digitalWrite(inc2, HIGH);                     //

    ledcWrite(2, 0);                                   //Motor steht

    ledcWriteTone(1, 0);                           //pasiver Buzzer Aus

  }                                            

    bremslicht(entfernung);                      //Aufruf der Funktion für die LED´s 

 

//Einstellungen für die 7 Segment Anzeige

  display.setBrightness(7);

  display.showNumberDec(entfernung);

  delay(20);

}

Projektbeschreibung

  • Einführung
  • Auftrag
  • Vorausschau
  • Inhalte
  • Kompetenzen
  • Projektablauf
  • Materialplanung
  • Motivationsfaktoren

Funktionsbeschreibung

Elektrotechnik/ Elektronik

Microcontroller programmieren

3D-Konstruktion und rapid prototyping

Projektmanagement und Teamfähigkeit

Projektpräsentation


Im Projekt Erweiterung des Monitoring Projektes wird das Basis Projekt Monitoring um eine simulierte Temperaturregelung erweitert.

Fällt die Temperatur in einen der Vordefinierten Bereiche wird entweder eine Heizung simuliert oder eine Kühlung simuliert.

Die Temperatur des T1 soll überwacht werden. Die Anzeige der Temperatur wird über eine 4-stellige 7-Segment Anzeige erfolgen. Zudem lässt sich dann der Temperaturwert über den seriellen Monitor beobachten. 

Wird eine oberer Temperaturgrenze überschritten so wird die simulierte Kühlung aktiviert. Wird eine untere Temperaturgrenze unterschritten so wird die simulierte Heizung aktiviert.

In unserem Projekt haben wir die untere Temperaturgrenze bei 22°C und die obere Temperaturgrenze bei 27°C in der Programmierung definiert. Die Temperatur lässt sich außerhalb des Programms nicht einstellen.

Draufsicht des fertigen Projekt T1-Busses mit der eingebauten Temperaturregulierungsanlage


In dem Lehrgang werden folgende Inhalte bearbeitet:

  • digitale Temperaturerfassung
  • Anzeigen von Werten (Digitalanzeige)
  • Anschluss und Verwendung von Sensoren
  • Programmierung mit Bibliotheken
  • Programmierung von "If-Then-Else" befehlen (Auswertung Temperaturbereiche)
  • Transistorschaltung (für Ansteuerung der Motorsteuerung benötigt)
  • Nutzung eines MosModuls (Mosfet IRF520 // Motoransteuerung)
  • Ansteuerung von LED's

Folgende Kompetenzen wurden erlernt, verbessert bzw. werden benötigt:

  • Erstellen und berechnen einer Transistorschaltung (Spannungsverstärkung)
  • Programmieren in Arduino
  • 3D Konstruktionen
  • Teamfähigkeit

  1. Ideenfindung:
    • Wie kann man das Basisprojekt Monitoring am besten erweitern?
      • Auswerten der Temperatur und diese für neue Bauteile nutzbar machen
  2. Planen der Umsetzung:
    • Zeitlichen Ablauf planen
    • Teilabschnitte planen und definieren
  3. Umsetzen der Teilabschnitte
    • Schaltung und Breadboardlayout planen, erstellen und aufbauen
    • 3D Konstruktionen der Bauteile erstellen und drucken
    • Aufbauen des vollständigen Projektes
  4. Testen des Projektmodells
  5. Projekt abschließen

Materialliste:

    • Jumper Kabel (Male-Male; Male-Female; Female-Female) 
    • Temperatursensor Typ DS18B20 (DellasTemperature) 
    • Widerstände (verschiedene Größen) 
    • Transistor BC550C 
    • MosModul (Modul zur Ansteuerung des Motors) 
    • Mosfet IRF520 (Auf MosModul verbaut) 
    • LEDs (Blau, Rot) 
    • ESP32 Mikrocontroller 
    • DC-Motor (für die Lüftung) 
    • Digitale 7-Segmentanzeige 
    • Batterie 9V Block 

                        Folgende Faktoren haben uns in diesem Projekt Motiviert:
                        • Bereits bestehendes Projekt erweitern und verbessern
                        • Eigene Idee ERFOLGREICH umsetzen
                        • Neue Erfahrungen Sammeln; Erfahrungshorizont erweitern
                        • Einzelne kleine erfolge im Projektablauf (Motivation durch Erfolg)

                        Um die Funktion zu starten, wird der ESP32 Mikrocontroller über die USB-Schnittstelle mit Spannung versorgt. Über den Mikrocontroller wird danach auch der Temperatursensor (DS18B20) mit Spannung versorgt und beginnt damit, die Umgebungstemperatur in Echtzeit zu messen. Die Daten des Temperatursensors werden daraufhin an den Mikrocontroller über einen OneWire-Bus (Einzelne Leitung zur Datenverbindung) übermittelt. Gleichzeitig übersetzt der Mikrocontroller mit Hilfe einer im Programm installierten Bibliothek die Daten in einen Temperaturwert. Dieser Temperaturwert wird daraufhin über die digitale 7-Segmentnzeige ausgegeben. 

                        Im nächsten Schritt wertet der Mikrocontroller aus, ob sich die Temperatur in einem vordefinierten Bereich befindet.  

                        Unterschreitet die Temperatur den Grenzwert von 22°C, wird das Signal gegeben zu heizen. Hierzu wird eine Rote LED eingeschaltet, welche dazu verwendet wird, die Heizung zu simulieren. Zusätzlich wird über den Seriellen Monitor eine Nachricht ausgegeben, dass die Temperatur zu niedrig ist und somit die Heizung aktiviert wird. Wenn während des Heizprozesses die Temperatur weiter sinkt, wird über den Seriellen Monitor zusätzlich eine Warnung ausgegeben. Die Warnung beinhaltet eine Meldung, dass die Temperatur zu kalt wird, sobald 17°C unterschritten werden. 

                         

                         

                        Wenn die Temperatur den Grenzwert von 27°C überschreitet, wird das Signal gegeben zu kühlen. Um dies zu simulieren, wird eine Blaue LED eingeschaltet. Zusätzlich wird der Lüfter aktiviert um so einen Luftstrom zu erzeugen um die Kühlung zu unterstützen. Die Ansteuerung des DC-Motors für den Lüfter erfolgt über ein MosModul, welches über eine Transistorschaltung zur Spannungsverstärkung am Signal-Pin angesteuert. Die Spannungsverstärkung wird benötigt, damit das auf dem MosModul verbaute Mosfet (Typ: IRF520) den benötigten Strom für den DC-Motor schalten kann. Der DC-Motor wird extern über den 9V-Block mit Spannung versorgt. Dies ist notwendig, da über den Mikrocontroller keine Spannung in dieser höhe zur verfügung gestellt werden kann. Des Weiteren wird über den Seriellen Monitor eine Nachricht ausgegeben, dass die Temperatur zu hoch ist und somit die Kühlung aktiviert wird. Sollte die Temperatur während des Kühlungsprozesses weiter steigt und die Grenze von 32°C überschreiten, wird über den  Seriellen Monitor zusätzlich eine Warnung ausgegeben. Die Warnung beinhaltet die Informatio, dass die Temperatur zu Warm wird. 

                        Unter der Vorausgesetzung, dass die Temperatur zwischen 22°C und 27°C liegt, ist weder die Heizung noch die Kühlung aktiv. 


                        Schaltbild:


                        Breadboardlayout:



                        !!!Benötigte Bibliotheken aus Basisprojekt "Monitoring" integrieren!!!

                        Quellcode inkl. Kommentare zur Programmierung des ESP32 über Arduino:

                        #include <OneWire.h>

                        #include <DallasTemperature.h>

                        #include <TM1637Display.h>


                        //Daten-Pin für den Temperatursensor festlegen

                        #define temperatureSensorPIN 32


                        //Daten- und Taktpin des Displays festlegen und Initialisierung des Displays

                        #define CLK 23

                        #define DIO 25

                        TM1637Display display(CLK, DIO);


                        //Temperatursensor initialisieren

                        OneWire temperatureSensorWire(temperatureSensorPIN);

                        DallasTemperature temperatureSensor(&temperatureSensorWire);


                        //Pin LED WARM

                        #define WarmLedPin 17


                        //Pin LED KALT

                        #define KaltLedPin 18


                        //Motor Belüftung

                        #define MotorPin 19


                        void setup() 

                        {

                          //Temperatursensor starten

                          temperatureSensor.begin();



                          //Helligkeit des Displays einstellen

                          display.setBrightness(0x0f);


                          //Seriellen Monitor mit einer Baudrate von 115200 starten

                          Serial.begin(115200);


                          //Digitalpin Output

                          pinMode(17, OUTPUT);

                          pinMode(18, OUTPUT);

                          pinMode(19, OUTPUT);

                          

                        }


                        void loop() 

                        {

                          //Temperatur in °C erfassen

                          temperatureSensor.requestTemperatures();

                          float tC = temperatureSensor.getTempCByIndex(0);



                          //Temperatur in °C mit einer Nachkommastelle auf dem Display anzeigen

                          display.showNumberDec(tC * 10);


                          //Temperatur in °C ohne Nachkommastelle auf dem Display anzeigen

                          //display.showNumberDec(tC * 1);


                          //Temperatur auf dem seriellen Monitor ausgeben

                          Serial.print(tC);

                          Serial.println(" °C");

                          delay(500);

                          

                          //Kühlung

                          if (tC >= 30) {

                          Serial.print("Erhöhte Tempertur, Kühlung aktiviert");

                          digitalWrite (KaltLedPin, HIGH);

                          digitalWrite (MotorPin, LOW);

                          }

                          else if (tC >= 35) {

                          Serial.print("TEMPERATUR IM KRITISCHEN BEREICH");

                          digitalWrite (MotorPin, LOW);

                          digitalWrite (KaltLedPin, HIGH);

                          delay(200);

                          digitalWrite (KaltLedPin, LOW);

                          delay(200);

                          }

                          else {

                          digitalWrite (KaltLedPin, LOW);

                          digitalWrite (MotorPin, HIGH);

                          }


                          //Heizung

                          if (tC <= 20) {

                          Serial.print("Niedrige Temperatur, Heizung aktiviert");

                          digitalWrite (WarmLedPin, HIGH);

                          }

                          

                          else if (tC <= 15) {

                          Serial.print("Temperatur wird zu kalt");

                          digitalWrite (WarmLedPin, HIGH);

                          delay(200);

                          digitalWrite (WarmLedPin, LOW);

                          delay(200);

                          }

                          

                          else {

                          digitalWrite (WarmLedPin, LOW);

                          

                        }

                        }

                        1. Halterung für das Breadboard:

                        2. Halterung für LED's:

                        3. Halterung für DC-Motor:

                        4. Rotor für die Lüftung:

                        Vorgehen im Bereich des Projektmanagement:

                        • Agiles Projektmanagement verwendet
                        • Nutzen der Scrum Methoden
                        • Verwenden eines Kanban-Boards


                        Teamfähigkeit im verlauf des Projektes:

                        • Kennlernphase
                        • Einarbeitungsphase
                        • Koordinierung einzelner Aufgaben untereinander

                        Fazit/Zusammenfassung: 

                        Abschließend lässt sich zusammenfassen, dass die Funktion der automatischen Temperaturregulierung für einen vordefinierten Bereich, wie geplant umgesetzt worden ist. Es ist sinnvoll einen offenen Temperaturbereich zu wählen, in dem weder gekühlt noch geheizt wird. Dieser offene Temperaturbereich liegt zwischen 22°C und 27°C. Somit wird vermieden, dass die Funktion durchgehend zwischen kühlen und heizen wechseln muss. Dadurch kann auch Energie in der Funktion gespart werden, wenn sich die Temperatur zwischen 22°C und 27°C aufhält. Die fachliche Schwierigkeit in diesem Projekt, lag im Programmieren und Konstruieren. Durch das Projekt konnten wir unsere Fachkenntnisse im Programmieren und Konstruieren vertiefen. Die Schwäche in unserem Projekt, liegt daran das man seine persönliche wohlfühle Zone nicht einstellen kann. Sondern sie ist von uns von uns Angegeben. Da jeder Mensch unterschiedlich denkt und fühlt und sich in Unterschiedlichen Temperaturen wohl fühlt. Ist das Produkt nicht für den Markt geeignet und diente uns rein zum Lernen. Sollte man das Projekt jedoch mit einem Regler weiterentwickeln und somit die Temperatur einstellen können, könnte man es in unseren Augen durchaus auf dem Markt bringen. Die Zusammenarbeit im Team war anfangs schwierig, da man sich nicht wirklich kannte. Doch zum Ende waren alle Kollegen so motiviert, dass Wir das Projekt erfolgreich abschließen konnten. Daraus gelernt haben wir das Zusammenarbeit und Ehrlichkeit, sowie vertrauen und Zuverlässigkeit zum Erfolg führt. Da wir erst angefangen haben mit der Techniker Schule, freuen Wir uns auf zukünftige Projekte und sind dankbar für die Erfahrungen, die wir sammeln durften. 


                        Projektbeschreibung

                        • Einführung
                        • Auftrag
                        • Inhalte
                        • Kompetenzen
                        • Projektablauf
                        • Materialplanung
                        • Motivationsfaktoren

                        Funktionsbeschreibung

                        Elektrotechnik/ Elektronik

                        Microcontroller programmieren

                        3D-Konstruktion und rapid prototyping

                        Projektmanagement und Teamfähigkeit

                        Projektpräsentation

                        Fotodokumentation


                        Wir als Gruppe Mark Mallon, Ali Jfeily und Dennis Ackermann besuchen die Fachschule Technik der BBS 2 Wolfsburg, Schwerpunkt Elektrotechnik. Dabei bearbeiten wir ein T1-Bus Modell im Maßstab 1:18, welcher im Ursprung ein Stiftehalter ist. Wir nutzen die zusammengesteckte Karosserie aus Holz für die Modifikation. Durch unser erstes Projekt haben wir schon einige Veränderung vorgenommen und rüsteten den Modell T1 Bus mit einer Alarmanlage sowie mit einer Lichtsteuerung aus. Bei unserem aktuellen Projekt haben wir nicht auf unserem vorangegangenen aufgebaut, sondern wollten etwas komplett Neues kreieren, damit ein Wachstum an Wissen generiert wird. 

                         Der nächste Schritt in der Automobilindustrie ist das autonome Fahren und das machen wir uns zu eigen bzw. bauen unser Projekt danach auf. Unser Gedanke ist es ein Fahrzeug zu schaffen, welches allein fahren kann, Hindernisse selbstständig erkennt und ausweicht mit den Features der Sound und LED-Anzeige für den jeweils gemessenen Abstand zu realisieren.

                        Es soll ermöglicht werden, dass der T1 Bus bei erkannten Hindernissen sich einen freien Weg sucht. Dies soll durch einen Servomotor mit dem Ultraschallsensor realisiert werden.  Durch das Zusammenspiel des Sensors und des Antriebs soll es möglich sein den T1 Teilautonom fahren zu lassen.

                        In dem Lehrgang werden folgende Inhalte bearbeitet:

                        • Distanzmessung
                        • Hinderniserkennung
                        • Anschluss und Verwendung von Sensoren
                        • Ansteuerung eines Servomotors
                        • Programmierung mit Bibliotheken

                        Projektplanung gestalten
                        Projektdokumente erstellen
                        Problemlösungen finden 
                        Programmieren mit Arduino 
                        Konstruieren mit Catia/Fusion 360 
                        Arbeiten mit Cura und 3D Drucker 
                        Kenntnisse in Arduino und CATIA/FUSION 360 erweitern
                        Arbeiten mit Fritzing bzw. Schaltplan Erstellung 


                        - Den Ultraschallsensor aufbauen und programmieren
                        - Das 7-Segment-Display ebenso aufbauen und programmieren
                        - Die gemessenen Werte über das 7-Segment-Display anzeigen lassen
                        - Den Summer (Buzzer) und die LED's in das Programm integriert
                        - Ansteuerung des DC-Motors über den Motortreiber

                        - 4-stellige 7-Segment Anzeige(TM1637)
                        - Ultraschallsensor(HC-SR04)
                        - Antriebsmotoren(DC-Motor)
                        - Servomotor(MS18)
                        - Motortreiber(L293D)
                        - ESP 32 Mikrocontroller
                        - Breadboards
                        - Leitungsset Male – Male
                        - Leitungsset Male – Female
                        - Stiftebox T-1 Modell
                        - PETG für den 3D- Drucker
                        - Widerstände(220Ω,2KΩ)
                        - Buzzer
                        - LED‘s (grün, gelb, rot)

                        Project: Autonomes Fahren 

                        In diesem Projekt geht es darum viele der einzelnen erworbenen Kompetenzen zu kombinieren, um das erwünschte Ziel zu erreichen. Nicht nur wird hier auf die Ansteuerung von mehreren Motoren  eingegangen , auch wird sich hier mit einen Ultraschallsensor, dessen Auslesen und dem Anzeigen von Werten beschäftigt. Die Fähigkeit jederzeit auf die erworbenen Kenntnisse zurückzugreifen und diese in verschiedenen Kontexten einzubringen ist, vor allem im Beruf (Profession), eine sehr hilfreiche und gefragte Fähigkeit.

                        Weitere Motivationsfaktoren für dieses Projekt sind:

                        -Zusammenarbeit und Problemlösung gemeinsam im Team
                        -Entwicklung der eigenen Fähigkeiten 
                        -Neue innovative Ideen umzusetzen  

                        Zuerst haben wir uns Gedanken gemacht über den Aufbau und die dafür benötigten Teile. Uns war klar, dass wir außerhalb unseres gekauften Starterkits Teile/Module benötigen. Es gilt die Hürde zu überwinden das Fahrzeug flexibel und dynamisch lenken zu lassen, um die Fehlerquote so klein wie möglich zu halten. Wir haben uns entschieden das Fahrzeug auf Kettenrädern fahren zu lassen nach Vorbild eines Panzers. Dies ermöglicht uns das Fahrzeug aus dem Stand 360° Grad zu drehen und sind somit deutlich flexibler gegenüber einer eingebauten Lenkungsachse. Umgesetzt wird das durch zwei Gleichstrommotoren, die jeweils ein Rad pro Seite diagonal zueinander antreiben. Die Gleichstrommotoren werden durch einen eigens dafür konstruierten Motorhalter am Fahrzeug gehalten und befestigt. Dieser Motorhalter wird durch das 3D-Druck Verfahren hergestellt und ist gleichzeitig auch die Bodenplatte des Fahrzeugs. Dieser Aufbau macht es möglich das Fahrzeug geradeaus fahren zu lassen. Mit den Kunststoffketten können zwei angetriebene Räder, vier weitere antreiben, wodurch wir mehr Drehmoment und Leistung entwickeln können. Die Kettenantriebe sind von Lego Technic, die aus dem Internet bestellt worden sind. Angesteuert werden diese Motoren über den Motortreiber, welcher wiederum über den Microcontroller ESP32 gesteuert wird. Hierfür haben wir unser Wissen über den Motortreiber erweitert, um den passenden für unser Vorhaben zu verbauen. Wir steuern zwei Motoren gleichzeitig an, da der im Starterkit enthaltene Motortreiber dafür nicht ausreicht. Wir benötigen für den Motortreiber noch eine zusätzliche Spannungsquelle, damit dieser funktioniert. Die Spannungsquelle wird durch ein 9 V Blockbatterie realisiert. Die Blockbatterie wird in einer Batteriehalterung im Fahrzeug verstaut. Der Microcontroller ESP32 steuert den Motortreiber an, welcher dann den Arbeitsstrom der externen Spannungsquelle freigibt, damit der T1-Bus fahren kann.5 Dennis Ackermann, Mark Mallon, Ali Jfeily ESP-32 Motortreiber DC-Motor Für die Umsetzung des autonomen Fahrens benötigen wir noch einen Ultraschallsensor am Vorderwagen, der die Entfernung in regelmäßigen Abständen misst. Der Ultraschallsensor misst die Entfernung, indem ein Ausgangston erzeugt wird und die Zeit zwischen dem Ausgangston und Echo gemessen wird. Aus diesem Wert errechnet der ESP32 mit Hilfe einer Formel dann die Entfernung. Damit unser Fahrzeug schließlich auch allein fahren kann, muss es möglich gemacht werden, dass der Ultraschallsensor sich drehen kann. Ein Servomotor bietet uns die Möglichkeit dafür. Der Ultraschallsensor wird durch ein 3D-gedruckten Halter am Servomotor befestigt. Dadurch können wir den Ultraschallsensor in jede Position bringen. Der Servomotor und der Ultraschallsensor werden durch ein 3D-gedrucktes Teildach am Vorderwagen befestigt.6 Dennis Ackermann, Mark Mallon, Ali Jfeily Eine weitere Funktion ist es sich den Abstand zu einem Hindernis akustisch und visuell ausgeben zu lassen, anhand des vom Ultraschallsensors gemessenen Weges zum Objekt. Bei Annäherung eines Hindernisses gibt ein Summer einen immer schneller werdenden Ton von sich, wie man dies auch bei vielen Kraftfahrzeugen heutzutage vorfindet. Anschließend wird der Abstand optisch über eine Reihe LED's angezeigt, welche sich farblich ändern bei bestimmt erreichten Abständen. Die Abstände sind im Programm des ESP 32 hinterlegt und sind in Fahrversuchen erprobt und entwickelt worden. Während der farblichen Änderung der LED ́s wird gleichzeitig die gemessene Distanz über eine 7-Segment-Display angezeigt. Das fertige Projekt fährt allein geradeaus und stoppt bei einem erkannten Hindernis. Der Servomotor muss anschließend den Ultraschallsensor erst nach links und dann nach rechts drehen. Dabei wird jeweils der Abstand der beiden Seiten gemessen. Die Seite, die am meisten Freiheit bietet, wird als freier Weg ausgewählt. Dadurch lässt das Fahrzeug die Motoren im Stand in diese Richtung drehen und anschließend weiterfahren, bis er das nächste Hindernis erkennt. Danach beginnt die Funktion von vorn.

                        Die Halter und die Bodenplatte wurden mit Fusion 360 erstellt. Die Dateien wurden mit Cura in einen G-Code umgewandelt und an den 3D-Drucker gesendet.


                        PLA VS. PETG

                        • PLA ist in der Handhabung einfacher als PETG-Filament. PLA verzeiht auch kleine Druckfehler.

                        • Beide Materialien haben keinen hohen Materialverzug, wenn sie nach dem Drucken abkühlen.

                        • Beide Materialien gelten als lebensmittelecht.

                        • PETG ist haltbarer und robuster und kann höheren Belastungen standhalten.

                        • PLA zerkratzt nicht so leicht und hat eine stabilere Oberfläche.

                        • PETG-Filament ist in der Regel teurer als PLA-Filament

                        • PLA ist in mehr Variationen zu haben.



                        Teamfähigkeit:

                        Problemlösung durch gute Kommunikation

                        Aufgaben & Meilensteine gut gemeistert

                        Gegenseitige Hilfsbereitschaft innerhalb der Klasse

                        Zuverlässigkeit, Harmonie & Spaß innerhalb des Teams

                        Projektmangement:

                        Projektmanagement wurde in Form von einem Kanban Board und ein Gantt Diagramm betrieben. ​




                        Agenda


                        10.1 Einführung

                        10.2 Projektbeschreibung

                        10.3 Projektablauf

                        10.4 Materialliste

                        10.5 3D-Druck

                        10.6 Fritzing Schaltplan

                        10.7 Arduino Sketch

                        10.8 Funktionsnachweis

                        10.9 Erlernte Kenntnisse

                        10.10 Aufgetretene Probleme

                        10.11 Fazit

                        10.12 Quellen



                        Projekt VW Bulli TYP T1     

                        Im Rahmen unserer Weiterbildung zum staatlich geprüften Techniker im Maschinenbau an der BBS2 Wolfsburg , haben wir die Aufgabe bekommen ein Fahrzeugmodell VW Bulli Typ T1 als Stiftebox per Additiver Fertigung sowie Digitalisierung zu erweitern.

                        Die Realisierung des Projekts findet in den Fächern M1PR und M1PRM statt, zur Teambildung wurden idealerweise zwei Techniker aus der Fachrichtung Elektronik und ein Techniker aus der Fachrichtung Mechanik zusammengelegt.

                        Bei dem IST-Zustand handelt es sich um eine Stiftebox im Original Zustand.

                        Wir haben uns bei dem Projekt dafür entschieden die Heckklappe und den Motordeckel mit einer Automatischen Öffnung und Schließung zu versehen, sowie das Fahrwerk samt Bereifung additive zu Fertigen.

                        Die Umsetzung für die Steuerung der Automatischen Öffnung u. Schließung erfolgt über einen ESP32 sowie Programmierung via Arduino.

                        Ein Teil der zu druckenden Konstruktionsteile beziehen wir von der Seite Explore-DNA.de, der andere Teile wird via CATIA V5 konstruktiv erstellt und anschließend mit der Slicer Software CURA in einen für den 3D-Druck lesbaren G-CODE umgewandelt.

                         

                        Additive Fertigung (3D Druck u. Montage)

                        Hier beschäftigen wir uns mit der additiven Fertigung und Montage des Models.

                        Von dem VW Bulli T1 l wird es drei verschiedene Ausführungen geben, da verschiede Filamente zum Einsatz kommen. Hergestellt werden Fahrwerk, Heckklappe inkl. Heckscheibe und Motordeckel. die Fertigung des Fahrwerks wird auf bestehende STL. Dateien von der Internet Seite Explore-DNA.de zurückgegriffen. Das VW Bulli T1 Modell hat bereits alle notwendigen Aussparungen für das Fahrwerk, die Öffnungen für Heckklappe und Motordeckel werden mit einem Lasercutter mm genau ausgeschnitten. Das Fahrwerk bestehend aus: 1 Halter Lenkung, 2 Lenkungsträger, 2 Lenkungsstifte inkl. Kappe, 4 Felgen + Reifen, 2 Achse Lenkung, 2 Achse Motor, Motorhalter, sowie 2 Lenkverbinder Servo werden dafür verwendet. Die Heckklappe inkl. Heckscheibe und Motordeckel werden mit dem Konstruktionsprogram Shapr 3D erstellt. Nachdem alle benötigten Bauteile bereitstehen, werden die Dateien mit dem Slicer Programm CURA für den 3D-Drucker in ein Lesbares Format Umgewandelt.

                        Bei der additiven Fertigung des Fahrwerks, Heckklappe u. Motordeckel wird auf folgende Filamente mit entsprechenden Slicer Einstellungen zurückgegriffen, da wäre zuerst das Standardfilament PLA in Schwarz mit den Einstellung  Drucktemperatur 200 C°, Druckplatten 60 C° und Druckgeschwindigkeit 80mm/s als zweites ein Holz Filament  mit den Einstellung Drucktemperatur von 180 C°, Druckplatten Temperatur von  55 C° und in einer Druckgeschwindigkeit von 100mm/s   und als letztes ein Carbon Filament mit 15% Kohlefaseranteil mit den Slicer Einstellung Drucktemperatur von 200 C°, Druckplatten Temperatur von  60 C° und in einer Druckgeschwindigkeit von 80mm/s. Bei der additiven Fertigung der Heckschreibe wird auf ein Transparents PLA Filament zurückgegriffen, hier werden die Einstellung  Drucktemperatur von 220 C°, Druckplatten Temperatur von  66 C° und in einer Druckgeschwindigkeit von 60mm/s. verwendet. Die Fertigung der Reifen wird durch ein TPU Filament umgesetzt, es besitzt eine gummiartige Elastizität, hohe Reiß- und Abriebfestigkeit. Hier liegen die Slicer Einstellungen bei einer Drucktemperatur 210 C°, Druckplatten Temperatur  60 C° und einer Druckgeschwindigkeit von 60mm/s. Nach dem Druck aller  Teile mit dem  Creality CR-10S Pro V2 Drucker abgeschlossen ist, wird der Lenkungshalter für die Vorderachse an der Unterseite des Modells verschraub, anschließend werden die beiden Lenkungsträger links und rechts eingesetzt und mit Lenkungsstiften und Abschlussdeckel gesichert. Als nächstes werden die Achsen für die Lenkung mit den Achsträgern und den Felgen verbunden und die Reifen auf die Felge gezogen. Für die Hinterachse wird erst die Motorhalterung am Boden verschraubt und der Motor eingesetzt, jetzt werden die 2 Achsen für den Motor am Motor und Felgen montiert. Als letztes folgt die Montage der Heckklappe und des Motordeckels, hierzu wird die hergestellte Heckscheibe passgenau in die Öffnung der Heckklappe hineingedrückt. Die Hecklappe und der Motordeckel werden jetzt auf die Aussparung des Hecks gelegt und die Scharniere werden mit Sekundenkleber an der Karosse des Models befestig.

                         

                        Programmierung

                        Wir haben uns dafür entschieden die Heck und Motorklappen über Servomotoren mit Schaltern zu öffnen und außerdem eine Alarmanlage einzubauen. Wir haben mehrere Möglichkeiten dies zu realisieren. Zum einen können wir einen Halter für die Servomotoren Drucken und diesen über eine Stange mit der Heckklappe zu verbinden. Die Zweite Möglichkeit ist den Servomotor an den Bus zu kleben und mit dem Gestänge des Motors die Klappen betätigen. Wir haben uns für die zweite Variante entschieden da es einfacher aufzubauen ist und wir weniger Materialien benötigen. Anschließend haben wir uns überlegt welche Bauteile wir Benutzen. Für die LEDs benötigen wir noch passende Vorwiderstände, diese haben wir berechnet. Danach haben wir eine Schaltplan in Fritzing (Programm für Schaltpläne) erstellt.  Als nächstes Folgt die Programmierung des ESP in Arduino.  Für die Alarmanlage haben wir Inspirationen aus Xplore-DNA genommen.  Da wir uns mit dem Servomotor noch nicht auseinander gesetzt haben besorgen wir uns Informationen über die Programmierung. Zuerst haben wir die Alarmanlage programmiert und getestet.. nach der erfolgreichen Prüfung beginnen wir mit den Motoren. Hier war die Besonderheit das der Motor sich nur maximal 90 Grad bewegen darf. Nach dem ersten Test ist uns aufgefallen das die Geschwindigkeit des Motors so schnell ist dass die Gefahr besteht das die Heckklappe abreißt. Anschließend haben wir ein Programm geschrieben mit dem die Geschwindigkeit des Motors runtersetzt.  Nach Erfolgreichem Test muss alles nur noch in den T1-Bus eingebaut werden.  Nun haben wir das ESP32 auf die Steckplatine gesetzt, und  die LEDs mit passenden Vorwiderständen in den T1-Stiftehalter eingebaut. Danach  haben wir die Servomotoren positioniert und Angeklebt. Nachdem alles angeschlossen war wurden die 3D-Gedruckten Teile (Achsen Vorne + Hinten Motor/Heckklappe) angebaut. Zuletzt testen wir nochmal die Funktion.

                         

                         

                         

                         

                         

                         

                         

                         

                         


                         Projektbeschreibung

                        ■ Automatisierte Heckklappen Öffnung und Schließung
                        ■ Warnblinklicht bei Annäherung des T1
                        ■ Fahrwerk Konstruktion
                        ■ Umsetzung über den ESP32 und Programmierung via Arduino

                        Projektablauf

                        ■ Projektthema aussuchen
                        ■ Schaltplan in Fritzing erstellen
                        ■ 3D-Druck
                        ■ Programmierung Arduino
                        ■ Schaltung aufbauen
                        ■ Funktionsprüfung
                        ■ Montage Bus
                        ■ Dokumentation erstellen



                        Lasercutter

                        CAD



                         Konstruktion




                        Slicing + G-Code







                        Additive Fertigung der Vorderachse


                        Material: PLA Schwarz

                        Drucktemperatur: 200 °C

                        Temperatur Druckplatte: 60 °C

                        Druckgeschwindigkeit: 80 mm/s


                        Material: PLA Holz 30% Holz Anteil

                        Drucktemperatur: 180 °C

                        Temperatur Druckplatte: 55 °C

                        Druckgeschwindigkeit: 100 mm/s


                        Additive Fertigung der Reifen



                        Material: TPU Filament

                        Drucktemperatur: 210 °C

                        Temperatur Druckplatte: 60 °C

                        Druckgeschwindigkeit: 60 mm/s


                        Additive Fertigung aus Carbon



                        Material: PLA Carbon 15% Kohlefaseranteil

                        Drucktemperatur: 210 °C

                        Temperatur Druckplatte: 50 °C

                        Druckgeschwindigkeit: 60mm/s




                        Additive Fertigung der Heckscheibe




                        Material: PLA Transparent

                        Drucktemperatur: 220 °C

                        Temperatur Druckplatte: 65 °C

                        Druckgeschwindigkeit: 60 mm/s


                        Düse (Nozzle) Messing 0,4



                        Bei dem Standard Nozzle aus Messing handelt es sich um eine Hochpräzisions Düse. Das Material leitet Wärme hervorragend und korrodiert nicht. Dadurch hat es die besten Voraussetzungen um die gängigsten Materialien wie PLA, ABS, PETG uvm. wunderbar zu verarbeiten.

                        Leider stößt Messing bei Materialien mit abrasiven Partikeln an seine Grenzen. Metall-, Holz-, Carbon- oder Glow in the Dark Filamente machen einer Messing Düse zu sehr zu schaffen.

                        Besonderheiten

                        ·         Hohe Hitzebeständigkeit

                        ·         Glattes Oberflächenfinish

                        ·         Antihaft

                        ·         Durchmessertoleranz: ± 0,01 mm

                        ·         Rundheit: ≤ 0,02 mm

                        ·         Innenlochrauheit: ≤ Ra0,4

                         

                         

                        Düse (Nozzle) gehärteter Stahl 0,4



                        Düsen aus gehärtetem Stahl sind genau richtig um Filamente abrasiven Partikeln zu verarbeiten. Die speziell gehärteten Stahldüsen sind im Bereich des 3D Drucks kaum zu zerstören. Egal ob Glow-in-the-Dark, Carbon-, Metall- oder Holzfilamente – Düsen aus gehärtetem Stahl sind dafür genau richtig. Gehärteter Stahl ist durch die gehärtete Oberfläche kaum abnutzbar. Wenn du also nicht nur mit den Standardmaterialien arbeitest gehören Düsen aus gehärtetem Stahl mit den unterschiedlichen Düsendurchmessern auf alle Fälle in dein Repertoire.

                        Besonderheiten

                        ·         Hohe Hitzebeständigkeit

                        ·         Glattes Oberflächenfinish

                        ·         Antihaft

                        ·         Durchmessertoleranz: ± 0,01 mm

                        ·         Rundheit: ≤ 0,02 mm

                        ·         Innenlochrauheit: ≤ Ra0,4

                         









                        Arduino Sketch




                        Funktionsnachweis

                        (Video 1) VIDEO-2022-06-09-21-02-07 (Alarmanlage)

                        Bei Annäherung an den Bewegungssensor, löst die optische Alarmanlage visuell über blinkende LEDs aus.


                        (Video 2) VIDEO-2022-06-09-21-01-09 (Heckklappen und Motordeckel)

                        Dieses Video zeigt eine Automatisierte Hecklappen und Motordeckel Öffnung/Schließung. Angesteuert werden die Servomotoren von zwei Schalter, die an der rechten Seite des Modell verbaut sind.




                        Erlernte Kenntnisse

                        ■Programmierung Arduino
                        ■Slicing (3D-Druck)
                        ■Lösungen im Team finden
                        ■Umgang mit Fritzing
                        ■Strukturierter Vorgang eines Projekts

                        Aufgetretene Probleme


                        Allgemeine Probleme:

                        ■Anfangs mangelhaftende Kenntnisse
                        ■Dokumentation unvollständig

                        Probleme Beim Druck

                        ■Mangelhafte Haftung an der Bauplattform
                        ■Einsatz neuer Filamente


                        Fazit:

                        Das Projekt wurde innerhalb der vorgegebenen Zeit erfolgreich abgeschlossen, es war sehr lehrreich in Bezug auf  Teamarbeit und Verarbeitung von neuen Filamenten sowie neue gewonnene Programmierkenntnisse. Unter anderem haben wir festgestellt, dass die Kommunikation untereinander essentiell ist und somit die Grundlage einer funktionierenden Teamarbeit darstellt. Durch das gerechte Aufteilen der Arbeit bzw. der Arbeitspakete auf die einzelnen Teammitglieder, konnten wir als Team besonders effektiv arbeiten und somit schnell Arbeitsfortschritte erreichen. In regelmäßigen Teamrunden  konnten wir außerdem die jeweiligen Stände besprechen und mögliche Komplikationen direkt beheben.

                        Bei der Additive Fertigung der 3D Bauteile,  gab es einige Herausforderungen. Erstmalig wurden zwei neue Filamente verarbeitet, die andere Fließeigenschaften hatten als das zuvor verarbeitete Standard Filament PLA. Hier mussten wir zahlreichen Veränderungen im Bereich der Slicing Software für den Druck ,sowie extra Feinabstimmungen direkt an dem 3D Drucker wären des Druck vornehmen. Als Resultat hatten wir etliche Arbeitsstunden und Fehldrucke mit der richtigen Druckeinstellung verbracht. Des weiteren mussten wir bei einem Filament basierend auf Carbon einen anderen Nozzle (Druckerdüse) einsetzten, da dieses Material den Standard Nozzle aus Messing durch die Harten Fasern beschädigen würde. Da solch einen Wechsel noch nie von uns durchgeführt wurde, war auch dies eine dementsprechende Herausforderung

                        Eine andere Hürde war die Konstruktion der Scharniere für die Heckklappe, da man mit dem Drucker nicht winzig kleine Scharniere drucken kann, gab es auch hier verschiede Konstruktionen und Drucke Versuche. Wir hatten schlussendlich die Scharnierzapfen an den oben Abschluss der Heckklappe gesetzt und die dazugehörige Aufnahmen an der Karosse befestigt.

                        Abschließend können wir sagen, dass wir in dem Projekt viele Erfahrungen im Bereich der Organisation und Technik sammeln konnten. In gewissen Punkten wäre eine noch regelmäßigere und genauere Absprache hilfreich gewesen um das arbeiten miteinander zu vereinfachen. Zudem haben wir uns zu Anfang keinen genauen Zeitplan erstellt, an den wir uns hätten halten können. Somit haben wir viele Aufgaben erst am Ende der Projektlaufzeit fertig gestellt und hatten keine Kapazitäten mehr für die Überprüfung eventueller Fehler, die während des Projekts hätten auftreten können. Daher würden wir bei dem nächsten Projekt direkt zu Beginn einen Zeitplan erstellen und die Aufgabenbereiche strukturierter organisieren.

                        Insgesamt finden wir als Team jedoch, dass wir das Projekt erfolgreich abschließen konnten und uns mit dem von uns erstellten T1-Modell identifizieren können.