Gleich vorweg, eine richtige Wetterstation ist der in diesem Beitrag beschriebene Aufbau natürlich nicht. Dazu fehlen vor allem die Sensoren für Windrichtung und Windgeschwindigkeit, die im Eigenbau relativ schwer zu realisieren und zu eichen sind.

Aber trotzdem kann man mit einfachen Mitteln einige Grunddaten sammeln und online bereitstellen. Ich verwende hier derzeit – trotz aller Mängel – den Internet-of-Things Dienst thingspeak.com.

Meine Wetterstation soll eigentlich ein Datensammler für ein Hochbeet im Garten werden und wurde deswegen um einen Sensor zur Messung der Bodenfeuchtigkeit erweitert. Folgende Sensoren sind derzeit enthalten:

DHT11 – Temperatur und Luftfeuchtigkeit (Tutorial)
Digitaler, vorkalibrierter Sensor. Benötigt am Arduino nur 1 Pin zum Auslesen der Daten.

MPL3115A2 – Luftdruck und Temperatur
I²C-Sensor, misst die Temperatur genauer als der DHT11

TSL45315 – Lux / Lichteinfall (Tutorial)
I²C-Sensor, misst die Lichtmenge pro Fläche (Lux)

Seed Studio Feuchtigkeitssensor – Bodenfeuchtigkeit
Analoger Sensor, gibt einen mit der Feuchtigkeit des Mediums steigenden Wert an einem Analogpin zurück

Zusätzlich habe ich noch einen Arduino Uno R3 und ein Arduino Ethernet Shield zur Datenübertragung verwendet.

Hier werden die Bauteile noch einmal vorgestellt:

Thingspeak.com ScreenshotDie aktuelle Version des Arduino Sketch ist noch sehr einfach. Der Sketch macht alle 2 Minuten eine Messung und überträgt diese an einen bei thingspeak.com eingerichteten Channel zur Erfassung und Anzeige der Messdaten. Der Channel ist hier öffentlich abrufbar. Falls sich jemand über die Daten wundert: Der Aufbau steht die meiste Zeit im der Werkstatt im Keller – deswegen ist es auch an sonnigen Tagen eher kalt und dunkel.

Sollte der Channel gerade nicht mit Daten beschickt werden, hier ein Screenshot.

Der Anschluss der Sensoren an den Arduino ist nicht schwierig. Die Datenleitung des DHT11 habe ich mit Pin 8 verbunden. Die beiden I²C-Sensoren hängen an den I²C-Pins des Arduino (beim Arduino Uno R3 sind das A4 und A5). Achtung nur beim MPL3115A4-Sensor, da gehören laut Datenblatt zwei Widerstände I²C-Pins. Der Sensor für die Bodenfeuchtigkeit kommt an einen Analogpin.

Den grundlegenden Aufbau der Schaltung findet ihr in diesem Video:

Und die aktuelle Version des Arduino-Sketches mit etwas Dokumentation gibt es am Ende des Beitrags:

Für die beiden I²C-Sensoren, den DHT11 und das Ethernet-Shield werden passende Libraries benötigt, die hier zu finden sind:

DHT11
https://github.com/adafruit/DHT-sensor-library

MPL3115A2
https://github.com/sparkfun/MPL3115A2_Breakout (da gibt’s auch einen Hookup-Guide etc.)

TSL45315
https://github.com/adidax/Makerblog_TSL45315 (noch sehr rudimentär, aber bei mir funktioniert’s)

Die restlichen Libraries (Wire, SPI, Ethernet etc.) sind bei der Arduino IDE dabei.

 

Und hier der Sketch in der aktuellen Version. Keine Angst, der Programmcode ist hauptsächlich wegen der Testausgaben über die serielle Schnittstelle so lang:

