[gelöst] DHT22 Probleme

Hi,

ich hab in einem Projekt einen DHT22.
Aber damit habe ich immer wieder Fehler beim Lesen des Sensors.
Verwende die DHT sensor lib von Adafruit V 1.3.0.
Verkabelt ist er mit ca. 10cm Kabel. Pin 2 (Datenleitung) ist mit 1k Pullup gegen +Ub.
Ich betreibe ihn mit 3,3V. Aber das soll lt. Datenblatt möglich sein.
Ich lese ihn alle 5 sek. aus. Da bringt er dann in ca. 10% Fehler.
Habt ihr da ähnliche Erfahrungen gemacht?
Ist der so "instabil"?

Den 1K Pullup brauchst du eigentlich nicht. Die DHT22 haben einen eingebauten 4,7K Pullup, zumindest die die ich habe. Aber kannst es ggf. nachmessen. Bei mir sind die Strippen bis zu 20cm lang und laufen mit den ESP8266 problemlos und stabil mit den 3,3V. Abgefragt werden die mir allerdings nur alle 5 Minuten. Da hab ich über Tage hinweg keine Fehlmessung gehabt.

Ich hab bei mir mal den Versuch gemacht.

Alle 5 Sekunden eine Messung, und das über eine Stunde hinweg.

Am ende waren es ca. 70% fehlerhafte Messungen.

Seitdem hab ich den DHT22 weg geworfen, und hab mir BME280 geholt. Die sind zwar (von Watterott) teurer, aber liefern dafür, wenn du 5 davon nebeneinander packst, alle 5 den selben Wert.

hk007:
Habt ihr da ähnliche Erfahrungen gemacht?
Ist der so "instabil"?

Ich habe mir mal vor circa vier Jahren den DHT11^und DHT22 und zwei verschiedene Arduino-DHT-Libraries angesehen, Und "instabil" bzw. "grenzwertig" war dabei allenfalls der Code der Libraries und nicht der Sensor. Das einzige Manko am Sensor, das ich feststellen konnte: Der fabrikfrische Sensor hat jeeils deutlich zu niedrige Luftfeuchtewerte gemessen, weit außerhalb der im Datenblatt angegebenen Toleranz. Das konnte man allerdings verbessern, indem man den Sensor einem Refresh-Zyklus bei erhöhter Luftfeuchte unterzogen hat.

Das Problem am Code der Libraries war: Die Library-Programmieer hatten eine enge Schleife für das Heraustickern der 40 Bits (5 Bytes) aus dem Sensor geschrieben und sich dabei auf das micros() Timing verlassen, ohne zu Berücksichtigen, daß während der Schleife jederzeit ein Timer0-Interrupt auftreten kann, der das Timing um vier Microsekunden versaut und langsamer macht (Laufzeit der Timer0-Interruptbehandlungsroutine). Da die beiden Library-Programmierer den Code ihrer Libraries wohl auch noch gegenseitig abgechrieben hatten, hatten dann beide Libraries das Problem, dass unter den 40 auszulesenden Bits immer mal ein Bit falsch ausgelesen werden konnte. Und zwar nicht deshalb, weil der DHT-Sensoreinzelne Bits mit falschem Timing gesendet hätte, sondern weil die Library-Programmierer so instabilen Code geschrieben hatte, der den standardmäßig auf Arduinos laufenden Timer0 und die Laufzeit der Timer0-Interruptbehandlung außer Betracht gelassen hat, so dass das Auslesen der Bit-Zeiten auch mal einige Mikrosekunden daneben liegen konnte, was zusammen mit einer ungünstig gewählten Split-Zeit zur Unterscheidung von 0-Bits und 1-Bits regelmäßig zu Bit-Lesetfehlern geführt hat, die dann natürlich zu einer falschen Prrüfsumme und zu einer insgesamt falschen Auslesung geführt haben.

Mein Fazit damals:
Scheiß-DHT-Libraries!
Gute DHT-Sensoren!

Wobei der DHT11 mit einer Temperaturauflösung von nur 1°C natürlich auch für einen Billigsensor ein extrem schwaches Bild abgibt. Ich kenne RTC-Uhrenchips, die neben der Uhrzeit als Abfallprodukt noch nebenbei eine höher aufgelöste Temperaturmessung liefern können. Der DHT22 ist für Temperaturmessungen OK und hochauflösend.

dann ist es doch Zeit ne vernünftige Library zu schreiben!

@Jurs
Weilche Bibliothek bzw Auslesefunktion räts Du?
Grüße Uwe

Hallo hk007,

