Kleiner, tiefer, kürzer ... Entwicklung einer Wetterstation

Der Pragmatische Architekt  –  0 Kommentare

Bevor es mit drahtloser Kommunikation weitergeht, legt die Serie ein Intermezzo ein. Wir wollen wieder einmal ein kleines Projekt durchführen. Objekt der Begierde ist eine kleine Wetterstation.

In diesem Projekt für Regentage wollen wir eine kleine Umweltstation konstruieren, die neben Wetterdaten auch Feinstaub messen kann. Nennen wir sie einfach eFrog. Die Wetterstation soll dabei Größen wie Luftdruck, Temperatur, Feuchtigkeit und Feinstaub ermitteln.

Arduino Pro Mini als Basis

Wer auf Arduino-Basis ein solches Projekt initiiert, muss auf die Größe des Boards achten, soll das Ganze den Haushalt nicht verschandeln. Und natürlich auf den Stromverbrauch, falls am Installationsort kein Stromnetz vorliegt.

Der Arduino Pro Mini ist kein Eigengewächs von arduino.cc, sondern eine Open-Source-Hardware-Entwicklung von SparkFun. Dementsprechend tummeln sich auf den einschlägigen Online-Verkaufsportalen diverse Klone. Das Board existiert in Varianten mit 5 V und 3.3 V sowie mit 16 Mhz beziehungsweise 8 Mhz Taktfrequenz. Ein 5er-Pack ist bei Ebay inklusive Versandkosten ab 13 Euro zu haben. Macht also 2,60 Euro pro Board. Alle neueren Varianten basieren auf dem ATmega32. Früher gab es ebenfalls eine ATmega168-Version, die man heute nicht mehr anschaffen sollte.

Pro Mini: Kleine Bauweise, aber große Funktionsvielfalt

Aufgrund seiner kleinen Bauform liegt der Verdacht nahe, dass der Pro Mini dem großen Bruder Arduino Uno nicht das Wasser reichen kann. Doch weit gefehlt. Der kleine Racker steht seinem Bruder in nichts nach.


Microcontroller

ATmega328

Stromversorgung

3.35 -12 V (3.3V Modell) or 5 - 12 V (5V Modell)

Arbeitsspannung

3.3V oder 5V (modellabhängig)

Digitale I/O Pins
14

PWM Pins
6

UART
1

SPI
1

SPI
1

Analoge Eingänge
6

Externe Interrupts
2

Strom per I/O-Pin

40 mA

Flash Speicher

32 KB wovon der Bootloader 2 KB beansprucht

SRAM

2 KB

EEPROM

1 KB

Taktfrequenz

8 MHz (3.3V Version) oder 16 MHz (5V Version)

Das Einzige, was Sie jetzt noch erledigen müssen, ist das Anlöten der Header-Pins. Die werden lose mitgeliefert. Ich habe zusätzlich an die offenen Analogeingänge A4 und A5 Verbindungsdrähte gelötet, rein aus Bequemlichkeit. Über die beiden Eingänge, die auch als I2C-Bus fungieren, lassen sich dadurch Sensoren mit I2C-Anschluss leichter anschließen. Wer versucht, die Verbindungsdrähte einfach in die Löcher des Pro Mini zu stecken, sollte sich auf Enttäuschungen gefasst machen. Das geht allenfalls für kleine Versuche. Löten ist daher alternativlos.

Empowerment

Größenbedingt besitzt der Pro Mini keinen USB-Eingang. Stattdessen empfiehlt sich die Kopplung mit einem USB-FTDI-Baustein. Da der Pro Mini die zum FTDI-Board symmetrischen Anschlüsse besitzt, lassen sich beide sehr gut koppeln. Ich setze ein Pro Mini mit 3,3-V-Betriebsspannung voraus, um keinen Logik-Level-Shifter zwischen 5-V-Arduino und 3,3-V-Sensoren einsetzen zu müssen. Verwenden Sie ein Modell mit 5-V-Betriebsspa,nung, müssen Sie den Jumper auf dem FTDI-Board auf 5 V einstellen. Umgekehrt natürlich auf 3.3 V.