/* Makerblog.at Wetterstation
 
DHT11 fuer Temperatur und Luftfeuchtigkeit
TSL45315 Lux Sensor fuer Helligkeit
MPL3115A2 Barometer fuer Luftdruck und Temperatur
Moisture Sensor fuer Bodenfeuchte
Ethernet Board zur Datenuebertragung
 
I2C Pins auf den einzelnen Arduino Boards:
Board I2C/TWI Pins
SDA, SCL
----------------------------
Uno, Ethernet A4, A5
Mega 20, 21
Leonardo 2, 3
Due 20, 21
 
Datenleitung DHT11: Pin 8
 
Feuchtesensor: Analogpin A1
 
*/
 
// Die Libraries zur Ansteuerung aller Sensoren einbinden
#include <Wire.h>
#include <Makerblog_TSL45315.h>
#include <MPL3115A2.h>
#include <dht11.h>
#include <SPI.h>
#include <Ethernet.h>
 
byte mac[] = { 0xD4, 0x28, 0xB2, 0xFF, 0xA0, 0xA1 }; // Must be unique on local network
 
// ThingSpeak Settings - dazu ist ein kostenloser Account bei Thingspeak noetig
char thingSpeakAddress[] = "api.thingspeak.com";
String writeAPIKey = "OCOJGIZW03EVREJC";
const unsigned long updateThingSpeakInterval = (unsigned long)120*1000; // Time interval in milliseconds to update ThingSpeak (number of seconds * 1000 = interval)
 
// Variable Setup
unsigned long lastConnectionTime = 0; 
boolean lastConnected = false;
int failedCounter = 0;
 
// Initialize Arduino Ethernet Client
EthernetClient client;
 
Makerblog_TSL45315 luxsensor = Makerblog_TSL45315(TSL45315_TIME_M4);
MPL3115A2 myPressure;
uint32_t lux;
 
char pastring[10];
char tmpstring[10];
 
float pressure;
float temperature;
 
int ipress;
int itemp;
 
int soil;
 
dht11 DHT11;
#define DHT11PIN 8
 
// Der TSL45315 hat werkseitig die I2C ID 0x29
#define TSL45315_I2C_ADDR (0x29)
 
void setup() {
 
 Serial.begin(9600);
 Serial.println("Initialization:");
 
 Serial.print("TSL45315: ");
 Serial.println(luxsensor.begin());
 
 Serial.println("MPL3115A2"); 
 myPressure.begin(); // Get sensor online
 myPressure.setModeBarometer(); // Measure pressure in Pascals from 20 to 110 kPa
 myPressure.setOversampleRate(7); // Set Oversample to the recommended 128
 myPressure.enableEventFlags(); // Enable all three pressure and temp event flags 
 
 // DHT11 needs no setup
 // Moisture sensor needs no setup
 
 // Start Ethernet on Arduino
 startEthernet(); 
}
 