ich habe seit einigen Jahren5 DHT22 für meine Temperatursteuerung in der Wohnung. Die Leitungen sind die alten die schon verlegt waren ohne Abschirmung oder sonstiges und sind ca. 10-15m lang. Hatte am Anfang auch viele Störungen drauf. Ein Elko 4,7 MicroFarad direkt am Sensor hat geholfen. Jetzt ist nur noch manchmal wenn irgendwo ein Lichtschalter betätigt wird eine Fehllesung. Ist aber zu vernachlässigen. Ausgelesen werden die Sensoren alle 2sek.

Grüßle, Armin

@jurs
OK,
Ich hab in der Software einige Ticker-Instanzen laufen (60s / 5s / 2s / 1s).
In denen arbeite ich zwar keinen längeren Code ab, sondern setzte mir nur immer ein Enable-Bit damit ich beim nächsten Loop-Durchlauf den entsprechenden Programmcode abarbeite.
Das wird dem zeitkritischen Code der DHT-lib wohl auch nicht entgegenkommen.
Vllt. muss ich das mal etwas untersetzen. Nicht alle 5s sondern alle 4,9s.
Aktuell verwerfe ich halt die ungültigen Sensorwerte.

  if (EnableDHT) {
    dht_temp = dht.readTemperature();
      if (!isnan(dht_temp)) {TempRoom = dht_temp;}
      if (isnan(dht_temp)) {DEBUG << "Fehler beim Lesen des Sensors" << endl;}
    EnableDHT = false;
  }

uwefed:
@Jurs
Weilche Bibliothek bzw Auslesefunktion räts Du?
Grüße Uwe

Ich rate zu überhaupt keiner Bibliothek.

Wenn ich heute eine Auslesefunktion für DHT11 oder DHT22 benötigen würde, dann würde ich mir nochmal das Datenblatt herunterladen, dort ins Timingdiagramm schauen, und mir selbst eine Funktion schreiben, die die 40 Datenbits aus dem Sensor raustickert. Was im wesentlichen eine for-Schleife wäre, die vierzig mal durchlaufen wird, mit ein paar Zeilen Kleckerkram-Code drumherum.

Und eines würde diese Funktion bei mir garantiert nicht: Die Temperatur oder Luftfeuchte als "float" zurückliefern.

Wenn ich eine Funktion für den Sensor schreiben würde, dann kommt dabei der Wert sowohl für die Temperatur als auch für die Luftfeuchte als "int" zurück.

Temperatur als "Zehntelgrad Celsius"

Luftfeuchte als "Zehntelprozent relative Feuchte"

Und wer dann unbedingt 'float' braucht, obwohl der Sensor ganzzahlige Werte liefert, der könnte dann selbst, innerhalb seiner Applikation den int-Wert durch 10.0 teilen und bekommt ein float-Resultat.

Den Idiotenkram, dass ein Sensor von sich einen ganzzahligen Integer.Wert liefert, aber alle Libraries, die den Sensor auslesen, immer den Idiotenkram von 'float" zurückliefern, den würde ich schon mal als erstes NICHT mitmachen, wenn ich eine Funktion schreiben würde.

jurs:
Wenn ich heute eine Auslesefunktion für DHT11 oder DHT22 benötigen würde, dann würde ich mir nochmal das Datenblatt herunterladen, dort ins Timingdiagramm schauen, und mir selbst eine Funktion schreiben, die die 40 Datenbits aus dem Sensor raustickert.

So weit wenn ich schon wäre... :confused:
Da bleibt für mich nur: Nimm die lib und mach das Beste daraus.

hk007:
Da bleibt für mich nur: Nimm die lib und mach das Beste daraus.

Hast Du als Workaround gegen fehlerhafte Sensorauslesung schon mal folgendes probiert:

  • alle Interrupts sperren, während der DHT-Sensor mit einer Libraryfunktion ausgelesen wird?

Pseudo-Programmlogik in etwa:

noInterrupts(); // Interrupts sperren
float temp= readTemperatureFromDHT(); // Temperatur mit Bibliotheksfunktion auslesen
interrupts();// Interrupts wieder aktivieren

Ändert sich dann etwas an den Auslesefehlern?

@Jurs,

danke für die Idee.
Ich habs mal probiert. Nicht wirklich eine Verbesserung. Sind immer noch Lesefehler. Subjektiv evtl. ein paar weniger, aber das ist schwer zu beurteilen, da die Lesefehler vorher auch immer zufällig waren, und kein bestimmtes Muster hatten.

Um das Bild zu vervollständigen: Ich nutze atm einen ESP8266 und keinen reinen Arduino. Aber das sollte doch imho für die Software transparent sein?

EDIT:
Ich glaube mich zu erinnern, dass die Funktion noInterrupts() beim ESP nicht so vollständig funktioniert, wie beim klassischen Arduino.