Pro Mini mit Anschluss an FTDI-Breakout-Modul

Beachten Sie bitte zur Sicherheit die Kontakte auf dem Pro Mini und auf dem von Ihnen benutzten USB-Anschluss auf die richtige Position der Pins, bevor Sie beide verbinden. Warum RX zu TX und TX zu RX führen muss, hatten wir bereits früher thematisiert.

Und verbinden Sie alle sechs Anschlüsse ohne Ausnahme. Nur so kann die Arduino IDE das Pro Mini Board vor dem Upload eines Sketches über RESET programmierbereit machen. Es sei denn, Sie bevorzugen es, vor jedem Upload ein RESET per Hand auszulösen. Wenn Sie beim Upload sync-Fehler erhalten, haben Sie entweder die beiden Boards nicht richtig verbunden oder in der IDE Board, Processor oder Port nicht richtig eingestellt.

Sensorik

Jetzt müssen wir den Pro Mini noch mit geeigneten Fühlern ausstatten. An dieser Stelle kommen die drei folgenden Sensoren zum Einsatz:

  • BMP180: Dieser Sensor von Bosch misst den "Bariometric Pressure", zu gut Deutsch den Luftdruck. Der Sensor funktioniert mittels des piezoelektrischen Effekts. Die Ausgabespannung des eingesetzten piezoelektrischen Elements hängt vom jeweiligen Luftdruck ab. Zwei wesentliche Einflussgrößen beeinflussen dessen Wert, Höhe und Wetter. Das Messergebnis meldet der BMP180 über den I2C-Bus zurück. Physikalische Einheit des Luftdrucks ist Pascal, definiert als Newton pro Quadratmeter. Auf Meereshöhe beträgt der Wert 101.325 Pascal (Pa). Per 100 m Höhenzuwachs verringert sich der Druck um 1,3333.... %. Das heißt, dass sich der Luftdruck in rund 3750 m Höhe auf die Hälfte reduziert hat. Auch ein Temperatursensor ist in dem sehr kleinen Board integriert. Es lässt sich mit 3,3 V oder 5 V betreiben, und kommuniziert über I2C mit Anwendungsprogrammen.
    • Den Eingang Vin verbinden wir mit dem Vcc-Ausgang des Pro Mini
    • Ebenso verbinden wir GND des Sensors mit GND des Arduino
    • Die I2C-Ports des BMP180, SCL, SDA verbinden wir mit den Analogports A5, A4 des Pro Mini. Sollten Sie ein anderes Arduino-Board verwenden, liegen die I2C-Anschlüsse an anderer Stelle.
Breakout-Board mit Luftdrucksensor BMP180 von Bosch (Bild: adafruit.com)
  • DHT22 oder DHT11: DHT steht für Digital Humidity and Temperature. Der DHT22 schafft von -80 °C bis +40 °C Temperaturmessung mit Abweichung von 0,5 %, sowie eine Feuchtigkeitsmessung mit 2-5% Genauigkeit. Der Sensor hat Poren, durch die Feuchtigkeit dringt und die Spannung zwischen zwei elektrischen Platten und einem dazwischen liegendem Dielektrikum verändert, woraus sich die Feuchtigkeit ergibt. Einziger Haken des Sensors ist, dass er nur alle 2 Sekunden eine neue Temperatur liefert. Für unsere Zwecke ist das allerdings zu verschmerzen. Der DHT11 hat schlechteren Messumfang und schlechtere Genauigkeit, dafür aber nur 1 Sekunde Messverzögerung. Nun zu den Anschlüssen:
    • Der GND-Eingang des DHT22 ist mit dem GND des Arduino zu verbinden.
    • Den Spannungseingang vom DHT22 müssen sie an den Spannungsausgang des Pro Mini anschließen. Auch dieser Sensor verträgt 3,3 V oder 5 V.
    • Den Datenausgang des DHT22 verbinden Sie mit einem Digitaleingang des Pro Mini. Wir verwenden Pin 2.
    • Es empfiehlt sich, einen 10 kOhm Pull-up-Widerstand zwischen Spannungseingang und Datenausgang zu legen.
