Den Sensor AHT20 als Thermometer und Hygrometer (Luftfeuchtigkeit) nutzen und über den I2C-Bus auslesen


Genaue Temperatur-Messung mittels Sensoren ist gar nicht so einfach, wie man denkt.

Da gibt es zum einen die Kandidaten der "alten Garde", teils noch mit analogem Auslesewert: Allzu sehr würde ich hier nicht auf ein genaues Ergebnis hoffen. Natürlich funktionieren die Sensoren auf eins, zwei Grad Celsius genau, aber so richtig genau? Ich weiß nicht.

Da habe ich mich bisher eher auf den Sensor BMP280 von Bosch Sensortec verlassen:

Erfahrungen mit dem BMP280


Allerdings ist mir jetzt doch aufgefallen, dass die Werte des BMP280 immer zu hoch waren, so 1 bis 3 Grad zu hoch. Woran das liegen könnte, war mir bis vor Kurzem schleierhaft, aber dann habe ich das Kleingedruckte auf Seite 8 des Datenblattes gelesen:
3 Temperature measured by the internal temperature sensor. This temperature value depends on the PCB temperature, sensor element self-heating and ambient temperature and is typically above ambient temperature.
was sich übersetzt folgendermaßen liest:
Vom internen Temperatursensor gemessene Temperatur. Dieser Temperaturwert hängt von der Leiterplattentemperatur, der Eigenerwärmung des Sensorelements und der Umgebungstemperatur ab und liegt typischerweise über der Umgebungstemperatur.
Aha! Die Ursache ist also, dass der Sensor für eine genauere Messung ein wenig aufgeheizt wird. Und natürlich braucht der Luftdrucksensor als Kompensationsfaktor die Temperatur, die in seiner unmittelbaren Umgebung herrscht, also in dem kleinen silbernen und aufgeheizten Kästchen. Damit wird dann der genaue Luftdruck berechnet.

Was da vom BMP280 ausgegeben wird, ist also gar nicht die "Ambient Temperature", also nicht die Umgebungstemperatur, sondern die Temperatur auf der Platine bzw. im Sensor ("PCB-Temperature"). Und die ist wegen des Heizens natürlich höher, eben diese 1 bis 3 Grad.

Der Sensor ist also auf einen möglichst genauen Luftdruck ausgelegt. Die Umgebungstemperatur, gleich Zimmertemperatur bzw. Außentemperatur ist also niedriger. Leider gibt es hier keine fertigen Kompensationsformeln. Man müsste da mal eine Messreihe mit einem die Umgebungstemperatur genau messenden Thermometer und dem BMP280 machen und die Temperaturen miteinander vergleichen, um herauszufinden, ob der Unterschied immer gleich ist, es einen linearen oder vielleicht sogar einen nichtlinearen Unterschied gibt.

Und natürlich heizt sich der BMP280 umso mehr auf, desto öfter man mit ihm schnell hinteneinander misst.

BMP280 und AHT20 auf einem Board


Der Sache wollte ich mit einer Vergleichsmessung auf den Grund gehen. Und da bin ich bei AliExpress über ein Board gestoßen, das neben dem BMP280 noch einen zweiten Temperatursensor verlötet hat: einen AHT20. Beide Sensoren auf einem Board ist natürlich toll, denn dann ist sichergestellt, dass beide dieselbe Temperatur messen.

Auf dem Foto rechts sieht man dieses Kombi-Board. Das obere der silbernen Kästchen ist der AHT20 (mit dem großen, länglichen Loch) und darunter befindet der BMP280 mit einem kleinen Loch.

Hier gleich mal ein Hinweis: Bei mir war über den AHT ein weißes Vlies geklebt, das ich abgezogen hatte, weil ich dachte, es soll das Innere nur für die PCB-Reinigung schützen, so wie den Buzzern, auf denen ein Aufkleber "Remove seal after washing" klebt. Dieses Vlies sollte man nicht entfernen. Er ist eine luftdurchlässige Membran und ist dafür da, dass die Messwerte nicht so stark schwanken und sich die Lebensdauer des Sensors erhöht. Der Sensor wird natürlich auch ohne Vlies funktionieren und nicht gleich explodieren, aber besser ist, man lässt es drauf, wenn eins draufklebt.

