(WS19-01)Wetterballon Design: Unterschied zwischen den Versionen

Aus Verteilte Systeme - Wiki
Wechseln zu: Navigation, Suche
(Verbaute Sensoren und Geräte)
(Verbaute Sensoren und Geräte)
Zeile 30: Zeile 30:
 
| GPS || 1 || u-blox NEO-M8U     
 
| GPS || 1 || u-blox NEO-M8U     
 
|-
 
|-
|Buzzer || 1 ||
+
|Buzzer || 1 || Grove Buzzer
 
|-
 
|-
 
|}
 
|}

Version vom 16. März 2020, 15:31 Uhr

Verbaute Sensoren und Geräte

Messung Anzahl Name
Temperatur innen 1 MCP9808
Temperatur außen 1 TMP 117 Breakout
Luftfeuchtigkeit außen 1 SHT 35
Luftfeuchtigkeit außen 1 SHT 31
Luftfeuchtigkeit innen 1 SHT 35
Luftdruck außen 1 MS8607
Luftdruck außen 1 MS5611 auf GY-86
Luftdruck innen 1 MS8607
9-Achsen (3-Achsen-Beschl., -Gyro., -Magnet.) 1 IMU 10DOF mit MPU-9250 & BME280
UV-A und UV-B 1 GYML8511 an Grove I2C-ADC
Kamera Bild 1 WaveShare IMX179 USB-Kamera
Kamera Video 1 Raspicam V2
GPS 1 u-blox NEO-M8U
Buzzer 1 Grove Buzzer

Probleme

Bei den vorhandenen Sensoren sind wir auf kleinere Probleme gestoßen. Alle Sensoren sind bis zu einer Minimaltemperatur von -40°C funktionsfähig. Auf dem Flug werden diese allerdings deutlich unterschritten. Wir haben uns dennoch für den Einsatz dieser Sensoren entschieden, da auf dem Markt keine geeignerten Sensoren zu finden waren. Um Messungenauigkeiten oder gar Ausfälle zu kompensieren, werden wir die Sensoren für den Außeneinsatz mehrfach verbauen. Dabei kann es zu Adresskonflikten der einzelnen Sensoren kommen. Eine Lösung dafür steht noch aus.

Hardware-Architektur

HW Architecture.png

Als zentrale Steuereinheit habe wir einen Pi-Zero beutzt, um Gewicht und Strom zu sparen. Ein selbst gebauter HAT der uns zur Verfügung getellt wurde stellte u.a. die notwendigen I²C-Anschlüsse bereit, um die Sensoren mit dem Pi zu verbinden. Auf dem HAT befanden sich außerdem Module für die Lokalisierung per GPS und das Versenden von Daten über LoRaWAN sowie GPIO-Anschlüsse die wir für einen Buzzer verwendet haben, der die Bergung unterstützen sollte. Über einen USB-Hub wurden eine zusätzliche Kamera und ein Modul für die Datenübertragung per GSM angeschlossen. Der Zusammenschluss von Pi, HAT, USB-Hub und Speicherkarte wurde "master" getauft. Es befand sich außerdem ein GPS-Stick im Payload, der unabhängig vom eigentlichen System war und bei einem Stromausfall die Bergung ermöglichen sollte.

Software-Architektur

Bei der Software-Architektur stellte sich die Frage, wie die unterschiedlichen Messzyklen der Sensoren am besten zu verwalten sind. Hier gab es zwei grundsätzliche Ideen.

Parallel

Eine parallele Implementierung mit Threads bietet den Vorteil, dass jeder Sensor autonom läuft, also auch in keiner Weise von den anderen Sensoren abhängig ist. Jeder Sensor muss nur eine (oder für jede Phase eine) run-Methode implementieren, die vom Master gestartet wird. Der Zugriff auf den Bus kann per Mutex synchronisiert werden. Beim Wechsel des Modus kann der Master dann jeden Thread beenden.

