MicroPython Driver for AHT10 / AHT15

AHT10, AHT15 Driver Code for micro:bit

Download as zip file

'''
AHT10, AHT15 (humidity and temperature sensors)
MicroPython driver for micro:bit

AUTHOR: fredscave.com
DATE  : 2024/11
VERSION : 1.00
'''

from microbit import i2c, sleep
from micropython import const

ADDR = const(0x38)
CMD_INIT = [0xE1, 0x08, 0x00]
CMD_MEASURE = [0xAC, 0x33, 0x00]
CMD_RESET = const(0xBA)

class AHT1X():
    def __init__(self, addr=ADDR):
        self.addr = addr
        self.Initialise()

    def Initialise(self):
        i2c.write(self.addr, bytearray(CMD_INIT))        

    def Read(self):
        i2c.write(self.addr, bytearray(CMD_MEASURE))
        #sleep(50)
        busy = True
        while busy:
            buf = i2c.read(self.addr, 6)
            sleep(10)
            busy = buf[0] & 0b10000000
        measurements = AHT1X.convert(buf)
        return measurements

    def T(self):
        measurements = self.Read()
        return round(measurements[1], 1)

    def RH(self):
        measurements = self.Read()
        return int(measurements[0] + 0.5)

    def Reset(self):
        i2c.write(self.addr, bytes([CMD_RESET]))
        sleep(20)

    @staticmethod
    def convert(buf):
        RawRH = ((buf[1] << 16) |( buf[2] << 8) | buf[3]) >> 4
        RH = RawRH * 100 / 0x100000
        RawT = ((buf[3] & 0x0F) << 16) | (buf[4] << 8) | buf[5]
        T = ((RawT * 200) / 0x100000) - 50
        return (RH, T)

          

Examples

The AHT10 (and AHT15) product datasheet makes the extraordinary claim that only a single AHT10 can be connected to the I2C bus and no other I2C devices can be connected. This following example program is designed to test this assertion.

Example 1

Three different humidity and temperature sensors, AHT10, AHT15 and SHT40, will be used. Each sensor will be read in sequence for humidity and temperature each 2 seconds for 10 seconds i.e. a total of 5 readings from each sensor.

Each 2 second reading will be output. Then the average humidity and temperature readings from each sensor will be calculated and output.

Since the AHT10 and AHT15 sensors have the same I2C address they will be attached to channels on a TCA9548A I2C multiplexer. The AHT10 will use channel 7 and the AHT15 will use channel 2 of the multiplexer.

The following driver module files need to be copied to the micro:bit's filesystem:

Connections
  • Connect TCA9548A, AHT10, AHT15 and SHT40 power and ground pins to the micro:bit's 3.3V and GND pins respectively.
  • TCA9548A: Connect SCL and SDA to micro:bit's pin19 and pin20 respectively.
  • SHT40: Connect SCL and SDA to micro:bit's pin19 and pin20 respectively.
  • AHT10: Connect SCL and SDA pins to TCA9548A's SC7 and SD7 pins respectively.
  • AHT15: Connect SCL and SDA pins to TCA9548A's SC2 and SD2 pins respectively.

Example 1
# Simultaneously test AHT10, AHT15
# and SHT40 sensors.
# All three sensors measure humidity
# and temperature.

# AHT10 and AHT15 sensors have the
# same I2C address so it is necessary
# to use a TCA9548A multiplexer.

from fc_aht1x import *
from fc_tca9548a import *
from fc_sht4x import *
from microbit import sleep

# Instantiate multiplexer object.
multi = TCA9548A()

# Instantiate SHT40 sensor object.
sht40 = SHT4X()

# Instantiate AHT10 sensor object.
# Attached to multiplexer channel 7
multi.CloseAllChannels()
multi.OpenChannels(7)
aht10 = AHT1X()

# Instantiate AHT15 sensor object.
# Attached to multiplexer channel 2
multi.CloseAllChannels()
multi.OpenChannels(2)
aht15 = AHT1X()

