Browse Source

Reduced code in documentation.

master
nickg 4 years ago
parent
commit
93c340de3a
  1. BIN
      Latex/main.pdf
  2. 114
      Latex/main.tex

BIN
Latex/main.pdf

114
Latex/main.tex

@ -336,14 +336,14 @@ OneWire ist eine serielle Schnittstelle, die nur mit einer Datenleitung auskommt
%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
\section{Thermosensor} %Nick
Wie bereits erwähnt benutzen wir einen Dallas DS18b20 1-Wire Digital Thermometer, um die Motortemperatur zu messen. Der DS18b20 speichert die Temperatur als einen 9bit - 12bit Wert und kann Temperaturen im Bereich von -55°C bis 125°C messen. Für unsere Bedürfnisse reicht es wenn wir in 1-er Schritten messen. Der Sensor kommt aber auch mit kleineren Inkrementen zu recht. Der Senser benötig jedoch die OneWire Library.\\
Wie bereits erwähnt benutzen wir einen Dallas DS18b20 1-Wire Digital Thermometer, um die Motortemperatur zu messen. Der DS18b20 speichert die Temperatur als einen 9bit - 12bit Wert und kann Temperaturen im Bereich von -55°C bis 125°C messen. Für unsere Bedürfnisse reicht es wenn wir in 1-er Schritten messen. Der Sensor kommt aber auch mit kleineren Inkrementen zu recht. Der Sensor benötigt die OneWire-Library um angesprochen zu werden.\\
\begin{figure}[h]
\includegraphics[width=12cm]{ds18b20.jpg}
\centering
\caption{Der benutzte Sensor \\1) Erdung 2) Datenleitung 3) Spannung}
\end{figure}
Eine Messung wird durchgeführt indem der Sensor Takte, innerhalb eines Zeitfensters zählt. Der Zähler startet bei einem Wert, der -55°C darstellt. Erreicht der Zähler 0 schneller als das vorgegebene Zeitfenster wird das Temperaturregister inkrementiert. Der Zähler wird auf einen vom Slope Accumulator Circuitry abhängigen wert gestellt und wieder runtergezählt. Dies wiederholt sich solange bis das festgelegte Zeitfenster abgelaufen ist. \\
Eine Messung wird durchgeführt indem der Sensor Takte, innerhalb eines Zeitfensters zählt. Der Zähler startet bei einem Wert, der -55°C darstellt. Erreicht der Zähler 0 schneller als das vorgegebene Zeitfenster wird das Temperaturregister inkrementiert. Der Zähler wird dann auf einen vom Slope Accumulator Circuitry abhängigen wert gestellt und wieder runtergezählt. Dies wiederholt sich solange bis das festgelegte Zeitfenster abgelaufen ist. \\
\\
Es gibt verschiedene Wege den Code für den Sensor zu implementieren. Der einfachste Weg wäre die DallasTemperature-Library zu benutzen.
@ -351,98 +351,65 @@ Es gibt verschiedene Wege den Code für den Sensor zu implementieren. Der einfac
\begin{lstlisting}[language=C++]
#include <OneWire.h>
#include <DallasTemperature.h>
// OneWire auf Pin 4 setzen
OneWire oneWire(4);
// DallasTemperatures den OneWire zuweisen
OneWire oneWire(x);
DallasTemperatures sensors(&oneWire);
void setup(){
Serial.begin(9600);
Serial.begin(9600);
// Die Library starten
sensors.begin();
}
void loop(){
// Temperaturmessung anfordern
sensors.requestTemperatures();
sensors.requestTemperatures();
// Temperatur anzeigen
Serial.print(sensors.getTempCByIndex(0));
Serial.print(sensors.getTempCByIndex(y));
}
\end{lstlisting}
\end{file}
Das war auch der erste Ansatz. Der Clue an der Sache ist jedoch, dass die Prozedur auf die Weise etwa 600ms dauert und das den Roboter viel zu lange blockieren würde, da er in der Zeit keine weiteren Befehle verarbeiten kann. Also wurde diese Idee gestrichen und nach einer effizienteren Alternative gesucht.\\
OneWire wird auf Pin 4 initialisiert, dann wird OneWire an sensors() übergeben. Damit weiß die Library wo der Sensor angeschlossen ist. Mit sensors.begin() startet man die Library. Eine Messung fordert man mit requestTemperatures() an und mit getTempCByIndex(y) kann man einen bestimmten Sensor, wenn man mehrere hat, nach der Temperatur in Grad Celsius abfragen. Mit der Library ist das ganze also sehr einfach.\\
\\
Das war auch der erste Ansatz. Der Clue an der Sache ist jedoch, dass die Prozedur auf die Weise etwa 600ms dauert und das den Roboter viel zu lange blockieren würde, da er in der Zeit keine weiteren Befehle verarbeiten kann. Also wurde diese Idee mitsamt der Library gestrichen und nach einer effizienteren Alternative gesucht.\\
\\
Für unsere Implementierung haben wir uns an\\ \url{https://www.scargill.net/reading-dallas-ds18b20-chips-quickly/} orientiert. Dieses Beispiel ermöglicht es eine Messung in nur 5ms durchzuführen. Es wurden jedoch einige Änderungen in der Umrechnung der Temperatur gemacht. Da ein Einsatz in negativen Temperaturen nicht vorgesehen ist, machen wir eine viel simplere Umrechnung als die im Blog. \\
\\
\begin{file}[DS18B20-1]
\begin{file}[DS18B20]
\begin{lstlisting}[language=C++, inputencoding={utf8}, extendedchars=false]
#include <OneWire.h>
// DallasTemperature Library nicht notwendig
int16_t dallas(int x){
// Initialisierung von OneWire auf Pin x
// Initialisiergung
OneWire ds(x);
// Initialisierung unserer Prozesswerte
byte i;
byte data[2];
int16_t result;
// Chip zurücksetzen
int16_t result = 0;
// Auf Scratchpad schreiben
ds.reset();
// Rom überspringen
ds.write(0xCC);
// Auslesen der Werte aus dem Scratchpad
ds.write(0xBE);
result = 0;
// Die Datenbytes speichern
for(i = 0; i < 2; i++){
// Vom Scratchpad lesen
for(int i = 0; i < 2; i++){
data[i] = ds.read();
}
// Umrechnung der Werte in Grad Celsius
result = (data[1]<<8)|data[0];
result = result/16;
// Messen
ds.reset();
ds.write(0xCC);
// Messung starten
ds.write(0x44, 1);
return result;
}
\end{lstlisting}
\end{file}
\begin{file}[DS18B20-2]
\begin{lstlisting}[language=C++, inputencoding={utf8}, extendedchars=false]
void setup(){
Serial.begin(9600);
// Initiale Messung auf Pin 4
dallas(4);
}
void loop(){
// Messung der Temperatur
int16_t temp = dallas(4);
// Anzeigen der Temperatur
Serial.println(temp);
}
\end{lstlisting}
\end{file}
Im Groben, holen wir uns hier nur den Binärwert vom Sensor und teilen ihn durch 16. Die 16 ergibt sich aus einer Tabelle aus dem Datenblatt, aus der sich alle Werte über 0 Null einfach als das 16-fache der Temperatur bilden. Man kann damit zwar keine negativen Werte berechnen, aber das ist für unsere Bedürfnisse vollkommen ausreichend.\\
\\
Um den Roboter so wenig wie möglich zu belasten und somit eine eine schnelle Reaktionszeit zu ermöglichen, wird die Temperaturmessung nur alle 100ms durchgeführt und nur jede Sekunde durch den Funkcontroller abgefragt.
Wir initialsieren im Beipspiel OneWire auf einen beliebigen Pin und setzen den Sensor mit reset() zurück. Die ROM Adresse wird dabei mit write(0xCC) übersprungen, da wir nur einen Temperatursensor haben und es somit reicht, dass wir alle Geräte auf dieser OneWire-Verbindung ansprechen.Mit write(0xBE) wird dem Sensor gesagt, dass er die Werte auf dem Scratchpad speichern soll, die wir dann mit read() in einen Array einlesen. Die Werte im Array führen wir dann zusammen und teilen sie durch 16. Die 16 ergibt sich aus einer Tabelle aus dem Datenblatt. Bei genauerer Betrachtung stellt man Fest, dass die Temperatur Werte über 0 einfach nur die Binärwerte geteilt durch 16 sind. da es für unsere Bedürfnisse genügt, dass wir nur die positiven Werte messen, belassen wir es bei dieser einfachen Umrechnung. Dann wird der Chip wieder resetet, die Addresierung übersprungen und mit write(0x44) eine Messung durchgeführt. Es empfiehlt sich in der setup() Funktion die dallas() Funtion aufzurufen, damit er in der loop() den richtigen Wert erhält.\\
\\
Um den Roboter so wenig wie möglich zu belasten und somit eine eine schnelle Reaktionszeit zu ermöglichen, wird die Temperaturmessung nur alle 100ms durchgeführt und nur jede Sekunde durch den Funkcontroller abgefragt. Die Abfrage wird, aus Übersichtsgründen, abseits der Steuerung gemacht.
\newpage
\section{Ultraschallsensor} %Nick
@ -461,52 +428,37 @@ In der ISR messen wir die Zeit bis ein Echo ankommt und teilen es, wie im Datenb
\begin{file}[HC-SR04]
\begin{lstlisting}[language=C++, inputencoding={utf8}, extendedchars=false]
// Trigger- und Echo Pins setzen
int trig = 3;
int echo = 4;
long distance;
ISR(PCINT2_vect) {
//Zeit des Signals messen
distance = pulseIn(echo, HIGH);
distance = distance/58;
// Pinchange Interrupt ausmachen
distance = pulseIn(echo, HIGH)/58;
// Pinchange Interrupt ausschalten
PCICR &= ~0b00000111;
PCMSK2 &= ~(1 << echo);
delayMicroseconds(10);
PCMSK2 &= ~(1 << echo);
delayMicroseconds(10);
}
void measureDistance(){
// Signal r Messung abgeben
// Signal zur Messung abgeben
digitalWrite(trig, HIGH);
delayMicroseconds(10);
// Signal für Messung abgeben
// Signal zur Messung abschalten
digitalWrite(trig, LOW);
// Pinchange Interrupt aktivieren
PCICR |= 0b00000100;
PCMSK2 |= (1 << echo);
}
void setup(){
// Trigger Pin als Ausgang setzen
pinMode(trig, OUTPUT);
// Echo Pin als Eingang setzen
pinMode(echo, INPUT);
// Trigger resetten
digitalWrite(trig, LOW);
}
void loop(){
// Distanz messen
measureDistance();
PCMSK2 |= (1 << echo);
}
\end{lstlisting}
\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.\\
\\
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.\\
\\
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
%----------------------------------------------------------------------------------------
% Latex Beispeiele

Loading…
Cancel
Save