Temperatur und Feuchtigkeit kann der DHT22 messen (Bild: adafruit.com)
  • Sharp GP2Y10...: Dieser Sensor misst Feinstaubpartikel und kann Hausstaub von Rauch unterscheiden. Die Partikel sammeln sich in einem Messbereich und werden mit Infrarotstrahlung beschossen. Je nach Streuung der Strahlen lässt sich auf das Ausmaß von Staub schließen. Der Anschluss an den Arduino gestaltet sich etwas komplizierter. Normalerweise liefern die Händler den Sensor mit passendem Kabelstrang/Kabelsteckerleiste, 220 µF Elektrolytkondensator und Widerstand (150 Ohm bis 300 Ohm). Der Baustein sollte mit 3,.3 V und 5 V Versorgungsspannung funktionieren. Allerdings haben einige Nutzer berichtet, dass Sie den Staubsensor nicht stabil mit 3,3 V betreiben hätten können. In diesem Fall lässt sich das FTDI-Board auf 5 V konfigurieren (per Jumper!) und die Versorgungsspannung des FTDI-Boards an den Raw-Eingang des Pro Mini legen. Am Raw-Eingang findet sich ein Spannungsregler, sodass dem Pro Mini nichts geschehen kann. Die 5 V des FTDI-Boards lassen sich dann auch für die verwendeten Sensoren in unserem Mini-Projekt benutzen, da diese allesamt 5-V-tolerant sind. Bei meinem Aufbau gibt es aber unter 3.3 V keine Probleme. Die Verbindungen bei der 3.3-V-Schaltung lauten:
    • Pin 1 (V-LED) verbinden Sie über den mitgelieferten Widerstand an die Versorgungsspannung des Pro Mini.
    • Pin 2 (LED-GND) legen Sie auf Common GND des Arduino.
    • Pin 3 (LED) legen Sie an einen Digitalausgang des Arduino. Wir nehmen Pin 12. Hinweise: Diese LED ist Active Low, was heißt, dass Sie sie durch LOW-Signal erleuchten und mit HIGH-Signal ausschalten.
    • Pin 4 (S-GND) legen Sie ebenfalls auf Common GND des Arduino.
    • Pin 5 (Vo) dient zum Messen des Staubs als Spannungswert. Legen Sie den Pin an an einen Analog-Pin des Arduino mit 10 Bit Auflösung bei der Analog-Digital-Wandlung. Wir verwenden A1.
    • Pin 6 (Vcc) verbinden Sie direkt mit der Versorgungsspannung des Pro Mini.
    • Der Elko verbindet Pin 1 des Sharp Dust Sensors mit GND.
Sharp Feinstaubsensor (Bild: sparkfun.com)
Gesamt-Schaltung

Insgesamt ergibt sich folgendes Bild in Fritzing. Da ich keine Beschreibung des Staubsensors als Fritzing-Part gefunden habe, muss eine Notiz mit der Beschreibung der insgesamt sechs Verbindungen genügen (oberer Teil der Schaltung).

Insgesamt ergibt sich obige Schaltung

In der Schaltung sind alle Sensoren angeschlossen. Wie bereits erwähnt, arbeitet der Luftdrucksensor BMP180 über den I2C-Bus mit dem Pro-Mini zusammen (Analoge Ports A4, A5).

Der Sketch