Die Nachteile dieser Methode sind größtenteils erst nach einer Probeimplementierung aufgefallen. Dazu zählen neben der ohnehin höheren Komplexität paralleler Programme, dass die Abgrenzung der Sensoren untereinander auch dazu führt, dass sie weitestgehend vom Master entkoppelt sind. Das ist vor allem im Bezug auf die Live-Datenauswertung ein Problem, da ein einzelner Sensor keinen simplen Weg hat, mit dem Master zu kommunizieren. Des weiteren führt die Anforderung der Unterbrechbarkeit in Verbindung mit der Synchronisierung per Mutex zum Problem von Race-Conditions, die, wenn nicht korrekt behandelt, das komplette Programm lahmlegen könnten.

Aus diesen Gründen wurde sich gegen die Implementierung mit Threads entschieden.

Monolithisch

Eine monolithische Implementierung mit einer einzigen Hauptfunktion, die alle Sensoren und andere Funktionalitäten, wie das Schreiben der Daten in Dateien, überwacht, sah zunächst nach einem uneleganteren Weg aus, da ihr Hauptvorteil im Vergleich zu Threads lediglich die einfachere Programmierung zu sein schien.

Neben der Lösung für die Problematik der Live-Datenverarbeitung bietet dieser zentralisierte Ansatz allerdings noch einige andere Vorteile. Die Komplexität des Codes wird verringert und die Implementierung der Wartungsschnittstelle wird vereinfacht. Außerdem eröffnet dieser Ansatz die Möglichkeit für weitere Dateninteraktionen. Des Weiteren müssen gleiche Abläufe nicht mehr für jeden Sensor redundant programmiert, sondern nur einmal im Master geschrieben werden.

Durch die engere Bindung der einzelnen Komponenten wurde eine größere, gut durchdachte und klar definierte Schnittstelle für die Sensoren nötig, die hilft, den Master algorithmisch übersichtlich zu halten, die aber auch auf den Eigenheiten der unterschiedlichen Sensoren gerecht wird.

Software-Architektur

Komponentendiagramm.jpg

Messdatenstruktur

Die Messdaten der Sensoren müssen über Programmteile hinweg kommuniziert werden können, z. B. zur internen Verarbeitung oder zur Serialisierung. Um eine solch vielseitige Nutzung zu ermöglichen, braucht es eine Datenstruktur, die nicht nur Zahlenwerte speichert sondern ihnen auch einen Kontext gibt. Daher ist für jeden Messwert der zugehörige Messdatentyp gespeichert.

Sensorschnittstelle

Alle Methoden dieser Schnittstelle sind mit Rückgabewerten definiert, die eindeutig Fehlercodes darstellen können. Das erlaubt von außen zu entscheiden, ob eine Fehlermeldung relevant ist und z. B. zum Programmabbruch führen soll, oder ob anderweitig bzw. überhaupt auf sie reagiert werden muss.

init()
Vor allem komplexere I²C-Sensoren bieten die Möglichkeit, sie über ihre Register zu konfigurieren. Für solche Sensoren existiert diese Funktion. Dies ist die einzige Funktion, die kein informelles Zeitlimit hat. Dauert die Konfiguration länger, stellt das kein Problem dar.
init_data(measurement*)
Um möglichst hohe Flexibilität zu wahren, wird der Speicher für die Messdaten nicht durch den Sensor selbst verwaltet. Dieser bietet Lediglich die Funktionalität, Speicherplatz in der für ihn korrekten Größe und Struktur anzulegen. Alle weiteren Methoden erwarten eine solche Struktur als Parameter.
free_data(measurement*)
Gibt eine allokierte Messdatenstruktur wieder frei.
measure(measurement*)
Für Sensoren, z. B. aufgrund eines Analog-Digital-Converters etwas Zeit brauchen, um nach dem Messen Daten bereit zu stellen, ist diese Funktion gemacht. Es wird eine Messdatenstruktur erwartet, um den Zeitpunkt, zu dem die tatsächliche Messung ausgeführt wurde, festzuhalten.
get_data(measurement*)
In dieser Funktion werden die Sensordaten abgefragt und in die Messdatenstruktur gespeichert. Je komplexer der Sensor, desto mehr passiert hier. Es ist trotzdem wichtig, dass diese Funktion nicht übermäßig viel Zeit braucht.