sum_aht10_rh = sum_aht15_rh = sum_sht40_rh = 0
sum_aht10_t = sum_aht15_t = sum_sht40_t = 0
# Read the sensors
for x in range(5):
    # AHT10 sensor
    multi.CloseAllChannels()
    multi.OpenChannels(7)
    data = aht10.Read()
    sum_aht10_t += data[1]
    sum_aht10_rh += data[0]
    print('AHT10 - RH(%):', data[0], 'T(C):', data[1])
    
    # AHT15 sensor
    multi.CloseAllChannels()
    multi.OpenChannels(2)
    data = aht15.Read()
    sum_aht15_t += data[1]
    sum_aht15_rh += data[0]    
    print('AHT15 - RH(%):', data[0], 'T(C):', data[1])
    
    # SHT40 sensor
    data = sht40.Read()
    sum_sht40_t += data[0]
    sum_sht40_rh += data[2]    
    print('SHT40 - RH(%):', data[2], 'T(C):', data[0])
    sleep(2000)
    
# Calculate averages
avg_aht10_t = sum_aht10_t / 5
avg_aht10_rh = sum_aht10_rh / 5
avg_aht15_t = sum_aht15_t / 5
avg_aht15_rh = sum_aht15_rh / 5
avg_sht40_t = sum_sht40_t / 5
avg_sht40_rh = sum_sht40_rh / 5
print('Averages:')
print('AHT10 - RH(%):', avg_aht10_rh, 'T(C):', avg_aht10_t)
print('AHT15 - RH(%):', avg_aht15_rh, 'T(C):', avg_aht15_t)
print('SHT40 - RH(%):', avg_sht40_rh, 'T(C):', avg_sht40_t)

Typical Output:
AHT10 - RH(%): 46.51852 T(C): 19.92226
AHT15 - RH(%): 44.86694 T(C): 19.71779
SHT40 - RH(%): 46.55398 T(C): 20.82361
AHT10 - RH(%): 46.48161 T(C): 19.91501
AHT15 - RH(%): 44.88029 T(C): 19.7361
SHT40 - RH(%): 46.45289 T(C): 20.82361
AHT10 - RH(%): 46.47999 T(C): 19.92226
AHT15 - RH(%): 44.9152 T(C): 19.71588
SHT40 - RH(%): 46.41856 T(C): 20.82895
AHT10 - RH(%): 46.48743 T(C): 19.9213
AHT15 - RH(%): 44.86589 T(C): 19.71912
SHT40 - RH(%): 46.50439 T(C): 20.81293
AHT10 - RH(%): 46.48695 T(C): 19.92321
AHT15 - RH(%): 44.78722 T(C): 19.71321
SHT40 - RH(%): 46.52346 T(C): 20.82628
Averages:
AHT10 - RH(%): 46.4909 T(C): 19.92081
AHT15 - RH(%): 44.86311 T(C): 19.72042
SHT40 - RH(%): 46.49065 T(C): 20.82308
          
Example 2

All three sensors (AHT10, AHT15, SHT40) behaved perfectly. However it is mention on some online forums that the AHT10 over time will cause the I2C bus to freeze. So this was tested with the next example.

The first example code was slightly modified to take readings from the three sensors sequentially every 2 seconds for one hour i.e. 1,800 readings were taken by each sensor. The code modifications made were:

  • The range in the for loop was changed from 5 to 1800.
  • The three print statements inside the loop were commented out.
  • The average calculations were changed to reflect that 1,800 samples per sensor were taken.

Typical Output:
Averages:
AHT10 - RH(%): 39.98535 T(C): 24.86712
AHT15 - RH(%): 38.88862 T(C): 23.58581
SHT40 - RH(%): 39.72151 T(C): 25.64433
          

As it can clearly be seen, the microbit and its I2C bus continued to function and did not freeze. All three sensors showed close results for relative humidity which is the primary function of these sensors.

The SHT40, which would be regarded as the best sensor of the three, displayed a slightly higher temperature reading.