Die gute Nachricht: Mit Hilfe von Bibliotheken erleichtert sich die Aufgabe spürbar. Folgende Bibliotheken verwendet der Sketch für den eFrog:

  • Für den Sharp-Feinstaubsensor erhalten Sie eine Bibliothek, die sie in die Arduino IDE importieren.
  • Von Adafruit brauchen wir die allgemeine Sensor-Bibliothek, die Sie hier finden. Ohne diese Bibliothek ergeben sich bei nachfolgenden Bibliotheken Fehlermeldungen des Compilers, weil die Adafruit-Bibliotheken die allgemeine Sensor-Library voraussetzen.
  • Für den Bosch Luftdrucksensor BMP180 finden Sie eine entsprechende Bibliothek von Adafruit auf diesem GitHub-Ordner.
  • Last but not least findet sich die Bibliothek für den DHT22 oder DHT11 ebenfalls auf einem DHT22/DHT11-spezifischen GitHub-Verzeichnis. Dank wiederum an Adafruit!

Sobald Sie die obigen Bibliotheken in die Arduino IDE importiert haben, können Sie die dort mitgelieferten Beispiele nutzen, um jeden der Sensoren separat zu testen. Sie erinnern sich sicher an den Menü-Pfad: [capps]File | Examples[/caps].

Der eigentliche Sketch wird dadurch zum Kinderspiel. Der nachfolgende Code dürfte relativ selbsterklärend sein. Das trifft aber nur deshalb zu, weil die verwendeten Bibliotheken Faktoren wie komplexes Timing oder die teilweise nicht trivialen Berechnungen der physikalischen Größen aus den gemessenen Spannungen kapseln.

////////////////////////////////////////////////////////////////////
//
// Kleine Wetterstation mit
// Luftdrucksensor Bosch BMP180
// Feinstaubsensor Sharp GP2Y1010
// Feuchtigkeitssensor DHT22/DHT11
//
// Anschluss an Pro Mini, Stromversorgung über FTDI-Breakout Board
// Arduino Pro Mini mit 8Mhz, ATmega328, 3.3V
//
// Für Heise Developer Blog "Der pragmatische Architekt"
// 10. Juli 2016
// Michael Stal
//
/////////////////////////////////////////////////////////////////////


#include <Wire.h> // I2C-Unterstützung
#include <DHT.h> // Bibliothek für DHT22/DHT11
#include <Adafruit_Sensor.h> // Allgemeine Adafruit Sensorbibliothek
#include <Adafruit_BMP085_U.h> // Bibliothek für BMP180-Support
#include <SharpDust.h> // Bibliothek für Staubsensor


// Vereinbarungen zur Konfiguration von DHT22 bzw. DHT11
#define DHTPIN 2 // Digitalpin mit dem DHT22
#define DHTTYPE DHT22 // Sensor Typ: DHT 22 (oder für DHT 11: DHT11)
DHT dht(DHTPIN, DHTTYPE); // DHT-Zugriffsobjekt

//Anschlüsse des Staubsensors konfigurieren

int dustSensorMeasurePin = 1; // Analog A1: Anschluss zur Messung
int dustSensorLed = 12; // Anschluss IR-LED

// Variable für Zugriff auf Luftdrucksensor:

Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10085);

// Initialisierungsarbeiten

void setup(){
Serial.begin(9600); // Serielle Kommunikation auf 9600 Baud einstellen
pinMode(dustSensorLed,OUTPUT); // Ausgabe an die Staubsensor-LED

/* Initialisieren des Luftdrucksensors */
if(!bmp.begin())
{
/* Funktioniert der Zugriff auf den BMP180 nicht -> Fehlermeldung: */
Serial.print("Kein BMP180 gefunden. Bitte Schaltung ueberpruefen");
while(1);
}

dht.begin(); // DHT22 bzw. DHT11 starten

// Staubsensor starten
SharpDust.begin(dustSensorLed, dustSensorMeasurePin);

}