Ich habe am NodeMCU einen SHT21 über I2C im Dauerbetrieb laufen. Da habe ich noch keine Probleme festgestellt.

Gruß Tommy

Gibts da vielleicht unterschiedliche Libs?
Ich hab vor Monaten mal in der Firma tagelang
mit dem DHT22 gemessen... da war "mal" ein
blödsinns Wert dabei. Gemessen hatte ich alle
5 Sekunden.?
Ich hab ihn dann gegen analoge Feuchtigkeits
und Temperatursensoren getauscht, weil ich ein "ständiges" Datenlogging haben musste.
(keine 2...5 Sekunden Hüpfer).
Aber mit der Genauigkeit war ich zufrieden.

Stefan

Muss das Thema noch mal mit neuen Erkenntnissen hochholen.
Also: Alles was ich probiert habe (andere lib, Hardwarebeschaltung ändern usw..) hat nichts gebracht.

Aber heute ist mir etwas aufgefallen:
Ich habe auf dem ESP noch einen Webserver laufen. Die Software besteht aus 2 Teilen.
Den Teil für die void setup() und den Hauotteil für die zyklische Abarbeitung in der loop:

/******************************************************************
 *                           SETUP                                *
 ******************************************************************/
void WebServer_Setup () {
  DEBUG << "Initialisierung WebServer" << endl; 
  server.on("/", handleRoot);
  server.on("/options", handleOptions);
  server.onNotFound(handleNotFound);
  
  server.begin();
  DEBUG << "HTTP server started at Port " << HTTPport << endl;  
}

/******************************************************************
 *                            MAIN                                *
 ******************************************************************/
void WebServer_Loop() {
  server.handleClient();  
}

Und sobald ich den nur initialisert habe (also den Teil in der setup aufgerufen, ohne den loop-Teil aktiv), macht das Lesen des DHT die beschriebenen Probleme.

Kommen da die anfangs beschriebenen Timing-Probleme zur Geltung?

Hallo,
es scheint wohl zur dämlichen Angewohnheit zu werden, hier nur noch
SketchCodeSchnipzel zu veröffentlichen…
Das aber nur am Rande…

"Ich lese ihn alle 5 sek."
Hälst Du die latenzZeiten des Sensor ein?

"Da bringt er dann in ca. 10% Fehler."
Also 100mal ausgelesen- und 10 mal davon falsch.
Das ist zuviel. Hast Du das geändert?

Wenn Du nur den Arduino und BeispielProgramme für den DHT nimmst, läuft dieser
dann fehlerfrei?
Gruß und Spaß
Andreas

SkobyMobil:
es scheint wohl zur dämlichen Angewohnheit zu werden, hier nur noch
SketchCodeSchnipzel zu veröffentlichen…

Danke für das "dämlich" :-\
Ich poste Code schon mit Bedacht!
Was soll hier der andere Code? Der ist doch absolut nicht relevant. Glaube kaum dass sich jemand in eine großes Projekt einlesen will, um hier eine Antwort zu geben.
Ich hab das an Code gepostet, das bei Aufruf den Unterschied zwischen absolut einwandfreien und fehlerhaften Auslesen des DHT nach sich zieht. Und ich wollte darüber diskutieren, in wie weit die Webserver Routinen das Auslesen des Sensors beeinflussen könnten.

Hallo,
bitte schön.

"Was soll hier der andere Code? Der ist doch absolut nicht relevant."

Das ist der Typische Irrglauben.

Beispiel:

if ((digitalRead(LcdHb) == HIGH))
  {
mache LED an;
}

dann:

Hallo,
ich bin ganz neu mit dem Arduino. Ich will eine LED ein schalten. Kann sich das mal jemand anschauen?
Ich raffe es einfach nicht... Danke schön.
EgonTheJumper

Da kann keiner helfen, weil einfach keine Informationen vorliegen.

"Und ich wollte darüber diskutieren, in wie weit die Webserver Routinen das Auslesen des Sensors beeinflussen könnten.

Dann diskutieren wir mal...
Jede Webserver Routine ist in der Lage das Auslesen des Sensors zu beeinflussen!

Jetzt Du...
Gruß und Spaß
Andreas

So.

ich hab jetzt eine lib gefunden, die bei mir funzt. Hat Mark Ruys geschrieben.
Die von Adafruit ist halt einfach nicht sauber gelaufen. Noch dazu musste zu der DHT-lib noch die Adafruit-Sensor-lib installiert werden.
Mit der läuft der Sensor im 5sek-Takt seit ner 1/4h ohne Lesefehler :slight_smile:
Nur der Form halber: Der Aufruf und die Lesebefehle sind etwas anders.

Wen es interessiert: Hier der Link.

Hallo,
na, ist doch prima!
Viel Spaß damit.
Gruß
Andreas