20
20
#include "AHT20.h"
21
21
#include <stdio.h>
22
22
#include <string.h>
23
+ #include <math.h>
23
24
24
25
/*
25
26
* device address for AHT20
29
30
*/
30
31
static const uint16_t DEVICE_ADDRESS = (0x38 << 1 );
31
32
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
+
32
41
/*
33
42
* get status command. is needed for sending to device after power on
34
43
*
35
44
* Datasheet: AHT20 Product manuals
36
45
* 5.4 Sensor reading process, paragraph 1
37
46
*/
38
- static uint8_t GET_STATUS = 0x71 ;
47
+ static uint8_t GET_STATUS_CMD = 0x71 ;
39
48
40
49
/*
41
50
* array for calibration initialization
@@ -53,14 +62,19 @@ static uint8_t INIT_CMD[3] = {0xbe, 0x08, 0x00};
53
62
*/
54
63
static uint8_t MEASURE_CMD [3 ] = {0xac , 0x33 , 0x00 };
55
64
65
+ /*
66
+ * calculates crc8 for given data
67
+ */
68
+ static uint8_t calculate_crc (uint8_t * data );
69
+
56
70
/*
57
71
* sends reads status_word for further calibration verification
58
72
*
59
73
* Datasheet: AHT20 Product manuals
60
74
* 5.3 Send command
61
75
*/
62
76
aht20_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 )) {
64
78
return AHT20_STATUS_NOT_TRANSMITTED ;
65
79
}
66
80
@@ -92,7 +106,7 @@ aht20_status_t aht20_check_calibration(uint8_t status_word) {
92
106
* 5.4 Sensor reading process, paragraph 1
93
107
*/
94
108
aht20_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 )) {
96
110
return AHT20_STATUS_NOT_TRANSMITTED ;
97
111
}
98
112
@@ -106,18 +120,42 @@ aht20_status_t aht20_calibrate(I2C_HandleTypeDef *hi2c, uint8_t status_word) {
106
120
* 5.4 Sensor reading process, paragraph 2
107
121
*/
108
122
aht20_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 )) {
110
126
return AHT20_STATUS_NOT_TRANSMITTED ;
111
127
}
112
128
HAL_Delay (80 );
113
129
114
130
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 );
116
132
117
- if (measuring_status & (1 << 7 )) {
133
+ uint8_t all_data [7 ];
134
+ if (measuring_status & (1 << 7 )) {
118
135
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 );
121
159
}
122
160
123
161
return AHT20_STATUS_OK ;
@@ -138,3 +176,41 @@ void aht20_calculate_measurments(uint8_t *measured_data, float *humidity, float
138
176
* temp_c = (((float )raw_temperature * 200.0 ) / 1048576.0 ) - 50.0 ;
139
177
* temp_f = * temp_c * 9.0 / 5.0 + 32.0 ;
140
178
}
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