Den BMP280 habe ich hier mit all seinen technischen Daten schon ausführlich beschrieben. Bei Interesse bitte dort nachlesen.

Der AHT20 Sensor

Hier ein kurzer Steckbrief zum AHT20 Sensor zur Übersicht:

Technische Daten:
Auflösung:
Genauigkeit:
Der AHT20 ist mit einem neu entwickelten ASIC-Chip, einem verbesserten kapazitiven MEMS-Halbleiter-Feuchtigkeitssensorelement und einem standardmäßigen On-Chip-Temperatursensorelement ausgestattet. Er kann also Temperatur als auch Luftfeuchtigkeit messen.

Den AHT20 über eine Library ansprechen

Am einfachsten kann man den AHT20 über eine fertige Library ansprechen. Adafruit macht in Libraries eigentlich immer einen guten Job und bietet eine passende Library für viele Plattformen an.

Die passende Zeile für die platformio.ini lautet:
lib_deps = adafruit/Adafruit AHTX0 @ ^2.0.5
Viel Code benötigt man dann auch nicht, um Temperatur und Luftfeuchtigkeit abzufragen:
#include <Wire.h> #include <Adafruit_SH110X.h> Adafruit_AHTX0 aht; ... void testAdaAHT20() { if (aht.begin()) { Serial.println("Found AHT20"); } else { Serial.println("Didn't find AHT20"); } sensors_event_t humidity, temp; aht.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data Serial.println("AHT20 Demo"); Serial.print("Temperature: ");Serial.print(temp.temperature);Serial.println(" degrees C"); Serial.print("Humidity: ");Serial.print(humidity.relative_humidity);Serial.println(" RH %"); }
Oder man fragt direkt auf dem I2C-Bus den Sensor ab:

Den AHT20 direkt über I2C ansprechen

Im Datenblatt steht eigentlich alles beschrieben, was man wissen muss, um eine Messung anzustoßen und dem AHT20 seine Messwerte über I2C zu entlocken. Da ist die Vorgehensweise eigentlich auch ganz gut erklärt:

  1. Vielleicht zuerst einmal einen Soft-Reset durchführen: i2cWrite(addr, 0b10111010);
  2. min. 20 ms warten
  3. Status-Byte holen: i2cWrite(addr, 0xbe, 0x08, 0x00);
  4. min. 10 ms warten
  5. solange weiter warten, bis das Busy-Flag gelöscht ist: höchstwertiges Bit (Bit 7), also: Statusbyte BINARY_AND 0b10000000 muss ungleich 0 sein
  6. checken, ob das Calibrated-Flag gesetzt ist: Bit 3, also: Statusbyte BINARY_AND 0b00001000 muss gleich 0 sein
  7. Messung anstoßen: i2cWrite(addr, 0xac, 0x33, 0x00);
  8. Erstes Byte ist Statusbyte
  9. solange weiter warten, bis das Busy-Flag gelöscht ist: höchstwertiges Bit (Bit 7), also: Statusbyte BINARY_AND 0b10000000 muss ungleich 0 sein
  10. aus den nächsten 5 Bytes Temperatur und Luftfeuchtigkeit berechnen

Allzu klar ist im Datenblatt allerdings nicht herausgestellt, wie man die Bits der 5 Bytes nun zur Berechnung heranziehen muss:

Aus den Formeln
Luftfeuchtigkeit: S RH = -------- * 100 % 2^20 Temperatur: S T = -------- * 200 -50 2^20
lässt sich allerdings erraten, dass der Messwert für Luftfeuchtigkeit bzw. Temperatur jeweils 20 Bit lang ist. 5 Bytes Daten mal 8 sind 40 Datenbits, die werden in der Mitte geteilt und geben so jeweils 20 Bits für beide Messwerte:
SSSSSSSS HHHHHHHH HHHHHHHH HHHHTTTT TTTTTTTT TTTTTTTT CCCCCCCC
wäre vielleicht eine bessere Darstellung gewesen, als nur überall "x" reinzuschreiben. Dabei bedeutet:

Testaufbau und Temperaturvergleich


Für meine Messungen benutze ich das Elecrow LoRaWAN LR1262 Development-Board mit Raspi-Pico 2040, weil ich hier gerade daran arbeite, Sensordaten über LoRa zu übertragen und da schon den Code für den BMP280 drin habe. Also habe ich da einfach weiter gemacht. Im Grunde genommen funktioniert das natürlich auch mit jedem anderen Board, das I2C über 3.3 V kann (der BMP280 mag keine 5 Volt).

Schauen wir uns einmal die Messwerte im Vergleich an: normales Digital-Thermometer: 22.5 °C AHT20 über I2C: 23.34°C (53.41 %RH) BMP über I2C: 24.34° Der AHT20 liegt also 0.84 °C höher als das Küchenthermometer. Und dem vertraue ich eigentlich. Mein genauestens Thermometer wird mein Fieberthermometer sein und das Küchenthermometer zeigt bei meiner Körpertemperatur das gleiche an wie das Fieberthermometer, ± 0.1 °C.

Und der BMP280 liegt da noch einmal 1 °C drüber, insgesamt also fast 2 °C.

Der AHT20 sollte sich nicht aufheizen, um den Nebenmesswert (hier Luftfeuchtigkeit) zu messen, wie es der BMP280 tut. Das entnehme ich folgendem Hinweis im Datenblatt:
Datasheet AHT20 by ASAIR, V1.1
Moreover, when the measurement frequency is too high, the temperature of the sensor itself will rise, which will affect the measurement accuracy. In order to make its temperature rise below 0.1 , the activation time of AHT20 should not exceed 10% of the measurement time - it is recommended to measure data every 2 seconds.
Übersetzt: "Darüber hinaus steigt bei einer zu hohen Messfrequenz die Temperatur des Sensors selbst, was die Messgenauigkeit beeinträchtigt. Um den Temperaturanstieg unter 0,1 °C zu halten, sollte die Aktivierungszeit des AHT20 10 % der Messzeit nicht überschreiten. Es wird empfohlen, nicht öfters als alle 2 Sekunden Daten zu messen."

Ich habe den AHT20 nur einmal gemessen. Und so nah ist der "aufgeheizte" BMP280 auch nicht am AHT20, dass der diesen wesentlich beeinflussen sollte.

Nichtsdestotrotz habe ich noch einmal mit "kaltem" (also frisch eingeschaltetem) Board gemessen und kam da auch auf 0.5 °C, die der AHT20 über dem Küchenthermometer lag. Einigen wir uns darauf, dass der AHT20 ein halbes Grad zu viel anzeigt und der BMP280 ungefähr zwei Grad zu viel.

In Sachen Luftfeuchtigkeit liegt der AHT20 ungefähr 0.2 bis 0.3 % RH über dem, was die anderen Hygrometer in meiner Wohnung anzeigen, der Wert stimmt also.

Fazit zum Kombisensor

Zwei Sensoren auf einem Board, wovon zwei die Temperatur messen, ist kein Unsinn, wenn man weiß, dass sich der BMP280 zur Luftdruckmessung aufheizt und die Platinentemperatur und nicht die Umgebungstemperatur anzeigt.

In Sachen Temperatur sollte man also mit dem AHT 20 messen und den BMP280 nur für den Luftdruck benutzen. Um den BMP280-Luftdruck zu kalibrieren, benutzen wir dann natürlich auch die BMP280-Temperatur in unserer Rechnung.

Und die zusätzliche Info über die Luftfeuchtigkeit ist sicher auch ein gern genommenes Extra.

Da die Kombi-Boards nicht so teuer sind (unter einem Euro das Stück direkt aus China, wenn man mehrere kauft) ist das mein neuer Favorit für die Messung der Umgebungstemperatur.

Video

Ich habe ein kleines Demo-Video über den Kombi-Sensor auf meinem Elecrow LoRa-Dev.-Board gemacht, dass ich euch nicht vorenthalten will: