Yves Ehrlich 5 years ago
parent
commit
ed28dc5065
  1. BIN
      Latex/images/JoystickToLogic.png
  2. BIN
      Latex/images/JoystickUML.PNG
  3. BIN
      Latex/images/MotorUML.PNG
  4. BIN
      Latex/images/SteuerungUML.PNG
  5. BIN
      Latex/images/akkuhalterung.png
  6. BIN
      Latex/main.pdf
  7. 146
      Latex/main.tex
  8. 5
      Latex/references.bib

BIN
Latex/images/JoystickToLogic.png

After

Width: 2827  |  Height: 1762  |  Size: 1.6 MiB

BIN
Latex/images/JoystickUML.PNG

After

Width: 616  |  Height: 181  |  Size: 10 KiB

BIN
Latex/images/MotorUML.PNG

After

Width: 307  |  Height: 111  |  Size: 4.7 KiB

BIN
Latex/images/SteuerungUML.PNG

After

Width: 325  |  Height: 182  |  Size: 8.9 KiB

BIN
Latex/images/akkuhalterung.png

After

Width: 696  |  Height: 748  |  Size: 27 KiB

BIN
Latex/main.pdf

146
Latex/main.tex

@ -323,16 +323,123 @@ Die Umsetzung ist nichts anderes als die PWM-Werte für die beiden Motoren in je
%TODO Graphik für die Übersetzung %TODO Graphik für die Übersetzung
\subsection{Überführung der Joystick Steuerung in eine Library} %Lukas \subsection{Überführung der Joystick Steuerung in eine Library} %Lukas
%TODO Hier wurde besonderes Augenmerk auf wiederverwendbarkeit und varibilität gelegt.
Hier wurde besonderes Augenmerk auf Wiederverwendbarkeit und Variabilität gelegt.
Des weiteren ist die Library komplett in C++ geschrieben. Wie genau eine C++ Library erstellt wird, wird in dieser Sektion nicht aufgefasst sondern nur die Besonderheiten betreffend der Joystick Library.
\subsection{Aufbau der Klassen}
Um eine höhere Variabilität und Wiederverwendbarkeit zu ermöglichen wurde die Library Objekt Orientiert programmiert. Dazu wurden drei Klassen Implementiert: Joystick, Motor und Steuerung.
\begin{figure}[h]
\includegraphics[width=13cm]{JoystickUML.PNG}
\centering
%\caption{Interpretation der Aussteuerung}
\end{figure}\begin{figure}[h]
\includegraphics[width=7cm]{MotorUML.PNG}
\centering
%\caption{Interpretation der Aussteuerung}
\end{figure}\begin{figure}[h]
\includegraphics[width=8cm]{SteuerungUML.PNG}
\centering
%\caption{Interpretation der Aussteuerung}
\end{figure}
Von diesen Klassen ist die Steuerung diejenige, welche die die eigentliche Logik beinhaltet, jedoch benötigt man zur Verwendung der implementierten Steuerung zwei Motoren und einen Joystick. Um einen Motor zu erstellen reicht es den Höchsten und den Niedrigsten PWM-Wert anzugeben. Über das Attribut PWMValue lässt sich nach dem Aufruf der updateValues() Funktion der Steuerungsklasse der Aktuelle PWM-Wert jedes Motors einzeln abrufen. Beim instantiieren der Joystick-klasse müssen mehr Daten angegeben werden. Die ersten beiden Parameter legen die Pins fest an welchen die jeweilige Achse angeschlossen ist. Die nächsten zwei sind wieder der niedrige und Höchste Wert. Zum Schluss benötigt der Joystick noch einen Wert, der einen Abstand zum Mittelpunkt von der Aktivierung der Steuerung ausschließt das sogenannte spaceing. Es wird benötigt, da der Joystick selbst in der Mittelstellung werte sendet, die über bzw unter 0 liegen.
\newpage \newpage
\section{Arduino Libaries} %Lukas \section{Arduino Libaries} %Lukas
\subsection{OneWire} \subsection{OneWire}
OneWire ist eine serielle Schnittstelle, die nur mit einer Datenleitung auskommt. Jedes angeschlossene Gerät hat eine eigene 64bit ROM Adresse, die man gezielt ansprechen kann. Alternativ, kann man Befehle an alle Geräte senden indem man den Skip ROM-Command (0xCC) benutzt. Anschließend kommt der eigentliche Befehl mit write(), der ausgeführt werden soll. Danach werden die Daten auf ein Scratchpad-Speicher geschrieben von wo sie per read() gelesen werden können. OneWire ist eine serielle Schnittstelle, die nur mit einer Datenleitung auskommt. Jedes angeschlossene Gerät hat eine eigene 64bit ROM Adresse, die man gezielt ansprechen kann. Alternativ, kann man Befehle an alle Geräte senden indem man den Skip ROM-Command (0xCC) benutzt. Anschließend kommt der eigentliche Befehl mit write(), der ausgeführt werden soll. Danach werden die Daten auf ein Scratchpad-Speicher geschrieben von wo sie per read() gelesen werden können.
\newpage
\section{Gedruckte Bauteile} %Yves
Alle gedruckten Bauteile haben wir selbst entworfen. einsehbar sind diese im Repositorium als STL oder aber auch unter den öffentlichen Fusion 360 Links.
\newline
%Platine
\begin{figure}[h]
\centering
\subfigure[Rahmen \cite{HC-SR04_Halterung}]{\includegraphics[width=7.5cm]{hc-sr04_rahmen.png}}
\subfigure[Winkel \cite{HC-SR04_Halterung}]{\includegraphics[width=7.5cm]{hc-sr04_winkel.png}}
\caption{HC-SR04 Halterung}
\begin{minipage}[t]{0.48\textwidth}
\includegraphics[width=\textwidth]{schalterhalterung.png}
\caption{Schalterhalterung \cite{Schalterhalterung}}
\end{minipage}\hfill
\begin{minipage}[t]{0.48\textwidth}
\includegraphics[width=\textwidth]{akkuhalterung.png}
\caption{Akkuhalterung \cite{Akkuhalterung}}
\end{minipage}
\end{figure}
\begin{figure}
\centering
\begin{minipage}[t]{0.48\textwidth}
\includegraphics[width=\textwidth]{joystickhalterung.png}
\caption{Joystick Halterung \cite{Joystick_Halterung}}
\end{minipage}\hfill
\begin{minipage}[t]{0.48\textwidth}
\includegraphics[width=\textwidth]{kugelrad.png}
\caption{Kugelrad \cite{Kugelrad}}
\end{minipage}
\medskip
\begin{minipage}[t]{0.48\textwidth}
\includegraphics[width=\textwidth]{rad.png}
\caption{Räder \cite{Raeder}}
\end{minipage}\hfill
\begin{minipage}[t]{0.48\textwidth}
\includegraphics[width=\textwidth]{plattform.png}
\caption{Roboter Plattform \cite{Plattform}}
\end{minipage}
\end{figure}
\newpage \newpage
\section{Motorsteuerung} %Yves \section{Motorsteuerung} %Yves
Die Steuerung der Motoren wurde über den IC MX1508 realisiert. Dieser ist sehr günstig als Modul für etwa 1€ erhältlich.
Mit seinen Spezifikationen von max. 10V Versorgungsspannung und maximal 1,5A war er perfekt für dieses Projekt geeignet.
Leider konnten wir kein Datenblatt zu diesem IC finden, die Angaben stammen lediglich aus den Beschreibungen der Händler die dieses Modul verkaufen.
Es scheint sich um einen Treiber mit H-Brücke bzw. doppelter H-Brücke zu handeln, er verfügt über jeweils zwei Kanäle mit je zwei Eingängen. Je nach Polung der Eingänge kann ein Motor vorwärts oder rückwärts drehen.
Um die Geschwindigkeit der Motoren regulieren zu können schrieben wir eine Bibliothek mit dem Namen L298N (Achtung, nicht mit der gleichnamigen Bibliothek im Librarymanager der Arduino IDE zu verwechseln!).
Der Name ist angelehnt an den gleichnamigen IC, welcher dem MX1508 in seiner Ansteuerung ähnelt.
Die Bibliothek nutzt Timer1 als 8-Bit Timer für die im Atmega328p integrierten PWM-Module OC1A und OC1B.
Ein PWM Pin ist mit jeweils einem der beiden Eingangspins eines Kanals des MX1508 verbunden. Der jeweils andere Pin muss kein PWM Pin sein, muss aber je nach Drehrichtung korrekt gepolt sein. Für diese nicht-PWM-Pins haben wir die Portpins B0 (Kanal A) und D7 (Kanal B) verwendet.
\newline
Im folgenden Code ist exemplarisch zu sehen, wie das setzen eines PWM Wertes für Kanal A abläuft. Valide PWM-Werte sind -255 bis +255.
\begin{file}[MX1508]
\begin{lstlisting}[language=C++]
L298N::setPWM_A(int16_t pwmA) {
if(pwmA < 0) {
PWMA = 0xFF + pwmA;
PORT_A |= PIN_A;
} else {
if(pwmA == 0) {
PWMA = 0;
PORT_A &= ~PIN_A;
} else {
PWMA = pwmA;
PORT_A &= ~PIN_A;
}
}
}
\end{lstlisting}
\end{file}
Zunächst wird geprüft, ob der PWM-Wert "`pwmA"' negativ ist. Davon hängt die Polung von "`PIN\_A"' ab und ob der PWM-Wert negiert werden muss.
\newline
Anschließend werden PWM-Wert und der Zustand des nicht-PWM-Pins entsprechend gesetzt.
\newpage
\begin{figure}[h]
\includegraphics[width=12cm]{MX1508.png}
\centering
\caption{MX1508 Anschluss \cite{MX1508}}
\end{figure}
%Folgende beiden ließen sich auch durch subsections mittels sensoric als section realisieren, kommt aber auf die menge des textes an subsections sollten nicht über eine halbe seite lang sein. %Folgende beiden ließen sich auch durch subsections mittels sensoric als section realisieren, kommt aber auf die menge des textes an subsections sollten nicht über eine halbe seite lang sein.
\newpage \newpage
\section{Thermosensor} %Nick \section{Thermosensor} %Nick
@ -424,42 +531,43 @@ Die Implementation ist relativ einfach. Wir setzen den Trigger Pin als Ausgang u
\\ \\
Zum Empfangen des Echo nutzen wir einen Pinchange Interrupt. Diese ISR wird ausgeführt, wenn ein Signal an einen bestimmten Pin kommt. Dazu aktivieren wir die nötigen PCINTs im PCIRC Register und PCMSK2 das bit für unseren Pin.\\ Zum Empfangen des Echo nutzen wir einen Pinchange Interrupt. Diese ISR wird ausgeführt, wenn ein Signal an einen bestimmten Pin kommt. Dazu aktivieren wir die nötigen PCINTs im PCIRC Register und PCMSK2 das bit für unseren Pin.\\
\\ \\
In der ISR messen wir die Zeit bis ein Echo ankommt und teilen es, wie im Datenblatt beschrieben, durch 58 um die Distanz in cm zu bekommen.
In der ISR messen wir die Zeit bis ein Echo ankommt und teilen es, wie im Datenblatt beschrieben, durch 58 um die Distanz in Centimetern zu bekommen.
\begin{file}[HC-SR04] \begin{file}[HC-SR04]
\begin{lstlisting}[language=C++, inputencoding={utf8}, extendedchars=false] \begin{lstlisting}[language=C++, inputencoding={utf8}, extendedchars=false]
int trig = 3;
int echo = 4;
long distance;
int trig;
int echo;
//ISR for PCINT2
ISR(PCINT2_vect) { ISR(PCINT2_vect) {
//Zeit des Signals messen
distance = pulseIn(echo, HIGH)/58;
// Pinchange Interrupt ausschalten
PCICR &= ~0b00000111;
PCMSK2 &= ~(1 << echo);
delayMicroseconds(10);
if((PIND & (1<<echo)) > 0) {
pulseStart = micros();
} else {
startNewMeasurement = true;
pulseLength = micros() - pulseStart;
newResult = true;
}
PCIFR = 0;
} }
void measureDistance(){ void measureDistance(){
// Signal zur Messung abgeben
digitalWrite(trig, HIGH); digitalWrite(trig, HIGH);
// ... wait for 10 µs ...
delayMicroseconds(10); delayMicroseconds(10);
// Signal zur Messung abschalten
// ... put the trigger down ...
digitalWrite(trig, LOW); digitalWrite(trig, LOW);
// Pinchange Interrupt aktivieren
PCICR |= 0b00000100;
PCMSK2 |= (1 << echo);
//Serial.println("messe...");
startNewMeasurement = false;
} }
\end{lstlisting} \end{lstlisting}
\end{file} \end{file}
In der setup() Funktion müssen wir den Trigger Pin als Ausgang und den Echo Pin als Eingang definieren und ein initiales Sigal mit dem trigger Pin senden.\\
In einer setup() Funktion müssen wir den Trigger Pin als Ausgang und den Echo Pin als Eingang definieren und ein initiales Sigal mit dem trigger Pin senden. Im Anschluss aktivieren wir die nötigen Bits im PCICR und PCMSK2 Register um den Pinchange Interrupt für unseren Echo Pin zu aktivieren.\\
\\ \\
Die measureDistance() Funktion, leitet die Messung ein. Sie gibt aus dem Trigger mit digitalWrite(trig, HIGH) Pin ein Signal an den Sensor, der dann ein Ultraschallsignal von sich für 10 Mikrosekunden abgibt, welches mit digitalWrite(trig, LOW) wieder abgestellt wird. Im Anschluss aktivieren wir die nötigen Bits im PCICR und PCMSK2 Register um den Pinchange Interrupt für unseren echo Pin zu aktivieren. Die ISR führt dann die eigentliche Messung mit pulseIn(echo, HIGH) durch und deaktivieren Pinchange Register wieder damit die ISR nicht versehentlich durch ein anderes Signal ausgeführt wird.\\
Die measureDistance() Funktion, leitet die Messung ein. Sie gibt aus dem Trigger mit digitalWrite(trig, HIGH) Pin ein Signal an den Sensor, der dann ein Ultraschallsignal von sich für 10 Mikrosekunden abgibt, welches mit digitalWrite(trig, LOW) wieder abgestellt wird. Die ISR führt dann die eigentliche Messung durch. Da die ISR bei Anfang und bei Ende des Signals aufgerufen wird, haben wir eine Fallunterscheidung eingebaut die zu Beginn des Signals die Startzeit speichert und am Ende des Signals, daraus die Pulslänge berechnet, mit der wir die Distanz bestimmen können. Dazu müssen wir die Pulslänge, wie im bereits erwähnt, durch 58 teilen.\\
\\ \\
Mit der Distanz die wir nun haben können wir den Roboter stoppen lassen, wenn er zu nah an einen Gegenstand ranfährt. Ihn aber komplett zu stoppen wäre unsinnig, da er sich überhaupt nicht mehr bewegen könnte. Also gucken wir nach den Motorgeschwindigkeiten und setzen diese nur auf 0 wenn sie mit einer Vorwärtsbewegung übereinstimmen. Somit kann sich unser Roboter immer noch auf der Stelle drehen oder rückwärts fahren um das Hindernis zu umgehen. Mit der Distanz die wir nun haben können wir den Roboter stoppen lassen, wenn er zu nah an einen Gegenstand ranfährt. Ihn aber komplett zu stoppen wäre unsinnig, da er sich überhaupt nicht mehr bewegen könnte. Also gucken wir nach den Motorgeschwindigkeiten und setzen diese nur auf 0 wenn sie mit einer Vorwärtsbewegung übereinstimmen. Somit kann sich unser Roboter immer noch auf der Stelle drehen oder rückwärts fahren um das Hindernis zu umgehen.
\newpage \newpage
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% Latex Beispeiele % Latex Beispeiele

5
Latex/references.bib

@ -75,6 +75,11 @@
note = {https://a360.co/38YTKAo}, note = {https://a360.co/38YTKAo},
title = {Schalterhalterung}, title = {Schalterhalterung},
} }
@Unpublished{Akkuhalterung,
author = {Yves Ehrlich},
note = {},
title = {Akkuhalterung},
}
@MISC{MX1508, @MISC{MX1508,
author = {{ifuturetech}}, author = {{ifuturetech}},
title = {MX1508 Motortreiber}, title = {MX1508 Motortreiber},

Loading…
Cancel
Save