- Genauigkeit
- Übertragungs-Protokkoll
Die Genauigkeit der Messwerte sind in der folgenden Tabelle zusammengefasst:
Auflösung | Genauigkeit | Reproduzierbar | |
Temperatur | 0,01 °C | 0,5 °C | 0,1 °C |
Luftfeuchtigkeit | 0,024 % | 0,024 % | 0,024 % |
Die Tabelle zeigt: Es ist sinnvoll, die Messwerte mit einer einzigen Nachkommastelle anzugeben.
Die Versorgungsspannung liegt zwischen 2,2 V und 5,5 V; wir können das Modul also über den 3,3V-Pin betreiben.
Die Stromstärken sind recht gering: Im Ruhezustand ist sie unter 1 uA, bei einem Messvorgang unter 1 mA. Da der Messvorgang weniger als 1 ms dauert (s. u.), ist der "Stromverbrauch" sehr niedrig.
Die Kommunikation zwischen dem DHT20-Modul und dem Mikrocontroller erfolgt über eine I2C-Schnittstelle. Externe Pull-Up-Widerstände sind nicht nötig. Die maximale Taktfrequenz beim DHT20-Baustein ist 400 000 Hz. Das ist identisch mit der Standardfrequenz, mit der die Micropython-Software bei Benutzung des Hardware-I2C arbeitet (vgl. Abb. 2); deswegen kann bei der Instanziierung des i2c-Objekts auf die Angabe der Frequenz verzichtet werden.
Die Instanziierung habe ich folgendermaßen vorgenommen (SCL -> Pin 25, SDA -> Pin 26):
Code: Alles auswählen
from machine import Pin, I2C
i2c = I2C(1, scl=Pin(25), sda=Pin(26))
Anschließend wird mit der Funktion trigger_measurement eine Messung ausgelöst; nach einer Wartezeit von 80 ms werden die Werte für die Temperatur t und die Luftfeuchtigkeit h vom DHT20 mit der Funktion read_measurements ausgelesen. Auch hier wird ggf. ein zweiter Leseversuch vorgenommen. Der Rückgabewert wird in der Vatiablen buffer gespeichert; er besteht aus einem Bytestring von 7 Bytes.
Die Bedeutung der einzelnen Bytes von buffer ergibt sich aus der folgenden Tabelle von S. 11 des Datasheets (Abb. 3):
Byte 0: Status-Information; ist Bit 7 = 1, dann liegt kein lesbarer Messwert vor; das Programm wird abgebrochen.
Bytes 1, 2 und das höherwertige Halbbyte von Byte 3 geben die Luftfeuchtigkeit an.
Das niederwertige Halbbyte von Byte 3 und die Bytes 4 und 5 geben die Temperatur an.
Das letzte Byte 6 dient zur Durchführung eines CRC-Checks; auf diesen verzichten wir hier.
Durch geschickte Links- bzw. Rechts-Shifts und Oder-Verknüpfungen erhalten wir die Rohwerte raw_h und raw_t; diese können mit der auf derselben Seite angegebenen Formeln
t = raw_t / 2**20 * 200 - 50
h = raw_h / 2**20 * 100
in die Werte mit den üblichen Einheiten % bzw. °C umgerechnet werden.
Hier nun der Quellcode für die Funktion get_t_h:
Code: Alles auswählen
def get_t_h():
# print('warten...')
sleep_ms(100)
if not is_ready():
# print('Falscher Status! Initialisieren...')
initialize()
sleep_ms(100)
if not is_ready():
print('Falscher Status! Abbruch...')
exit()
else:
print('Initialisieren erfolgreich!')
# print('messen...')
sleep_ms(20) # ???????????????????????????????????????????????????????????????????????????????????????????
trigger_measurements() # AC-Command, vgl. Abschnitt 7.4.2 vom Datasheet
sleep_ms(80)
buffer = read_measurements()
if buffer[0] >= 128: # Status-Bit 7 ist gleich 1 => Lesen der Messwerte noch nicht abgeschlossen
print('Lesen der Messwerte noch nicht abgeschlossen => warten...')
sleep_ms(80)
buffer = read_measurements() # neuer Versuch...
if buffer[0] >= 128:
print('Keine Messwerte lesbar => Abbruch')
exit()
raw_t = (buffer[3] & 0x0F) << 16 | buffer[4] << 8 | buffer[5]
# das obere Halbbyte von buffer[3] löschen;
# die Bytes dann um 16, bzw. 8, bzw. 0 Bits nach links verschieben;
# die Ergebnisse mit ODER zusammenfügen;
# vgl. Abschnitt 7.4.5 vom Datasheet
raw_h = buffer[1] << 12 | buffer[2] << 4 | buffer[3] >> 4
# die ersten beiden Bytes um 12 bzw. 4 Bits nach links verschieben,
# das dritte um 4 Bits nach rechts;
# die Ergebnisse mit ODER zusammenfügen;
# vgl. Abschnitt 7.4.5 vom Datasheet
t = raw_t / 2**20 * 200 - 50 # vgl. Formeln in Abschnitt 8 vom Datasheet
h = raw_h / 2**20 * 100
return t, h
Code: Alles auswählen
def is_ready() -> bool: # vgl. Abschnitt 7.4.1 vom Datasheet
i2c.writeto(address, b'\x71')
return i2c.readfrom(address, 1)[0] & 0x18 == 0x18
Die Funktion initialize hat den Quellcode:
Code: Alles auswählen
def initialize():
buffer = b'\x00\x00'
i2c.writeto_mem(address, 0x1B, buffer)
i2c.writeto_mem(address, 0x1C, buffer)
i2c.writeto_mem(address, 0x1E, buffer)
Code: Alles auswählen
def trigger_measurements():
i2c.writeto_mem(address, 0xAC, b'\x33\x00')
Code: Alles auswählen
def read_measurements():
buffer = i2c.readfrom(address, 7)
return buffer
Code: Alles auswählen
while True:
t, h = get_t_h()
print('t =', t, '°C h =', h, '%')
.