void loop(){ // Und hier erfolgen die eigentlichen Messungen
Serial.println("");
Serial.println("");
Serial.println("********************************");
Serial.println("********* Neue Messung *********");
Serial.println("********************************");
Serial.println("");
Serial.println("");
Serial.println("---------------------------------");
Serial.println("Messung - Feinstaubbelastung");
Serial.println("---------------------------------");
Serial.print(F("Staub: "));
Serial.print(SharpDust.measure()); // Wert einholen
Serial.println(F(" mg/m^3"));

delay(1000); // Eine Sekunde noch warten

Serial.println("");
Serial.println("---------------------------------");
Serial.println("Messung - Luftdruckmessung");
Serial.println("---------------------------------");
/* Neues Event vom Luftdrucksensor holen */
sensors_event_t event;
bmp.getEvent(&event);

/* Ergebnisse mit Luftdruck in hPa */
if (event.pressure) // Es konnte ein Wert ermittelt werden:
{
/* Luftdruck in hPa anzeigen */
Serial.print("Luftdruck: ");
Serial.print(event.pressure);
Serial.println(" hPa");

// Der BMP180 kann auch Temperaturen messen:
float bmp180Temperature;
bmp.getTemperature(&bmp180Temperature);
Serial.print("Temperatur: ");
Serial.print(bmp180Temperature);
Serial.println(" C");

// Höhe ermitteln:
float seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA;
Serial.print("Hoehe: ");

// Vergleich mit Luftdruck in Meereshöhe => ungefähre Höhe
Serial.print(bmp.pressureToAltitude(seaLevelPressure,
event.pressure));
Serial.println(" m");
Serial.println("");
}
else // Messung fehlgeschlagen:
{
Serial.println("Fehler beim BMP180 Sensor");
}
delay(1000); // noch eine Sekunde warten
Serial.println("");
Serial.println("---------------------------------");
Serial.println("Messung - Feuchtigkeit/Temperatur");
Serial.println("---------------------------------");

// Feuchtigkeitswert bestimmen
float dhtHumidity = dht.readHumidity();
// Temperatur in Celsius auslesen
float dhtTemperature = dht.readTemperature();


// Sinnvolle Ergebnisse ermittelt?
if (isnan(dhtHumidity) || isnan(dhtTemperature)) {
Serial.println("Konnte nicht vom DHT-Sensor lesen.");
return;
}


// Hitzeindex ermitteln mit Argument "false",
// da in Celsius gemessen werden soll, nicht in Fahrenheit

float hic = dht.computeHeatIndex(dhtTemperature, dhtHumidity, false);
Serial.print("Feuchtigkeit: ");
Serial.print(dhtHumidity); Serial.print(" %\t");
Serial.println("");
Serial.print("Temperatur: ");
Serial.print(dhtTemperature); Serial.print(" C ");
Serial.println("");
Serial.print("Hitzeindex: ");
Serial.print(hic); Serial.print(" C ");
Serial.println("");
Serial.println("****** E N D E Messschleife *****");
delay(10000); // Nächste Iteration bzw. Messung nach 10 Sekunden
}

Ausbauideen

Natürlich hat eine wirklich bedienerfreundliche Wetterstation keine Ausgabe über einen seriellen Monitor. Als Ergänzung ließe sich deshalb zum Beispiel ein LCD oder ein kleines OLED-Display nutzen. Wer will, kann selbstverständlich auch noch weitere Sensoren hinzufügen.

Und natürlich lässt sich nach erfolgter Programmierung des Arduino Pro Mini das FTDI-Board in der DiY-Wetterstation durch eine Batterie und einen kleinen Spannungsregler mit festen 3,3 V (oder 5 V) Betriebsspannung ersetzen. Wer Zugriff auf einen 3D-Drucker hat, kreiert sich ein Gehäuse für die Station, was speziell für den Außeneinsatz Sinn macht.

Auch eine Ausgabe der Messergebnisse auf einer Webseite ist denkbar. Da wir kein LAN-Kabel verlegen wollen, benötigen wir drahtlose Kommunikation. Genau um dieses Thema geht es in den nächsten Folgen, an deren Ende Sie wissen, wie Sie mit 2 bis 3 Euro Kosten WLAN ergänzen. Oder Bluetooth!