Luft-Feuchtigkeit messen (🚧)

Viele Messgeräte, viele Werte
Viele Messgeräte, viele Werte

Motivation vernetzte Taupunkt-Lüfter: Nicht jeder Lüfter müsste einen eigenen Aussensensor benötigen, wenn die Steuerungen sind über WLAN vernetzt sind? Ich suche nun geeignete Sensoren. Ein ganzer Zoo von Messgeräten und Sensoren ist hier zusammen gekommen und zeigt unterschiedliche Werte an. Beeindruckt bin ich von der Abweichung der zwei Ecowitt-Sensoren bei der Feuchtigkeitsmessung. Bei der Inbetriebnahme waren die Werte noch praktisch identisch. Ein Sensor war längere (5 Monate) Zeit im trockenen Heizungskeller, der andere in einem feuchten Kabuff unter einer Treppe. In der selben trockenen Umgebung zeigt nun der Sensor aus dem „Feuchtgebiet“ eine 4+% höhere Feuchtigkeit an. Für den Lüfter ist der Taupunkt (Dew Point) entscheidend.

🤖 Frage an Perplexitiy: DHT22 vs. BME280

Kurzfassung: Für neue Projekte ist der BME280 dem DHT22 fast immer vorzuziehen – genauer, schneller, stabiler, flexibler, plus Luftdruck.[2][4][6]

🤖 Technische Unterschiede

MerkmalDHT22 (AM2302)BME280
MessgrößenTemperatur, LuftfeuchteTemperatur, Luftfeuchte, Druck [2][4]
Schnittstelle1‑Wire‑ähnliches proprietärI²C oder SPI [2][4]
Versorgung3,3–5,5 V3,3–5 V (auf Breakout) [2][4]
Temp‑Genauigkeitca. ±0,5 °Cca. ±1 °C typisch, oft besser [4][6]
Feuchte‑Genauigkeitca. ±2–3% rFca. ±2–3% rF [4][5]
Temp‑Auflösung0,1 °C0,01 °C [4][5]
Messbereich Temp−40…80 °C−40…85 °C [2][4]
Messintervall min.≥2 sdeutlich schneller möglich [2][4]
Reaktionszeiteher träge (mehrere Minuten)deutlich schneller [6]
Langzeitkonstanzgrößere Streuung zwischen Stückssehr gute Reproduzierbarkeit [6]
Preis (Breakout)ähnlich wie BME280ähnlich wie DHT22 [1][3][4]

🤖 Praxis-Erfahrungen aus Tests

  • Mehrere unabhängige Messreihen zeigen, dass BME280‑Sensoren enger beieinander liegen und näher an Referenzthermometern sind als DHT22‑Exemplare.[3][6]
  • DHT22‑Stücke streuen teils über 1 °C, während BME280‑Stücke eher im Bereich 0,1–0,2 °C auseinanderliegen.[6]
  • Beim Sprung auf andere Temperaturen reagieren BME280 und z.B. DS18B20 deutlich schneller, während der DHT22 sich langsam angleicht.[6]

🤖 Software- und Protokoll-Aspekte

  • DHT22 nutzt ein eigenes Timing‑Protokoll mit relativ enger Toleranz; Implementierungen sind fehleranfälliger und blockierend, gerade bei ESP‑Plattformen mit WLAN.[10][2]
  • BME280 hängt einfach am I²C‑ oder SPI‑Bus, lässt sich mit Standard‑Libraries (Adafruit, Bosch) nutzen und gut in bestehende Designs integrieren.[4][2][10]
  • Wenn du sowieso einen I²C‑Bus auf dem Board hast (RTC, Display, andere Sensoren), „fällt“ der BME280 fast kostenlos mit ab.[10]

🤖 Wann welchen Sensor nehmen?

DHT22 sinnvoll, wenn

  • du alte Hardware/Codebasis hast, die explizit auf DHT22 ausgelegt ist,
  • du noch viele DHT22 auf Lager hast und maximale Genauigkeit nicht kritisch ist.

BME280 sinnvoll, wenn

  • du ein neues Projekt startest (ESP32/ESP8266/Arduino etc.),
  • du zuverlässigere, reproduzierbare Messwerte und schnellere Reaktion willst,
  • du Luftdruck (Wetter, Höhenabschätzung, Lüftungssteuerung) gebrauchen kannst,
  • du saubere I²C‑/SPI‑Integration bevorzugst.[2][4][6][10]

Für deine typischen ESP‑/Arduino‑Projekte im Smart‑Home‑ oder Logging‑Bereich würde ich heute klar BME280 empfehlen; DHT22 würde ich nur noch einsetzen, wenn er schon verbaut ist und ausreichend „gut genug“ misst.[8][9][6]

🤖 Quellen

[1] BME280 Vs. DHT22 Temperature Sensor Shootout as Tested on the TTGO T-Display ESP32 https://www.youtube.com/watch?v=y2-55LDZYKU
[2] Bme280 Vs Bmp180 https://randomnerdtutorials.com/dht11-vs-dht22-vs-lm35-vs-ds18b20-vs-bme280-vs-bmp180/
[3] BME280 Vs DHT22 Temperature Sensor Shootout as Tested on the TTGO TDisplay ESP32 https://www.eevblog.com/forum/microcontrollers/bme280-vs-dht22-temperature-sensor-shootout-as-tested-on-the-ttgo-tdisplay-esp32/
[4] DHT11 vs DHT22 vs BME280 vs DS18B20 – Best Arduino … https://zaitronics.com.au/blogs/guides/best-arduino-digital-temperature-sensors
[5] Сравнение датчиков DHT11, DHT22 и BME280 https://myproject.com.ua/ru/sravnenye-datchykov-temperatury-y-vlazhnosty-dht11-vs-dht22-vs-bme280-ru.html
[6] DHT22 v BME280 v DS18B20 – Der Vergleich https://datort.de/vergleiche-tests/512/dht22-v-bme280-v-ds18b20-der-vergleich/
[7] DHT22 v DS18B20 v BME280: Temperatursensoren im Vergleich – Welcher ist der Beste fürs Projekt? https://www.youtube.com/watch?v=iZZr21FaaMw
[8] BME280 vs DHT22 – Compared with test programme https://www.reddit.com/r/esp32/comments/ju1qea/bme280_vs_dht22_compared_with_test_programme/
[9] BME280 vs DHT22 Langzeitbetrieb und Ausfallsicherheit https://forum-raspberrypi.de/forum/thread/44440-bme280-vs-dht22-langzeitbetrieb-und-ausfallsicherheit/
[10] Chosing a humidity sensor : skip DHT22, go for BME280! | Details | Hackaday.io https://hackaday.io/project/28775-my-smart-fishroomanimal-room/log/72341-chosing-a-humidity-sensor-skip-dht22-go-for-bme280

DHT22 / AM2302 (Temperatur und Luftfeuchtigkeit)

Testaufbau mit zwei DHT22, einer (links mit dem Punkt) seit >4Jahren aus der Packung, der andere frisch aus der Antistatik-Folie.
Jeder Sensor wird über eine eigene Daten-Leitung angeschlossen. Dazu ein BME 280 von AZ und ein BME 680 von PIMORONI.
Anzeige oben nach unten = links nach rechts: Temperatur, Luftfeuchtigkeit, Taupunkt. Der BME 280 fühlt mehr Trockenheit.
Mit der IR-Kamera habe ich eine leicht erhöhte Temperatur bei den BME-Modulen gesehen, liegt an den Spannungswandlern.

Luftfeuchte Sensoren Vergleich DHT22 BME280 BME680
Luftfeuchte Sensoren Vergleich DHT22 BME280 BME680
#include <Wire.h>
#include <LiquidCrystal_PCF8574.h>

#include "DHT.h" //DHT Bibliothek laden
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <Adafruit_BME680.h>

#define DHTPIN1 2 // Der Sensor1 wird an PIN 2 angeschlossen
#define DHTPIN2 3 // Der Sensor2 wird an PIN 3 angeschlossen

#define DHTTYPE DHT22    // Es handelt sich um den DHT22 Sensor

DHT dht1(DHTPIN1, DHTTYPE);
DHT dht2(DHTPIN2, DHTTYPE);

LiquidCrystal_PCF8574 lcd (0x27); // LCD-Adresse auf 0x27
Adafruit_BME280 bme2; // I2C
Adafruit_BME680 bme6; // I2C

float dewPoint(float celsius, float humidity){
  float a = 17.271;
  float b = 237.7;
  float temp = (a * celsius) / (b + celsius) + log(humidity/100);
  return  (b * temp) / (a - temp);
}

