Heute kam der neue Sensor DHT20 mit der Post. Wie immer war meine Neugierde nicht zu bremsen und er musste sofort ausprobiert werden. Da die Lieferung angekündigt war, hatte ich schon das Datenblatt aus dem Internet heruntergeladen und sorgfältig gelesen. Denn zunächst wollte ich nicht glauben, dass dieser Sensor, äußerlich baugleich mit dem DHT11 und DHT22, eine I2C-Schnittstelle hat. Während der DHT11 blau und der DHT22 weiß sind, kommt der DHT20 mit einem schwarzen Gehäuse auf einem kleinen Breakout-Board, das sowohl mehr mechanische Stabilität als auch eine gut lesbare Beschriftung bietet. Tatsächlich: die vier Pins sind mit +, -, SCL und SDA beschriftet. Und damit, abweichend von der tatsächlichen Pin-Belegung des eigentlichen Sensors, in der üblichen Reihenfolge.
Gemäß Datenblatt hat die Versorgungsspannung eine Spanne von 2,2 bis 5,5 Volt, also sowohl für Raspberry Pi und ESPs als auch für AVR Mikrocontroller geeignet.
Pinbelegung des Breakout-Boards
Als Nächstes schließe ich den DHT20 an einen Mikrocontroller ATmega 328 an und prüfe die I2C-Adresse mit dem Sketch I2C-Scanner. Wie im Datenblatt beschrieben lautet die Adresse 0x38. Das werden wir später auch noch sehen, wenn ich den Logic Analyzer parallel zum I2C-Bus schalte.
Programmcode
Zu meiner großen Freude gibt es bereits zwei Programm-Bibliotheken. Ich teste beide und beginne mit der vom Januar 2022, die nach Aussage des Entwicklers Rob Tillaart zwar noch verbesserungswürdig ist, aber für unsere Zwecke brauchbar ist und uns die komplizierte Umrechnung der gesendeten Bytes in die Werte der relativen Luftfeuchtigkeit und der Temperatur abnimmt.
Und wie so oft werden mit der Installation der Bibliothek auch Beispiele gespeichert, die man unter /Datei/Beispiele/DHT20 findet.
Das oberste Beispiel probiere ich aus, modifiziere den Sketch nur hinsichtlich der zeitlichen Abstände zwischen den Messungen und verzichte auf die Ausgabe eines Zeitstempels:
//
// FILE: DHT20.ino
// AUTHOR: Rob Tillaart
// PURPOSE: Demo for DHT20 I2C humidity & temperature sensor
//
DHT20 DHT;
void setup()
{
DHT.begin();
Wire.setClock(400000);
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("DHT20 LIBRARY VERSION: ");
Serial.println(DHT20_LIB_VERSION);
Serial.println();
delay(2000);
Serial.println("Type,\tStatus,\tHumidity (%),\tTemperature (C)");
}
void loop()
{
if (millis() - DHT.lastRead() >= 1000)
{
// READ DATA
uint32_t start = micros();
int status = DHT.read();
uint32_t stop = micros();
switch (status)
{
case DHT20_OK:
Serial.print("OK,\t");
break;
case DHT20_ERROR_CHECKSUM:
Serial.print("Checksum error,\t");
break;
case DHT20_ERROR_CONNECT:
Serial.print("Connect error,\t");
break;
case DHT20_MISSING_BYTES:
Serial.print("Missing bytes,\t");
break;
default:
Serial.print("Unknown error,\t");
break;
}
// DISPLAY DATA, sensor has only one decimal.
Serial.print("DHT20, \t");
Serial.print(DHT.getHumidity(), 1);
Serial.print(",\t");
Serial.print(DHT.getTemperature(), 1);
Serial.println("\t");
// Serial.print(stop - start);
// Serial.print("\n");
delay(5000);
}
}
// -- END OF FILE –
Wie gesagt, die eigentliche Leistung steckt in den Programm-Bibliotheken DHT20.cpp und DHT20.h. Hier werden die Bibliothek für den I2C-Bus Wire.h inkludiert, die Initialisierungsbytes an den DHT20 gesendet und der Datenempfang und die Umrechnungen für die Funktionen DHT.getHumidity() und DHT.getTemperature() festgelegt.
Auch wenn ich in den Bibliotheken Dinge wie die I2C-Adresse und die Namen der Register wiederfinde, schaue ich mir das Ganze noch einmal mit dem Logic Analyzer an, den ich im Februar in einem zweiteiligen Blog (Teil 1, Teil 2) beschrieben hatte. Der gesamte Messvorgang vollzieht sich in zwei Abfolgen aus mehreren Bytes. Zunächst erfolgt die Anforderung durch den Mikrocontroller.
Wie im Datenblatt beschrieben werden vier Bytes gesendet: „Schreiben an Adresse 0x38“, „Aufforderung zum Messen 0xAC“ mit den Parametern 0x33 und 0x00.
Hier das Bild aus dem Datenblatt:
Dann erfolgt die Aufforderung zum Lesen der gemessenen Daten. Zur Erinnerung: die I2C-Adresse besteht aus 7 Bit, hier 0x38 = 0b0111000. Wenn das achte Bit 0 ist, soll der Sensor „zuhören“ wie im Bild oben, wenn das achte Bild 1 ist, soll der Sensor Daten senden wie im folgenden Bild:
Die folgenden sechs Bytes enthalten die Daten für Luftfeuchtigkeit und Temperatur, das letzte eine Checksumme (CRC check data). Hier das Bild aus dem Datenblatt:
Nun möchte ich noch einmal die verwendete Spannung thematisieren: Das Datenblatt hatte ja als Betriebsspannung zwischen 2,2 V und 5,5 V genannt. Die folgende Tabelle schränkt die Nutzung jedoch dahingehend ein, dass die Logikspannung nur minimal von der Betriebsspannung abweichen soll:
Das kann ich nicht bestätigen. Bei meinen Versuchen am Mikrocontroller mit ATmega328 habe ich keine signifikanten Abweichungen bei den Messwerten gesehen. Auf dem folgenden Bild hatte ich jeweils nach vier bis fünf Messungen die VCC zwischen 3,3V und 5V getauscht.
Meine Idee, die Messwerte von DHT11, DHT22 und DHT20 in einem Sketch zu vergleichen, habe ich wegen der überwiegend gleichen Nomenklatur bei den Bibliotheken nicht realisieren können.
Stattdessen habe ich einen zweiten Micro Controller mit dem DHT22 parallel betrieben und die Werte verglichen, links im Bild der DHT22, rechts der DHT20:
Es gibt kleine Abweichungen innerhalb der Toleranz. Welcher Sensor der genauere ist, kann ich leider nicht feststellen.
Schließlich habe ich die zweite Programm-Bibliothek von DF-Robot ausprobiert. Nicht sonderlich überraschend ist die Übereinstimmung der gemessenen und dann berechneten Werte. In der oberen Hälfte die Ergebnisse mit der Bibliothek von Rob Tillaart, in der unteren Hälfte mit der von DFRobot.
Auch hier schaue ich mir die Signale mit dem Logic Analyzer an. Einzige Unterschiede: Die Daten werden zweimal pro Zyklus ausgelesen (jeweils für Temperatur und Luftfeuchtigkeit) und es werden nur sechs Daten-Bytes gelesen. Offensichtlich wird auf die Abfrage der Checksumme verzichtet.
Beide Programm-Bibliotheken scheinen für den Zweck geeignet, beide können noch verbessert werden. In der Bibliothek von Rob Tillaart habe ich eine Programmzeile für ESP8266 und ESP32 gelesen, bei der von DFRobot nicht. Deshalb empfehle ich ESP-Nutzern die erstgenannte Bibliothek.
Zum Schluss noch ein Vergleich der Kennwerte aus den Datenblättern:
Sensor |
DHT 11 |
DHT 20 |
DHT 22 AM2302 |
Temperaturbereich |
0 bis 50°C |
-40 bis 80°C |
-40 bis 80°C |
Genauigkeit Temperatur |
+/- 2°C |
0.5℃ |
+/- 0,5°C |
Bereich rel. Luftfeuchtigkeit RH |
20 bis 90% RH |
0 bis 100% RH |
0 bis 100% RH |
Genauigkeit RH |
+/- 5% RH |
+/- 3% |
+/- 2% RH |
Wir haben in der Vergangenheit viele Anwendungsbeispiele für Temperatur- und Luftfeuchtigkeits-Sensoren gezeigt. Mit dem DHT20 gibt es nun einen weiteren gut geeigneten Sensor mit der bewährten I2C-Schnittstelle. Am Ende dürfte der Preis die Kaufentscheidung beeinflussen.
11 Kommentare
Grille
Hallo
Da ist eine Inkontinenz äää Inkonsistenz in der Beschreibung:
Zitat Text:
<<Tatsächlich: die vier Pins sind mit +, -, SCL und SDA beschriftet. Und damit, abweichend von der tatsächlichen Pin-Belegung des eigentlichen Sensors, in der üblichen Reihenfolge.>>
und zwei Zeilen darunter ist eine <>, die von der Reihenfolge +, SDA, GND, SCL schreibt, darunter wieder ein Bild vom BrakoOutBoard (“BOB”) das der Pinreihenfolge m Text entspricht. Das ist verwirrend.
Ich vermute, dass in der Tabelle die Belegung des DHT20 selbst aufgeführt ist. Diese Belegung ist aber für den Endnutzer des BOB nicht von Belang, weil am BOB ausgekreuzt. Das sollte man in der Tabelle eindeutiger kennzeichnen. Etwa statt “AHT21B” den “Pinbelegung des DHT20-Chips” anführen.
Gruß
GriLLe
Andreas Wolter
@Mike: leider ist der Vorteil des Sensors mit I2C Schnittstelle in diesem Fall ein Nachteil. Dieser Sensor funktioniert nur über diese Schnittstelle. Da die Sensoren die gleiche Adresse nutzen, wird es etwas schwierig ohne Multiplexer.
Eine weitere Möglichkeit wäre ein Software I2C:
https://wiki.seeedstudio.com/Arduino_Software_I2C_user_guide/
Grüße,
Andreas Wolter
AZ-Delivery Blog
Mike
Hallo ich habe auch das Problem dass ich einige DHT20 Sensoren an einem ESP32 anschließen muss und ich gerne auf einem Multiplexer verzichten würde. Ist es denn möglich den DHT20, ganz normal wie früher :D den DHT11 /DHT22, mit nur einem GPIO Pin anzuschließen. Und auf die I2C Schnittstelle zu verzichten?
Andreas Wolter
@Ulrich Engel: Vielleicht gibt es die Möglichkeit, das Calliope Board mit der Arduino IDE zu programmieren.
https://forum.calliope.cc/t/calliope-mini-rev2-unter-arduino-ide-programmieren/2219/7
Grüße,
Andreas Wolter
AZ-Delivery Blog
Ulrich Engel
Hallo Herr Wolter,
mit dem ESP oder Arduino wäre es keine Problem, da würde ich die IDE verwenden. Zig-mal schon gemacht.
Aber hier geht es um einer Anweendung für das Calliope-Board. Da verwendet man als Editor nicht die IDE, sondern einen Editor namens makecode von Microsoft. Ähnlich scratch.
Und da benötigt man eben ab und zu Erweiterungen mit “Bausteinen” z.B. für den DHT20. Profis können sich diese Erweiterungen selber bauen. Ich bin aber Neuling im Thema und kann es nicht. Oft sind auf github welche hinterlegt zur Nutzung.
VG
Andreas Wolter
@Ulrich Engel: ich kenne mich leider mit MS MakeCode nicht aus. Ich würde daher empfehlen, vielleicht doch die Arduino IDE auszuprobieren und damit zu versuchen, den Sensor in Betrieb zu nehmen. Im Grunde auch relativ einfach. Es gibt dafür Bibliotheken, die fertige Beispiele mitbringen. Der Sensor wird über die I2C Schnitttstelle angesprochen. Das geht mit den Bibliotheken sehr einfach. Ansonsten ginge das mit den ESPs auch in MicroPython.
Grüße,
Andreas Wolter
AZ-Delivery Blog
Ulrich Engel
Hallo, ich habe einen grove DHT20 und würde diesen gerne mit meinem Calliope betreiben. Da aber die Erweiterung des DHT11 nicht passt, suche ich eine passende Erweiterung für makecode. Wer kann mir helfen? Ohne Erweiterung wird der Sensor in meiner Kiste nie zum Einsatz kommen.
VG Ulli
Andreas Wolter
@Martin W.: damit ist gemeint, dass die Reihenfolge der Sensorpins auf dem Breakout Board anders sind, als die, die aus dem Board heraugeführt wurden. Man muss also die Pinbelegung des Breakout-Moduls beachten, statt der Reihenfolge im Datenblat für den Sensor, der auf das Modul gelötet wurde.
Grüße,
Andreas Wolter
AZ-Delivery Blog
Martin W.
Danke für die tolle Beschreibung dieses Sensors und der Extraktion der Daten. Anfängerfrage: Wie erwähnt unterscheiden sich Datenblatt und Beschriftung hinsichtlich der Funktion der Pins. Wonach sollte ich nun gehen?
Bernd Albrecht
Richtig: Die I2C-Adresse des DHT20 lautet 0×38. Es gibt hier keine Möglichkeit, eine alternative Adresse einzustellen.
Aber es gibt den I2C-Multiplexer PCA9548A, bei dem man bis zu acht I2C-Geräte anschließen kann. Da man bei dem Multiplexer die Adresse einstellen kann, lässt sich die Gesamtzahl auf theoretische 64 I2C-Geräte erhöhen. Hier der Link zur Produktseite und einem Anwendungsbeispiel mit weiteren Informationen:
https://www.az-delivery.de/products/tca9548a-i2c-iic-multiplexer
https://www.az-delivery.de/blogs/azdelivery-blog-fur-arduino-und-raspberry-pi/halloween-kurbis-2-0
Berti
Hallo Bernd,
danke für diese sehr ausführliche Beschreibung des DHT20.
Eine Frage zur Adressierung: Es scheint so, als hätte dieses Bauteil fix die Adresse 0×38.
Wenn ich aber mehrere Teilnehmer im I2C Bus habe, gibt es eine Möglichkeit die Adresse individuell anzupassen?
Danke und viele Grüße,
Berti