void loop() {
 
 int chk = DHT11.read(DHT11PIN);
 
 Serial.print("Read sensor: ");
 switch (chk)
 {
 case DHTLIB_OK: 
 Serial.println("OK"); 
 break;
 case DHTLIB_ERROR_CHECKSUM: 
 Serial.println("Checksum error"); 
 break;
 case DHTLIB_ERROR_TIMEOUT: 
 Serial.println("Time out error"); 
 break;
 default: 
 Serial.println("Unknown error"); 
 break;
 } 
 
 lux = luxsensor.readLux();
 Serial.print("Lux: ");
 Serial.println(lux, DEC); 
 
 pressure = myPressure.readPressure();
 float pressure = myPressure.readPressure();
 Serial.print("Pressure(Pa): ");
 Serial.println(pressure, 2);
 
 temperature = myPressure.readTemp();
 Serial.print("Temperature1: ");
 Serial.print(temperature, 2);
 Serial.println(" (MPL3115A2)");
 
 Serial.print("Temperature2: ");
 Serial.print((float)DHT11.temperature, 2); 
 Serial.println(" (DHT11)");
 
 Serial.print("Humidity (%): ");
 Serial.println((float)DHT11.humidity, 2);
 
 soil = analogRead(A1);
 
 Serial.print("Soil moisture: ");
 Serial.println(soil);
 
 Serial.println("------------------------------------");
 
 // Print Update Response to Serial Monitor
 while (client.available())
 {
 char c = client.read();
 Serial.print(c);
 }
 
 // Disconnect from ThingSpeak
 if (!client.connected() && lastConnected)
 {
 Serial.println("...disconnected");
 Serial.println();
 
 client.stop();
 }
 
 
 Serial.print("Millis: ");
 Serial.println(millis());
 
 Serial.print("lastConnectionTime: ");
 Serial.println(lastConnectionTime);
 
 Serial.print("Diff: ");
 Serial.println(millis() - lastConnectionTime);
 
 Serial.print("Interval: ");
 Serial.println(updateThingSpeakInterval); 
 
 // Update ThingSpeak - schauen ob 120 Sekunden vergangen sind, wenn ja dann Thingspeak updaten
 if(!client.connected() && (millis() - lastConnectionTime > updateThingSpeakInterval))
 {
 Serial.println("UPDATE!");
 
 // Ohne das Leerzeichen am Ende hat es bei mir nicht funktioniert
 updateThingSpeak("field1="+(String)temperature+"&field2="+(String)DHT11.temperature+"&field3="+(String)lux+"&field4="+(String)pressure+"&field5="+(String)DHT11.humidity+"&field6="+(String)soil+" ");
 
 }
 
 // Check if Arduino Ethernet needs to be restarted
 if (failedCounter > 3 ) {startEthernet();}
 lastConnected = client.connected();
 delay(10000);
}
 
 
void updateThingSpeak(String tsData)
{
 if (client.connect(thingSpeakAddress, 80))
 { 
 client.print("POST /update HTTP/1.1\n");
 client.print("Host: api.thingspeak.com\n");
 client.print("Connection: close\n");
 client.print("X-THINGSPEAKAPIKEY: "+writeAPIKey+"\n");
 client.print("Content-Type: application/x-www-form-urlencoded\n");
 client.print("Content-Length: ");
 client.print(tsData.length());
 client.print("\n\n");
 
 Serial.println(tsData);
 client.print(tsData);
 
 lastConnectionTime = millis();
 
 if (client.connected())
 {
 Serial.println("Connecting to ThingSpeak...");
 Serial.println();
 
 failedCounter = 0;
 }
 else
 {
 failedCounter++;
 
 Serial.println("Connection to ThingSpeak failed ("+String(failedCounter, DEC)+")"); 
 Serial.println();
 }
 
 }
 else
 {
 failedCounter++;
 
 Serial.println("Connection to ThingSpeak Failed ("+String(failedCounter, DEC)+")"); 
 Serial.println();
 
 lastConnectionTime = millis(); 
 }
}
 
void startEthernet()
{
 
 client.stop();
 
 Serial.println("Connecting Arduino to network...");
 Serial.println(); 
 
 delay(1000);
 
 // Connect to network amd obtain an IP address using DHCP
 if (Ethernet.begin(mac) == 0)
 {
 Serial.println("DHCP Failed, reset Arduino to try again");
 Serial.println();
 }
 else
 {
 Serial.println("Arduino connected to network using DHCP");
 Serial.println();
 }
 
 delay(1000);
}

One thought on “Eine einfache Wetterstation mit dem Arduino basteln

  • 28. Mai 2017 um 21:26
    Permalink

    Hej
    Tolles Projekt. Ich bin gerade dabei mir eine Gewächshaussteuerung zusammenzu stoppeln
    Dabei sollen 2 Arduinos (UNO + Mega 2560 R3 ATmega2560-16AU CH340G) mit einem Raspberry PI 3B zum Einsatz kommen, dazu etliche Sensoren.
    Mal sehen ob ich es ans Laufen bekomme
    Gruss aus Schweden
    Jörg

    Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Time limit is exhausted. Please reload the CAPTCHA.