void setup() {
  //Serial.begin(9600); //Serielle Verbindung starten
  unsigned status;
  lcd.begin(20, 4); // initialize the lcd
  lcd.clear();
  lcd.setBacklight(255);
  status = bme2.begin(0x76); // AZ-BME280 kann nur 0x76
  if (!status) {
    lcd.print(F("Kein BME280 erkannt."));
    while (1) delay(10);
  }
  status = bme6.begin(0x77); // PIMORONI BME680 mit duchgetrennten Pad kann 0x77
  if (!status) {
    lcd.print(F("Kein BME680 erkannt."));
    while (1) delay(10);
  }
  dht1.begin(); // Sensor starten
  dht2.begin(); // Sensor starten
  bme6.setTemperatureOversampling(BME680_OS_8X);
  bme6.setHumidityOversampling(BME680_OS_2X);
  bme6.setPressureOversampling(BME680_OS_4X);
  bme6.setIIRFilterSize(BME680_FILTER_SIZE_3);
  bme6.setGasHeater(320, 150); // 320*C for 150 ms
}

void loop() {
  delay(2000); //Zwei Sekunden Vorlaufzeit bis zur Messung (der Sensor ist etwas träge)
  if (! bme6.performReading()) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(F("BME680 Lesefehler"));
    return;
  }
  float temperatur1 = dht1.readTemperature();
  float temperatur2 = dht2.readTemperature();
  float temperatur3 = bme2.readTemperature();
  float temperatur4 = bme6.temperature;
  float luftfeuchtigkeit1 = dht1.readHumidity();
  float luftfeuchtigkeit2 = dht2.readHumidity();
  float luftfeuchtigkeit3 = bme2.readHumidity();
  float luftfeuchtigkeit4 = bme6.humidity;
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(temperatur1);
  lcd.print(F("\xdf "));
  lcd.print(luftfeuchtigkeit1);
  lcd.print(F("% "));
  lcd.print(dewPoint(temperatur1,luftfeuchtigkeit1));
  lcd.setCursor(0,1);
  lcd.print(temperatur2);
  lcd.print(F("\xdf "));
  lcd.print(luftfeuchtigkeit2);
  lcd.print(F("% "));
  lcd.print(dewPoint(temperatur2,luftfeuchtigkeit2));
  lcd.setCursor(0,2);
  lcd.print(temperatur3);
  lcd.print(F("\xdf "));
  lcd.print(luftfeuchtigkeit3);
  lcd.print(F("% "));
  lcd.print(dewPoint(temperatur3,luftfeuchtigkeit3));
  lcd.setCursor(0,3);
  lcd.print(temperatur4);
  lcd.print(F("\xdf "));
  lcd.print(luftfeuchtigkeit4);
  lcd.print(F("% "));
  lcd.print(dewPoint(temperatur4,luftfeuchtigkeit4));
}

Den Tau-Punkt berechnen

📖 Berechnung des Taupunkts von feuchter Luft Näherungsweise Berechnung aus Temperatur und Luftfeuchtigkeit:

float dewPoint(float celsius, float humidity){ // 
  float a = 17.271;
  float b = 237.7;
  float temp = (a * celsius) / (b + celsius) + log(humidity/100);
  return  (b * temp) / (a - temp);
}
float dewPoint(float t, float r) { // aus Make-Artikel
  float a, b;
  if (t >= 0) {
    a = 7.5;
    b = 237.3;
  } else if (t < 0) {
    a = 7.6;
    b = 240.7;
  }
  float sdd = 6.1078 * pow(10, (a*t)/(b+t)); // Sättigungsdampfdruck in hPa
  float dd = sdd * (r/100);                  // Dampfdruck in hPa
  float v = log10(dd/6.1078);                // v-Parameter
  float tt = (b*v) / (a-v);                  // Taupunkttemperatur (°C)
  return tt;  
}
float dewPoint(float temperature, float humidity) { // 🤖
  float a, b;
  if (temperature >= 0.0) {
    a = 7.5;
    b = 237.3;
  } else {
    a = 7.6;
    b = 240.7;
  }
  float gamma = log(humidity / 100.0) + (a * temperature) / (b + temperature);
  return (b * gamma) / (a - gamma);
}

Bosch BME 280 (Temperatur, Luftdruck und Luftfeuchtigkeit)

