How to Interface AHT20 Temp & Hum sensor

Today in this tutorial we will cover how to interface the AHT20 Temperature and Humidity sensor with STM32. AHT20 is small in size, and is relatively easy to interface compared to other temperature sensors we have interfaced before.

The Temperature resolution of the sensor is 0.01°C whereas the humidity resolution is 0.024%RH.

Connection

The sensor works with I2C hence the connection is very straightforward. Below is the image showing the connection between AHT20 and STM32F103.

The sensor is powered with 3.3V from the board itself. The SCL pin is connected to PB6 and the SDA pin is connected to PB7.



The Code

We will write the code by referring to the datasheet of the sensor.

Definition

Let’s start with some definitions that we will use in the project.

#include "math.h"

#define AHT20_ADDRESS 0x38<<1
float Temperature, Humidity;

The 7bit AHT20 device address is 0x38. This is mentioned in the datasheet of the sensor. The HAL library uses 8bit device address, that includes the 7bit address along with the Read/Write bit. This is why we need to shift the address by 1 place to the left (0x38<<1).

The variables Temperature and Humidity will be used to store the final calculated values.


Initialization

Below is the image showing the process to initialize the sensor as per the datasheet.

Below is the function to initialize the sensor.

void AHT20_Init (void)
{
	HAL_Delay(40);
	uint8_t status;
	HAL_I2C_Mem_Read(&hi2c1, AHT20_ADDRESS, 0x71, 1, &status, 1, 1000);
	if ((status>>3 & 0x01) == 0)  // if CAL = 0
	{
		uint8_t init_commands[3] = {0xBE, 0x08, 0x00};
		HAL_I2C_Master_Transmit(&hi2c1, AHT20_ADDRESS, init_commands, 3, 1000);
		HAL_Delay (10);
	}
}

As per the instructions in the datasheet,

  • We will first wait for 40ms.
  • Then Read the status register (0x71). The bit 3 (CAL) of this register indicates whether the sensor is calibrated or not.
  • If the CAL bit is 0, it means that the sensor is not calibrated and hence we need to initialize it.
  • The initialization command, 0xBE, has 2 parameters, 0x08 and 0x00. We will send these 3 bytes to the sensor.
  • At last wait for 10ms for the initialization to complete.

Reading Data

Below is the image showing the process to read the data.

We will write a separate function to read the data from the device.

void AHT20_Measure (void)
{
	uint8_t measure_command[3] = {0xAC, 0x33, 0x00};
	HAL_I2C_Master_Transmit(&hi2c1, AHT20_ADDRESS, measure_command, 3, 1000);
	HAL_Delay(80);

	uint8_t status;
	do {
		HAL_I2C_Mem_Read(&hi2c1, AHT20_ADDRESS, 0x71, 1, &status, 1, 1000);
		HAL_Delay(100);
	}
	while ((status>>7 & 0x01) == 1);

	uint8_t RxData[7];
	HAL_I2C_Master_Receive(&hi2c1, AHT20_ADDRESS, RxData, 7, 1000);

Here we will follow the steps as per the datasheet.

  • Send the “trigger measurement” command (0xAC) along with its parameters.
  • Wait for 80ms for the measurement to complete.
  • Then continuously read the status register (0x71) and check its 7th bit (BUSY). The loop will only exit if the BUSY bit is 0, indicating that the device has finished the measurement.
  • Then we will read 7 bytes of data from the slave device.

These 7 bytes of data contains 1 State Byte + 2 Humidity Bytes + 1 Humidity & Temperature Byte combined + 2 Temperature Bytes + 1 CRC Byte. This is shown in the image below.

We can ignore the State byte and the CRC Byte, therefore we only have to work with the rest 5 data bytes. In total we have 20Bits of Humidity data and 20Bits of Temperature data.

	uint32_t HUM_DATA = (RxData[1]<<16)|(RxData[2]<<8)|RxData[3];  // accumulated 24bit data
	HUM_DATA = HUM_DATA>>4;  // 20bit data
	Humidity = (float) ((HUM_DATA/pow(2,20)) * 100);

We will first combine the 2 Humidity data bytes and 1 combined byte to make a 24bit data. This 24 bit data also contains the 4bits of the temperature data, as they are part of the combined data byte. Therefore we will shift the 24bit data to the right by 4 places, so to discard the 4 least significant bits, i.e. the temperature data bits.

We now have the 20bit Humidity data so we will convert it to the %RH format by using the formula given in the datasheet of the sensor.

We will use the above formula to convert the Humidity data into the %RH. The converted value will be stored in the Humidity variable.

Similarly, We will first combine the temperature bytes to make a 24 bit temperature data.

	uint32_t TEMP_DATA = (RxData[3]<<16)|(RxData[4]<<8)|RxData[5];  // accumulated 24bit data
	TEMP_DATA = TEMP_DATA&0xFFFFF;  // first 20bit data
	Temperature = (float) (((TEMP_DATA/pow(2,20)) * 200) - 50);
}

This 24 bit data also contains the 4bits of the humidity data, as they are part of the combined data byte. Therefore we will perform an AND operation with 0xFFFFF, so to discard the 4 most significant bits, i.e. the humidity data bits.

We now have the 20bit Temperature data so we will convert it to the °C format by using the formula given in the datasheet of the sensor.

We will use the above formula to convert the Humidity data into the °C. The converted value will be stored in the Temperature variable.


The main function

Inside the main function we will initialize the AHT20 sensor. The read the data continuously in the while loop every 2 seconds.

int main()
{
  .....
  AHT20_Init();
  while (1)
  {
	  AHT20_Measure();
	  HAL_Delay(2000);
  }
}


Result

Below is the image showing the Temperature and Humidity values in the cubeIDE debugger.

You can see the current temperature and humidity values are displaying in the live expression.

Check out the Video Below




Info

You can help with the development by DONATING Below.
To download the project, click the DOWNLOAD button.

Subscribe
Notify of

0 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments