Wettermessstation mit ESP32
Eine kleine Station, die Temperatur, Luftfeuchtigkeit und Luftdruck misst, auf einem OLED anzeigt und die Werte optional per WLAN weitergibt. Der Aufbau ist an einem Abend fertig — die interessanten Fragen kommen danach.
Denn eine Wetterstation zu bauen ist einfach. Eine zu bauen, die richtige Werte liefert, ist es nicht. Zwei Fehler stecken in fast jedem Selbstbauprojekt: Der Sensor misst die Abwärme des eigenen Mikrocontrollers, und der Luftdruck lässt sich nicht mit dem Wetterbericht vergleichen. Beides steht weiter unten.
Bauteile
| Bauteil | Beschreibung |
|---|---|
| ESP32 DevKit | Mikrocontroller mit WLAN |
| BME280 | Temperatur, Luftfeuchte und Luftdruck (I²C) |
| SSD1306 OLED 0,96" | Display 128 × 64 Pixel (I²C) |
| Gehäuse | 3D-gedruckt — Materialwahl siehe unten |
| USB-Kabel | Stromversorgung |
Verkabelung (I²C-Bus)
Beide Bauteile hängen am selben Bus:
| Signal | ESP32 | BME280 | OLED |
|---|---|---|---|
| SDA | GPIO 21 | SDA | SDA |
| SCL | GPIO 22 | SCL | SCL |
| VCC | 3,3 V | VIN | VCC |
| GND | GND | GND | GND |
Adressen prüfen, bevor gerätselt wird. Der BME280 sitzt je nach Modul auf 0x76 oder 0x77 (bestimmt durch den SDO-Pin), das OLED auf 0x3C oder 0x3D. Ein Adressscan spart viel Zeit:
from machine import Pin, I2C
i2c = I2C(0, sda=Pin(21), scl=Pin(22), freq=400000)
print([hex(a) for a in i2c.scan()])
Kommt eine leere Liste zurück, fehlen meist die Pull-up-Widerstände — die meisten Breakout-Module bringen sie mit, aber nicht alle. 4,7 kΩ nach 3,3 V an SDA und SCL beheben das.
Code (MicroPython)
from machine import Pin, I2C
import bme280, ssd1306, time
i2c = I2C(0, sda=Pin(21), scl=Pin(22), freq=400000)
bme = bme280.BME280(i2c=i2c, address=0x76)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
HOEHE = 420 # Standorthöhe über NN in Metern -- anpassen!
def auf_meeresniveau(p_hpa, t_celsius, hoehe_m):
"""Rechnet den gemessenen Luftdruck auf Meeresniveau um."""
return p_hpa * (1 - (0.0065 * hoehe_m) /
(t_celsius + 0.0065 * hoehe_m + 273.15)) ** -5.257
def anzeigen():
t, p, h = bme.read_compensated_data() # °C, Pa, %rF
t /= 100; p /= 25600; h /= 1024 # Rohwerte umrechnen
p_nn = auf_meeresniveau(p, t, HOEHE)
oled.fill(0)
oled.text("Wetterstation", 0, 0)
oled.text("-" * 16, 0, 10)
oled.text("Temp: {:.1f} C".format(t), 0, 24)
oled.text("Feuchte: {:.0f} %".format(h), 0, 36)
oled.text("Druck: {:.0f}".format(p_nn), 0, 48)
oled.show()
while True:
try:
anzeigen()
except OSError as e:
print("I2C-Fehler:", e) # Wackelkontakt soll nicht abstürzen
time.sleep(5)
Falle 1: Der Sensor misst den Mikrocontroller
Ein ESP32 verbraucht im WLAN-Betrieb je nach Last zwischen 150 und 250 mW. Diese Leistung wird vollständig zu Wärme — in einem kleinen geschlossenen Gehäuse, in dem auch der Temperatursensor sitzt.
Das Ergebnis ist keine Kleinigkeit: Zwei bis fünf Kelvin zu hoch ist der Normalfall, und weil die relative Luftfeuchte direkt an der Temperatur hängt, ist die Feuchtemessung damit gleich mit verfälscht — pro Kelvin Fehler etwa 4 Prozentpunkte in die falsche Richtung.
Lüftungsschlitze allein reichen dagegen nicht. Was hilft:
Den Sensor aus dem Gehäuse holen. Der BME280 kommt an ein kurzes Kabel und sitzt außerhalb, mit Abstand zur Elektronik. Das ist die wirksamste Maßnahme und kostet nur eine vieradrige Leitung. I²C verträgt dabei problemlos 20 bis 30 cm.
Deep Sleep nutzen. Wenn der ESP32 nur alle paar Minuten für zwei Sekunden aufwacht, sinkt die mittlere Verlustleistung um mehr als zwei Größenordnungen — und mit ihr die Eigenerwärmung. Für eine Station ohne Display ist das ohnehin der richtige Betriebsmodus, und batteriebetrieben wird es dadurch überhaupt erst möglich.
Kamineffekt einplanen. Öffnungen unten und oben lassen warme Luft nach oben abziehen. Schlitze nur an einer Seite bringen fast nichts.
Falle 2: Luftdruck ohne Bezug ist wertlos
Der BME280 misst den absoluten Luftdruck an seinem Standort. Der sinkt mit der Höhe um grob 1 hPa je 8 Meter. In 400 Metern Höhe zeigt die Station also rund 50 hPa weniger an als der Wetterbericht — nicht weil sie falsch misst, sondern weil alle Wetterdienste ihre Werte auf Meeresniveau umrechnen.
Die übliche Reduktion nach der barometrischen Höhenformel:
mit dem gemessenen Druck \(p\) in hPa, der Standorthöhe \(h\) in Metern und der Temperatur \(T\) in °C. Genau das macht die Funktion auf_meeresniveau() im Code oben — die Konstante HOEHE muss auf den eigenen Standort gesetzt werden, sonst stimmt der Absolutwert nicht.
Für die Wettervorhersage zählt ohnehin weniger der Absolutwert als die Tendenz: Fällt der Druck über drei Stunden um mehr als 1 hPa, ändert sich das Wetter meist innerhalb eines Tages.
Gehäuse: drinnen und draußen sind zwei Projekte
Für drinnen genügt ein einfaches Gehäuse mit Displayausschnitt, USB-Öffnung und Lüftungsöffnungen unten und oben.
| Parameter | Wert |
|---|---|
| Schichthöhe | 0,2 mm |
| Füllung | 20 % |
| Wandstärke | 1,2 mm |
| Stützstrukturen | nein |
Für draußen ändert sich die Materialfrage grundlegend. PLA ist dafür ungeeignet: Es erweicht bereits um 60 °C, und in der Sonne wird ein dunkles Gehäuse deutlich wärmer als das. Dazu kommt, dass PLA unter UV-Strahlung versprödet. Ein PLA-Gehäuse überlebt vielleicht einen Sommer, meist verzieht es sich vorher. Nimm stattdessen PETG oder, wenn es dauerhaft halten soll, ASA — beides ist UV-beständiger und deutlich wärmefester. Mehr dazu im Filament-Vergleich.
Und für den Außeneinsatz braucht der Sensor einen Strahlungsschutz: den charakteristischen Stapel aus schräg gestellten, gegeneinander versetzten Tellern, wie man ihn von jeder Wetterhütte kennt. Er lässt Luft zirkulieren, hält aber die direkte Sonne vom Sensor fern. Ohne ihn misst man in der Sonne 10 K zu viel und damit gar nichts Sinnvolles mehr. Als Fertigteil kostet so ein Schutz erstaunlich viel — gedruckt besteht er aus einem einzigen, mehrfach wiederholten Teller und ist damit fast umsonst.
Genauigkeit: was realistisch drin ist
| Größe | Datenblatt-Genauigkeit | in der Praxis |
|---|---|---|
| Temperatur | ±0,5 K | ±1 K, sofern die Eigenerwärmung im Griff ist |
| Luftfeuchte | ±3 % rF | ±5 %, mit Alterungsdrift über Jahre |
| Luftdruck | ±1 hPa | ±1 hPa, sehr stabil |
Der Feuchtesensor driftet über die Zeit und reagiert empfindlich auf Lösungsmitteldämpfe — auch auf die Ausgasungen frisch gedruckter Kunststoffe. Bosch beschreibt dafür eine Konditionierung; praktisch genügt es meist, das fertige Gerät ein paar Tage laufen zu lassen, bevor man den Werten traut.
Erweiterungsmöglichkeiten
- Datenlogging auf SD-Karte oder in eine Zeitreihendatenbank
- Webinterface — der ESP32 liefert die Werte als kleine Webseite aus
- Solarbetrieb mit Panel und LiPo, sinnvoll nur zusammen mit Deep Sleep
- Zweiter Sensor außen, um die Eigenerwärmung des Innensensors gegenzumessen
Weiterführendes
- Sensoren — Übersicht — Messprinzipien und ihre Grenzen
- Wahrnehmung: was Sensoren wirklich liefern — Genauigkeit, Präzision und warum Filtern Zeit kostet
- Filament-Vergleich — PLA, PETG, ASA und ihre Temperaturgrenzen
- Mikrocontroller — Auswahl und Grundlagen