2020#include "AHT20.h"
2121#include <stdio.h>
2222#include <string.h>
23+ #include <math.h>
2324
2425/*
2526 * device address for AHT20
2930 */
3031static const uint16_t DEVICE_ADDRESS = (0x38 << 1 );
3132
33+ /*
34+ * performs soft resetting of the sensor
35+ *
36+ * Datasheet: AHT20 Product manuals
37+ * 5.5 Soft reset
38+ */
39+ static uint8_t SOFT_RESET_CMD = 0xba ;
40+
3241/*
3342 * get status command. is needed for sending to device after power on
3443 *
3544 * Datasheet: AHT20 Product manuals
3645 * 5.4 Sensor reading process, paragraph 1
3746 */
38- static uint8_t GET_STATUS = 0x71 ;
47+ static uint8_t GET_STATUS_CMD = 0x71 ;
3948
4049/*
4150 * array for calibration initialization
@@ -53,14 +62,19 @@ static uint8_t INIT_CMD[3] = {0xbe, 0x08, 0x00};
5362 */
5463static uint8_t MEASURE_CMD [3 ] = {0xac , 0x33 , 0x00 };
5564
65+ /*
66+ * calculates crc8 for given data
67+ */
68+ static uint8_t calculate_crc (uint8_t * data );
69+
5670/*
5771 * sends reads status_word for further calibration verification
5872 *
5973 * Datasheet: AHT20 Product manuals
6074 * 5.3 Send command
6175 */
6276aht20_status_t aht20_get_calibration_status (I2C_HandleTypeDef * hi2c , UART_HandleTypeDef * huart , uint8_t * status_word , uint16_t status_word_size ) {
63- if (HAL_OK != HAL_I2C_Master_Transmit (hi2c , DEVICE_ADDRESS , & GET_STATUS , (uint16_t )sizeof (GET_STATUS ), HAL_MAX_DELAY )) {
77+ if (HAL_OK != HAL_I2C_Master_Transmit (hi2c , DEVICE_ADDRESS , & GET_STATUS_CMD , (uint16_t )sizeof (GET_STATUS_CMD ), HAL_MAX_DELAY )) {
6478 return AHT20_STATUS_NOT_TRANSMITTED ;
6579 }
6680
@@ -92,7 +106,7 @@ aht20_status_t aht20_check_calibration(uint8_t status_word) {
92106 * 5.4 Sensor reading process, paragraph 1
93107 */
94108aht20_status_t aht20_calibrate (I2C_HandleTypeDef * hi2c , uint8_t status_word ) {
95- if (HAL_OK != HAL_I2C_Master_Transmit (hi2c , DEVICE_ADDRESS , INIT_CMD , 3 , HAL_MAX_DELAY )) {
109+ if (HAL_OK != HAL_I2C_Master_Transmit (hi2c , DEVICE_ADDRESS , INIT_CMD , ( uint16_t ) sizeof ( INIT_CMD ) , HAL_MAX_DELAY )) {
96110 return AHT20_STATUS_NOT_TRANSMITTED ;
97111 }
98112
@@ -106,18 +120,42 @@ aht20_status_t aht20_calibrate(I2C_HandleTypeDef *hi2c, uint8_t status_word) {
106120 * 5.4 Sensor reading process, paragraph 2
107121 */
108122aht20_status_t aht20_measure (I2C_HandleTypeDef * hi2c , uint8_t * measured_data ) {
109- if (HAL_OK != HAL_I2C_Master_Transmit (hi2c , DEVICE_ADDRESS , MEASURE_CMD , 3 , HAL_MAX_DELAY )) {
123+ uint8_t received_crc = 0 ;
124+
125+ if (HAL_OK != HAL_I2C_Master_Transmit (hi2c , DEVICE_ADDRESS , MEASURE_CMD , (uint16_t )sizeof (MEASURE_CMD ), HAL_MAX_DELAY )) {
110126 return AHT20_STATUS_NOT_TRANSMITTED ;
111127 }
112128 HAL_Delay (80 );
113129
114130 uint8_t measuring_status = 0 ;
115- HAL_I2C_Master_Receive (hi2c , DEVICE_ADDRESS , & measuring_status , 1 , HAL_MAX_DELAY );
131+ HAL_I2C_Master_Receive (hi2c , DEVICE_ADDRESS , & measuring_status , ( uint16_t ) sizeof ( measuring_status ) , HAL_MAX_DELAY );
116132
117- if (measuring_status & (1 << 7 )) {
133+ uint8_t all_data [7 ];
134+ if (measuring_status & (1 << 7 )) {
118135 return AHT20_STATUS_NOT_MEASURED ;
119- }else {
120- HAL_I2C_Master_Receive (hi2c , DEVICE_ADDRESS , measured_data , 6 , HAL_MAX_DELAY );
136+ } else {
137+ HAL_I2C_Master_Receive (hi2c , DEVICE_ADDRESS , all_data , (uint16_t )sizeof (all_data ), HAL_MAX_DELAY );
138+ }
139+
140+ // Copy 6 data bytes to measured_data
141+ for (uint8_t i = 0 ; i < 6 ; ++ i ) {
142+ measured_data [i ] = all_data [i ];
143+ }
144+ received_crc = all_data [6 ]; // CRC is the 7th byte
145+
146+ uint8_t calculated_crc = calculate_crc (measured_data );
147+ if (calculated_crc == received_crc ) {
148+ uint8_t ack = 0x06 ;
149+ if (HAL_OK != HAL_I2C_Master_Transmit (hi2c , DEVICE_ADDRESS , & ack , (uint16_t )sizeof (ack ), HAL_MAX_DELAY )) {
150+ return AHT20_STATUS_NOT_TRANSMITTED ;
151+ }
152+ } else {
153+ uint8_t nack = 0x15 ;
154+ if (HAL_OK != HAL_I2C_Master_Transmit (hi2c , DEVICE_ADDRESS , & nack , (uint16_t )sizeof (nack ), HAL_MAX_DELAY )) {
155+ return AHT20_STATUS_NOT_TRANSMITTED ;
156+ }
157+
158+ aht20_soft_reset (hi2c );
121159 }
122160
123161 return AHT20_STATUS_OK ;
@@ -138,3 +176,41 @@ void aht20_calculate_measurments(uint8_t *measured_data, float *humidity, float
138176 * temp_c = (((float )raw_temperature * 200.0 ) / 1048576.0 ) - 50.0 ;
139177 * temp_f = * temp_c * 9.0 / 5.0 + 32.0 ;
140178}
179+
180+ /*
181+ * resets the sensor without turning off the power supply
182+ *
183+ * Datasheet: AHT20 Product manuals
184+ * 5.5 Soft reset
185+ */
186+ aht20_status_t aht20_soft_reset (I2C_HandleTypeDef * hi2c ) {
187+ if (HAL_OK != HAL_I2C_Master_Transmit (hi2c , DEVICE_ADDRESS , & SOFT_RESET_CMD , (uint16_t )sizeof (SOFT_RESET_CMD ), HAL_MAX_DELAY )) {
188+ return AHT20_STATUS_NOT_TRANSMITTED ;
189+ }
190+
191+ HAL_Delay (20 );
192+ return AHT20_STATUS_OK ;
193+ }
194+
195+ /*
196+ * calculates crc8 for given data
197+ */
198+ static uint8_t calculate_crc (uint8_t * data ) {
199+ uint8_t crc = 0xFF ;
200+ uint8_t i = 0 , j = 0 ;
201+
202+ for (; i < 6 ; ++ i ) {
203+ crc ^= data [i ];
204+ for (j = 0 ; j < 8 ; ++ j ) {
205+ if (crc & 0x80 ) {
206+ crc = (crc << 1 ) ^ 0x31 ;
207+ } else {
208+ crc <<= 1 ;
209+ }
210+ }
211+ }
212+
213+ return crc ;
214+ }
215+
216+
0 commit comments