AHT10 Humidity and Temperature Sensor


Author Message
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 3321
Posted: 01:04am 05 Dec 2023      

Have been comparing the AHT10 with a DHT11 and a DS3231 RTC chip sensor for a few weeks.
To ensure they are all at the same temperature they are all sealed in a jar, close together.
According to the datasheets their temperature accuracies are:-
AHT10 +/- 0.3C
DHT11 +/- 2C
DS3231 +/- 3C

However in practice the DHT11 and DS3231 are usually within 0.3 C of the AHT10
If more people get similar results it may be worth asking Peter if he can add tenths of degrees to the DEVICE HUMID command output.
The data sheet Peter was using indicated only whole degrees were available and with +/- 2C accuracy that seemed reasonable.
A different translation of the datasheet showed tenths were there but for the above reason there seemed no reason to change it at the time.

The hack below uses the DHT12 command and an extra pin to get the tenths from byte 4 of the output.
' AHT10 DHT11 DS3231 and VL53LOX .bas
' PicoMite V5.08.08b2
'Read AHT10, DS3231, and VL53LOX using System I2C and DHT11 using GPO and GP1

'=======================================================================
'AHT10

Dim Float humid, temp
Const AHaddr = &H38 ' AHT10 I2C address
I2C write AHaddr, 0, 3, 172, 51, 0  'trigger first AHT10 measurement
Pause 45               'wait for data

Sub AHT10
  I2C write AHaddr, 0, 3, 172, 51, 0  'trigger measurement for next read
  Pause 45 'wait for data
  I2C read AHaddr,1,5,dat() 'read first 5 data bytes - last one not needed.
  humid = Cint(dat(1) * 0.390625)
  temp = Cint((((dat(3) And 15) << 8) + dat(4)) * 0.48828125 - 500) / 10
End Sub

'=======================================================================
' DHT11

SetPin gp1, dout 'provides extended "wake" pulse for DHT11
Pin(GP1) = 1     'via diode to GP0 (anode to GP0, cathode to GP1)
Dim n%, a(9) : a(9) = 255  ' = "array not full" flag, BASE 0
Dim Float T, H

Sub DHT11  'get DHT11 reading with tenths of degrees
  Pulse GP1, 25  'provide an extended low "wake" pulse for DHT11
  Pause 23.9     'overlap the 1mS DHT22 "wake" pulse
  Device humid GP0, T, H  'start DHT22 command
  If T <> 1000 Then ' 1000 = checksum error or no response
    H = H*10 >> 8   ' convert data format from DHT22 to DHT11
    T = (T*10 >> 8) + (T*10 And 255) / 10 ' and add tenths of degrees
'    byte 1 = humidity, 2 = not used, 3 = temp., 4 = tenths of degrees, 5 = checksum
    a(n%) = T      ' load array to get 10 sample mean
    Inc n% : n% = n% Mod 10 ' set array index, after 9 jump back to 0
    If a(9) < 100 Then T = Int(Math(sum a())) / 10 'if array is full get mean to 1 DP
  EndIf
  Pin(GP1) = 1 ' ensure correct start for next run (optional)
End Sub

'=======================================================================
' DS3231 RTC temp

Function RTCtemp() As FLOAT
' DS3231 RTC temp. registers get updated at 64 S intervals.
 Local D%, Q%
 RTC GetReg 17, D% ' Degrees are in register 17
 RTC GetReg 18, Q% 'and 0.25C steps in register 18, using top 2 bits.
 RTCtemp = D% + Q% / 256
End Function

'=======================================================================
'VL53LOX laser distance

Dim Integer  dat(4), dst(1), dist
Const VLaddr=&H29 'VL53LOX I2C address
I2C write VLaddr,0,2,0,1          'trigger first VL53LOX measurement
Pause 75

Sub VL53LOX
  I2C write VLaddr,1,1,30
  I2C read VLaddr,0,2,dst()
  dist = (dst(0)<<8) + dst(1) - 20

  I2C write VLaddr,0,2,0,1  'trigger measurement for next read
End Sub

'=======================================================================
'Main Loop
Print "AHT10 humid      AHT10 temp      RTC temp        DHT11 temp      DHT11 humid "'    distance"

Do
  AHT10
  Pause 500
  DHT11
  Pause 500
'   VL53LOX
  Print  humid;" %",, temp;" C",, RTCtemp()" C   ", T" C    ", H" %"',, dist" mm"
  Pause 1000 ' read every 2S
Loop

Sub mm.prompt
 Print Cwd$"> ";
End Sub

End

The output to console. For the DHT11 a rolling mean starts after 10 samples to reduce jitter.
Saved 3005 bytes
A:/> RUN
AHT10 humid      AHT10 temp      RTC temp        DHT11 temp      DHT11 humid
39 %            19.9 C          19.5 C          20.3 C          48 %
39 %            19.9 C          19.5 C          19.8 C          42 %
39 %            19.9 C          19.5 C          19.7 C          48 %
39 %            19.9 C          19.5 C          19.9 C          48 %
39 %            19.9 C          19.5 C          20 C            48 %
39 %            19.9 C          19.5 C          19.7 C          48 %
39 %            19.9 C          19.5 C          20.1 C          48 %
39 %            19.9 C          19.5 C          19.9 C          48 %
39 %            19.9 C          19.5 C          20 C            48 %
39 %            19.9 C          19.5 C          19.9 C          48 %
39 %            19.9 C          19.5 C          19.8 C          48 %
39 %            19.9 C          19.5 C          19.8 C          48 %
39 %            19.9 C          19.5 C          19.8 C          48 %
39 %            19.9 C          19.5 C          19.8 C          48 %
39 %            19.9 C          19.5 C          19.8 C          48 %
39 %            19.9 C          19.5 C          19.8 C          48 %
39 %            19.9 C          19.5 C          19.8 C          48 %
39 %            19.9 C          19.5 C          19.8 C          48 %
39 %            19.9 C          19.5 C          19.8 C          48 %
A:/>

Edit
Ignore the VL53LOX bit, it was already attached to the RTC so its code was left in.

Edit 2
The discrepancy between the AHT10 and DHT11 humidity readings has gradually decreased in the time they have been sealed in the jar. I put a small silica gel capsule in with them so I could compare them at lower humidity.
The difference was 18% when they went in a few weeks ago and this afternoon is down to 6%.
.
Edited 2023-12-05 16:55 by phil99

Footnote added 2025-10-10 17:15 by phil99
Also works on a MicroMite2.
Dim Float humid, temp
Dim integer dat(4)
Const AHaddr = &H38 ' AHT10 I2C address
I2C OPEN 400,1000,PU

Print "Time",,"count","Cell V",,"Tilt"
Do
  I2C write AHaddr, 0, 3, 172, 51, 0  'trigger measurement for next read
  Pause 45 'wait for data
  I2C read AHaddr,1,5,dat() 'read first 5 data bytes - last one not needed.
  humid = Cint(dat(1) * 0.390625)
  temp = Cint((((dat(3) And 15) << 8) + dat(4)) * 0.48828125 - 500) / 10

  Print Timer-t, temp;"`C", humid;"%"
  CPU sleep 10
Loop


Footnote added 2025-10-10 17:22 by phil99
Going senile. Extracted above from a bigger program and used the wrong column headings.
The Print statements should be :-

Print "Temperature", "Humidity"
and
Print  temp;"`C", humid;"%"