Kabellose Wetterstation
Autor: Daniel Hilgers & Daniel Block
Betreuer: Prof. Schneider
Einleitung
Dieses Projekt ist Teil des GET-Fachpraktikums und hat zum Ziel, wettertechnische Messdaten wie Temperatur und Luftfeuchtigkeit zu erfassen. Zur Umsetzung dieses Vorhabens werden zwei Arduino-Plattformen verwendet. Die drahtlose Kommunikation miteinander ermöglicht die Übermittlung der Messdaten zu der Innenraum-Station. Beide Arduinos werden in ein eigens 3D-gedrucktes Gehäuse integriert, wobei das Außengehäuse wasserabweisende Eigenschaften aufweisen muss, um vor Regen geschützt zu sein und Feuchtigkeitsschäden zu vermeiden. Sowohl die Außenstation als auch die Inneneinheit erfassen Messdaten. Die gesammelten Daten von beiden Stationen werden auf der im Haus befindlichen Einheit miteinander dargestellt. Die gesamte Programmierung der Arduinos erfolgt mithilfe von Matlab Simulink.
Anforderungen
Nr. | Beschreibung | Bereich | Zuständigkeit |
---|---|---|---|
1 | Das Gehäuse für die Außenstation muss Wetterfest sein. | Hardware | Block, Hilgers |
2 | Die Reichweite der Wetterstation soll mindestens 10 Meter durch Wände betragen. | Hardware | Block, Hilgers |
3 | Das Außensystem muss mit einem Akku betrieben werden. | Hardware | Block, Hilgers |
4 | Das Innensystem soll mit einem kabelgebundenen Netzteil betrieben werden. | Hardware | Block, Hilgers |
5 | Die Wetterstation muss Temperatur, Luftfeuchtigkeit, Luftdruck und Windgeschwindigkeit messen. | Hardware/Software | Block, Hilgers |
6 | Das Programm Simulink muss für die Programmierung verwendet werden. | Software | Block, Hilgers |
7 | Die Messdaten müssen auf einem Display in Echtzeit angezeigt werden. | Software | Block, Hilgers |
8 | Die Messdaten sollen spätestens alle 15 Minuten aktualisiert werden. | Software | Block, Hilgers |
Funktionaler Systementwurf/Technischer Systementwurf
Im folgenden Systementwurf wird das Projekt in Systemkomponenten unterteilt:
- Arduino: Der Mikrocontroller führt den Code aus.
- Display: Auf dem Display werden die Wetterdaten der Innen- und Außenstation nebeneinander dargestellt.
- Temperatur und Feuchtigkeitssensor: Dieser Sensor ermittelt Temperatur und Feuchtigkeitsdaten und gibt sie an den Arduino weiter.
- Anemometer: Misst die aktuelle Windgeschwindigkeit
- Barometer: Misst den aktuellen Luftdruck am Gerät
- Echtzeituhr: Dieser Baustein gibt die reale Zeit an den Arduino weiter.
- Spannungsversorgung: Versorgt die jeweilige Station.
- Funk- und Empfängermodul: Ermöglicht die Kommunikation der beiden Stationen und lässt einen kabellosen Datenaustausch zu.
-
Funktionaler Systementwurf - Skizze
-
Technischer Systementwurf - Skizze
Komponentenspezifikation
Umsetzung (HW/SW)
Hardware
Projektübersicht:
In unserem Projekt zur Entwicklung einer kabellosen Wetterstation spielt die Konzeptionierung und Klärung der designtechnischen Aufgaben der Gehäuse für den Innen- und Außenbereich eine zentrale Rolle. Die zu entwerfenden Gehäuse sind nicht nur Behältnisse für die Elektronik, sondern erfüllen auch entscheidende funktionale Anforderungen, um die Langlebigkeit und Zuverlässigkeit der Wetterstation zu gewährleisten.
Innengehäuse Design:
Für den Innenbereich wird das Gehäuse um ein 3,5-Zoll-Display entworfen, das die Lesbarkeit der Wetterdaten sicherstellt. Es enthält auch einen Empfänger-Modul, Sensoren für Temperatur und Feuchtigkeit sowie eine Echtzeituhr, die alle innerhalb des Gehäuses geschützt sind. Die Benutzerfreundlichkeit und Ästhetik stehen hier im Vordergrund, wobei das Gehäuse auch eine gute Belüftung und einfache Wartung ermöglichen muss.
Außengehäuse Design:
Das Gehäuse für den Außenbereich ist ohne Display gestaltet, beherbergt aber neben dem Funkmodul und den Temperatur- und Feuchtigkeitssensoren zusätzlich ein Anemometer und ein Barometer. Dieses Gehäuse stellt höhere Anforderungen an die Witterungsbeständigkeit, um die Technik vor den Elementen zu schützen. Hier kommt das Material ASA (Acrylonitril-Styrol-Acrylester) ins Spiel, das sich durch seine hervorragende UV- und Witterungsbeständigkeit, Hitze- und Stoßfestigkeit als ideal für Außenanwendungen erweist.
Materialwahl und Verarbeitung:
Obwohl ASA in der Verarbeitung anspruchsvoller sein kann und eine begrenzte Lösungsmittelbeständigkeit aufweist, überwiegen seine Vorteile für den Außenbereich. Aufgrund potenziell gefährlicher Dämpfe während des Druckprozesses wird eine gute Belüftung erforderlich, und die höheren Kosten sowie die notwendigen höheren Extrudertemperaturen müssen realisiert werden.
Montage:
Das Design der Gehäuse berücksichtigt eine effiziente Montage und Demontage, um den Zugang zu den Komponenten für Wartung oder Austausch zu erleichtern. Das Außengehäuse bietet zudem eine effektive Wärmeableitung, um eine Überhitzung der Elektronik zu verhindern. Ein robustes Montagesystem sichert die Wetterstation an verschiedenen Orten wie Wänden, Pfosten oder Palisaden.
Integration:
Ästhetisch soll das Design der Gehäuse das moderne und technische Wesen der Wetterstation widerspiegeln und sich harmonisch in die jeweilige Umgebung einfügen. Zusammengefasst bieten die durchdacht gestalteten Gehäuse eine optimale Balance zwischen Funktionalität und Widerstandsfähigkeit, wodurch die kabellose Wetterstation nicht nur ein nützliches, sondern auch ein ansprechendes Element im Wohn- oder Außenbereich darstellt.
Software
In der Entwicklung unseres Projekts spielte die Verwendung von MATLAB/Simulink eine zentrale Rolle. Um die spezifischen Anforderungen unseres Systems zu erfüllen, wurden zwei unterschiedliche Simulink-Modelle entwickelt. Diese Entscheidung ergab sich aus der Notwendigkeit, zwei separate Arduino-Controller zu steuern: einen für den Außenbereich und einen weiteren für den Innenbereich.
Um eine effiziente Integration mit den Arduino-Controllern zu gewährleisten, wurde das Simulink Support Package für Arduino eingesetzt. Dieses Paket ermöglichte es uns, die Funktionalität der Arduino-Hardware direkt in die Simulink-Umgebung zu integrieren, was eine nahtlose Interaktion zwischen unserer Software und der Hardware sicherstellte.
Ein entscheidendes Element unserer Softwareentwicklung war die Verwendung des Simulink S-Function Builder Blocks. Dieser Block spielte eine Schlüsselrolle, da er es uns ermöglichte, benutzerdefinierten C++-Code in unsere Simulink-Modelle zu integrieren. Durch diesen Ansatz konnten wir verschiedene Arduino-Bibliotheken nutzen, um spezifische Funktionen und Fähigkeiten unserer Hardware zu steuern und zu erweitern.
Für eine transparente Dokumentation und mögliche Weiterentwicklungen haben wir zudem den Quellcode der einzelnen S-Function Blöcke separat im Artikel beigefügt. Diese Dokumentation des Quellcodes erleichtert das Verständnis der Funktionsweise und ermöglicht es anderen Entwicklern, auf unserer Arbeit aufzubauen oder sie für ihre eigenen Projekte anzupassen.
Innenstation
Touchdisplay Block
/* Includes_BEGIN */
#ifndef MATLAB_MEX_FILE
#define ARDUINO 101
#include "Adafruit_GFX.h"
#include "MCUFRIEND_kbv.h"
#include "TouchScreen.h"
constexpr uint16_t BLACK { 0x0000 };
constexpr uint16_t NAVY { 0x000F };
constexpr uint16_t DARKGREEN { 0x03E0 };
constexpr uint16_t DARKCYAN { 0x03EF };
constexpr uint16_t MAROON { 0x7800 };
constexpr uint16_t PURPLE { 0x780F };
constexpr uint16_t OLIVE { 0x7BE0 };
constexpr uint16_t LIGHTGREY { 0xC618 };
constexpr uint16_t DARKGREY { 0x7BEF };
constexpr uint16_t BLUE { 0x001F };
constexpr uint16_t GREEN { 0x07E0 };
constexpr uint16_t CYAN { 0x07FF };
constexpr uint16_t RED { 0xF800 };
constexpr uint16_t MAGENTA { 0xF81F };
constexpr uint16_t YELLOW { 0xFFE0 };
constexpr uint16_t WHITE { 0xFFFF };
constexpr uint16_t ORANGE { 0xFD20 };
constexpr uint16_t GREENYELLOW { 0xAFE5 };
// Touch screen pinout
constexpr uint8_t YP { A1 };
constexpr uint8_t XM { A2 };
constexpr uint8_t YM { 7 };
constexpr uint8_t XP { 6 };
// Touch calibration
constexpr int TS_LEFT { 924 };
constexpr int TS_RT { 150 };
constexpr int TS_TOP { 958 };
constexpr int TS_BOT { 139 };
constexpr int MINPRESSURE { 200 };
constexpr int MAXPRESSURE { 1000 };
MCUFRIEND_kbv tft;
TouchScreen ts { TouchScreen(XP, YP, XM, YM, 300) };
int displayState = 0;
#endif
/* Includes_END */
/* Externs_BEGIN */
/* extern double func(double a); */
/* Externs_END */
void TouchDisplay_Start_wrapper(real_T *xD)
{
/* Start_BEGIN */
#ifndef MATLAB_MEX_FILE
uint16_t ID { tft.readID() };
tft.begin(ID);
tft.setRotation(1);
tft.setTextSize(2);
tft.setTextColor(BLACK, WHITE);
tft.fillScreen(WHITE);
#endif
/* Start_END */
}
void TouchDisplay_Outputs_wrapper(const real32_T *temp,
const real32_T *humid,
const uint32_T *time,
const real32_T *windspeedoutside,
const real32_T *tempoutside,
const real32_T *humidoutside,
const real_T *pressureoutside,
const real_T *xD)
{
/* Output_BEGIN */
#ifndef MATLAB_MEX_FILE
if(displayState == 0)
{
tft.drawFastVLine(80, 0 , tft.height(), BLACK);
tft.fillRect(0, 0, 80, 80, RED);
tft.fillRect(0, 100, 80, 80, BLUE);
tft.setCursor(90, 20);
tft.print("Temperature: ");
tft.print(temp[0]);
tft.setCursor(90, 60);
tft.print("Humidity: ");
tft.print(humid[0]);
tft.drawFastHLine(80, 100 , tft.width(), BLACK);
tft.setCursor(90, 120);
tft.print("Temperature: ");
tft.print(tempoutside[0]);
tft.setCursor(90, 160);
tft.print("Humidity: ");
tft.print(humidoutside[0]);
tft.setCursor(90, 200);
tft.print("Luftdruck: ");
tft.print(pressureoutside[0]);
tft.setCursor(90, 240);
tft.print("Windgeschwindigkeit: ");
tft.print(windspeedoutside[0]);
}
else if(displayState == 1)
{
tft.setCursor(90, 20);
tft.print("zweite Seite ");
}
TSPoint p { ts.getPoint() };
long x,y;
x = map(p.y, TS_LEFT, TS_RT, 0, 480);
y = map(p.x, TS_TOP, TS_BOT, 0, 320);
// if sharing pins, you'll need to fix the directions of the touchscreen pins
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
Serial.print("x: ");
Serial.print(p.x);
Serial.print("\ty: ");
Serial.print(p.y);
Serial.print("\tPressure: ");
Serial.println(p.z);
if (x < 80 && y > 240) {
displayState = 0;
}
else if (x < 80 && y > 140 && y < 220) {
displayState = 1;
}
tft.fillRect(81, 0, 400, 320, WHITE);
}
#endif
/* Output_END */
}
void TouchDisplay_Update_wrapper(const real32_T *temp,
const real32_T *humid,
const uint32_T *time,
const real32_T *windspeedoutside,
const real32_T *tempoutside,
const real32_T *humidoutside,
const real_T *pressureoutside,
real_T *xD)
{
/* Update_BEGIN */
/* Update_END */
}
void TouchDisplay_Terminate_wrapper(real_T *xD)
{
/* Terminate_BEGIN */
/*
* Custom Terminate code goes here.
*/
/* Terminate_END */
}
nRF24L01_1 Wireless Modul (Empfänger)
/* Includes_BEGIN */
#ifndef MATLAB_MEX_FILE
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Wire.h>
RF24 radio(22, 23); // CE, CSN
struct Data {
float temp = 0;
float humid = 0;
double pressure = 0;
float windspeed = 0;
};
Data data;
#endif
/* Includes_END */
/* Externs_BEGIN */
/* extern double func(double a); */
/* Externs_END */
void nRF24L01_1_Start_wrapper(real_T *xD)
{
/* Start_BEGIN */
#ifndef MATLAB_MEX_FILE
Serial.begin(9600);
const byte address[6] = "00001";
if(!radio.begin())
{
Serial.println("Failed");
}
else
{
Serial.println("init");
}
radio.openReadingPipe(0, address);
radio.setPALevel(RF24_PA_HIGH);
radio.startListening();
#endif
/* Start_END */
}
void nRF24L01_1_Outputs_wrapper(real32_T *windspeed,
real32_T *temp,
real32_T *humid,
real_T *pressure,
const real_T *xD)
{
/* Output_BEGIN */
#ifndef MATLAB_MEX_FILE
if (radio.available()) {
radio.read(&data, sizeof(Data)); // Read the whole data and store it into the 'data' structure
}
temp[0] = data.temp;
humid[0] = data.humid;
pressure[0] = data.pressure;
windspeed[0] = data.windspeed;
#endif
/* Output_END */
}
void nRF24L01_1_Update_wrapper(real32_T *windspeed,
real32_T *temp,
real32_T *humid,
real_T *pressure,
real_T *xD)
{
/* Update_BEGIN */
/* Update_END */
}
void nRF24L01_1_Terminate_wrapper(real_T *xD)
{
/* Terminate_BEGIN */
/*
* Custom Terminate code goes here.
*/
/* Terminate_END */
}
DS3231 Block ( Echtzeituhr)
/* Includes_BEGIN */
#ifndef MATLAB_MEX_FILE
#include "DS3231.h"
DS3231 myRTC;
DateTime myDT;
#endif
/* Includes_END */
/* Externs_BEGIN */
/* extern double func(double a); */
/* Externs_END */
void DS3231_Start_wrapper(real_T *xD)
{
/* Start_BEGIN */
#ifndef MATLAB_MEX_FILE
Wire.begin();
#endif
/* Start_END */
}
void DS3231_Outputs_wrapper(uint32_T *time,
const real_T *xD)
{
/* Output_BEGIN */
#ifndef MATLAB_MEX_FILE
myDT = RTClib::now();
time[0] = myDT.unixtime();
#endif
/* Output_END */
}
void DS3231_Update_wrapper(uint32_T *time,
real_T *xD)
{
/* Update_BEGIN */
/* Update_END */
}
void DS3231_Terminate_wrapper(real_T *xD)
{
/* Terminate_BEGIN */
/*
* Custom Terminate code goes here.
*/
/* Terminate_END */
}
Außenstation
-
Simulink Modell Außenstation
nRF24L01_1 Wireless Modul (Sender)
/* Includes_BEGIN */
#ifndef MATLAB_MEX_FILE
#define ARDUINO 100
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Wire.h>
RF24 radio(7, 6); // CE, CSN
struct Data {
float temp = 0;
float humid = 0;
double pressure = 0;
float windspeed = 0;
};
Data sendData;
#endif
/* Includes_END */
/* Externs_BEGIN */
/* extern double func(double a); */
/* Externs_END */
void nRF24L01_Start_wrapper(real_T *xD)
{
/* Start_BEGIN */
#ifndef MATLAB_MEX_FILE
Serial.begin(9600);
const byte address[6] = "00001";
if(!radio.begin()) {
Serial.println("Radio failed");
} else {
Serial.println("Radio initilized");
}
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_HIGH);
radio.stopListening();
#endif
/* Start_END */
}
void nRF24L01_Outputs_wrapper(const real32_T *temp,
const real32_T *humid,
const real_T *pressure,
const real32_T *windspeed,
const real_T *xD)
{
/* Output_BEGIN */
#ifndef MATLAB_MEX_FILE
sendData.temp = temp[0];
sendData.humid = humid[0];
sendData.pressure = pressure[0];
sendData.windspeed = windspeed[0];
radio.write(&sendData, sizeof(Data));
#endif
/* Output_END */
}
void nRF24L01_Update_wrapper(const real32_T *temp,
const real32_T *humid,
const real_T *pressure,
const real32_T *windspeed,
real_T *xD)
{
/* Update_BEGIN */
/* Update_END */
}
void nRF24L01_Terminate_wrapper(real_T *xD)
{
/* Terminate_BEGIN */
/*
* Custom Terminate code goes here.
*/
/* Terminate_END */
}
Komponententest
Ergebnis
Zusammenfassung
Lessons Learned
Projektunterlagen
Projektplan
Projektdurchführung
YouTube Video
Weblinks
Literatur
→ zurück zur Übersicht: WS 23/24: Angewandte Elektrotechnik (BSE)