Beim Betrieb über I2C kann man beim 🔗AZ-Delivery-Modul nicht die zweite mögliche I2C-Adresse 0x77 einstellen, ist auf 0x76 festgelegt, somit kann nur ein Sensor pro I2C-Bus betrieben werden.

AZ BME280 Modul
AZ BME280 Modul

Betriebs-Spannungsbereich: von 3.3V bis 5V DC
Stromverbrauch: < 1mA
Temperaturbereich: von -40°C bis 85 °C
Temperaturgenauigkeit: ±1.0°C
Druckbereich: von 300 bis 1100 hPa
Druckgenauigkeit: ±1hPa
Luftfeuchtigkeitsbereich: von 0 bis 100% RH
Genauigkeit der Feuchte: ±3%
Abmessungen: 9 x 11 x 2mm

#include <Wire.h>
#include <LiquidCrystal_PCF8574.h>

#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define SEALEVELPRESSURE_HPA (1013.25)
LiquidCrystal_PCF8574 lcd (0x27); // LCD-Adresse auf 0x27

Adafruit_BME280 bme; // I2C

void setup() {
  unsigned status;
  status = bme.begin(0x76); 
  lcd.begin(20, 4); // initialize the lcd
  lcd.clear();
  lcd.setBacklight(255);
  if (!status) {
    lcd.print(F("Kein Sensor erkannt."));
    while (1) delay(10);
  }
}

void loop() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(F("Temp:   "));
  lcd.print(bme.readTemperature());
  lcd.print(F("\xdf\C "));
  lcd.setCursor(0,1);
  lcd.print(F("Druck:  "));
  lcd.print(bme.readPressure()/100); // Ausgabe in HektoPascal
  lcd.print(F(" hPa"));
  lcd.setCursor(0,2);
  lcd.print(F("Hoehe:  "));
  lcd.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
  lcd.print(F(" m"));
  lcd.setCursor(0,3);
  lcd.print(F("Feucht: "));
  lcd.print(bme.readHumidity());
  lcd.print(F("%"));
  delay(2000);
}

Bosch BME 680 (Temperatur, Luftdruck, Luftfeuchtigkeit und VOC)

Hab ich rumliegen, ist aber für die Aufgabe übertrieben. Mit der BSEC2-Lib von Bosch kann der VOC-Teil besser analysiert werden, scheint einen ESP32 zu brauchen.

#include <Wire.h>
#include <LiquidCrystal_PCF8574.h>

#include <Adafruit_Sensor.h>
#include <Adafruit_BME680.h>
LiquidCrystal_PCF8574 lcd (0x27); // LCD-Adresse auf 0x27

Adafruit_BME680 bme; // I2C

void setup() {
  unsigned status;
  status = bme.begin(0x77); 
  lcd.begin(20, 4); // initialize the lcd
  lcd.clear();
  lcd.setBacklight(255);
  if (!status) {
    lcd.print(F("Kein Sensor erkannt."));
    while (1) delay(10);
  }
  // Set up oversampling and filter initialization
  bme.setTemperatureOversampling(BME680_OS_8X);
  bme.setHumidityOversampling(BME680_OS_2X);
  bme.setPressureOversampling(BME680_OS_4X);
  bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
  bme.setGasHeater(320, 150); // 320*C for 150 ms
}

void loop() {
  if (! bme.performReading()) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(F("Lesefehler"));
    return;
  }
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(F("Temp:   "));
  lcd.print(bme.temperature);
  lcd.print(F("\xdf\C "));
  lcd.setCursor(0,1);
  lcd.print(F("Druck:  "));
  lcd.print(bme.pressure/100); // Ausgabe in HektoPascal
  lcd.print(F(" hPa"));
  lcd.setCursor(0,2);
  lcd.print(F("Feucht: "));
  lcd.print(bme.humidity);
  lcd.print(F("%"));
  lcd.setCursor(0,3);
  lcd.print(F("Gas:    "));
  lcd.print(bme.gas_resistance/1000.0);
  lcd.print(F(" kOhms"));
  delay(2000);
}

Bosch BME 688 (Temperatur, Luftdruck, Luftfeuchtigkeit und VOC)

Bosch BME688 gefädelt
Bosch BME688 gefädelt

Hab ich auch rumliegen,ist aber für die Aufgabe übertrieben. Mit der BSEC2-Lib von Bosch kann der VOC-Teil besser analysiert werden, scheint einen ESP32 zu brauchen.