ESP32_DHT_Node/main/aht10/aht10.c

135 lines
3.1 KiB
C

#include <stddef.h>
/* Private header */
#include "aht10.h"
#define AHT10_STATUS_CALIBRATED_MASK (1U << 3U)
#define AHT10_STATUS_BUSY_MASK (1U << 7U)
#define AHT10_ERROR_CHECK(x) \
if (x != AHT10_OK) return AHT10_FAIL
typedef struct {
uint8_t status;
uint32_t temperature;
uint32_t humidity;
} aht10_raw_t;
static aht10_ret_t aht10_software_reset(aht10_t *aht) {
/* Reset and initialize device */
uint8_t tx_data[3] = {0xBA};
aht10_xfer_desc_t xfer = {
.tx_data = tx_data,
.tx_size = 1U,
.rx_data = NULL,
.rx_size = 0U,
};
AHT10_ERROR_CHECK(aht->cb.xfer(aht->user_data, &xfer));
AHT10_ERROR_CHECK(aht->cb.delay(aht->user_data, 20));
tx_data[0] = 0xE1;
tx_data[1] = 0x08;
tx_data[2] = 0x00;
xfer.tx_size = 3U;
AHT10_ERROR_CHECK(aht->cb.xfer(aht->user_data, &xfer));
return AHT10_OK;
}
static aht10_ret_t aht10_start_measurement(aht10_t *aht) {
/* Start measurement */
uint8_t tx_data[3] = {0xAC, 0x33, 0x00};
aht10_xfer_desc_t xfer = {
.tx_data = tx_data,
.tx_size = 3U,
.rx_data = NULL,
.rx_size = 0U,
};
AHT10_ERROR_CHECK(aht->cb.xfer(aht->user_data, &xfer));
return AHT10_OK;
}
static aht10_ret_t aht10_read_result(aht10_t *aht, aht10_raw_t *raw) {
/* Read conversion result */
uint8_t tx_data[] = {0x71};
uint8_t rx_data[6];
aht10_xfer_desc_t xfer = {
.tx_data = tx_data,
.tx_size = 1U,
.rx_data = rx_data,
.rx_size = 6U,
};
AHT10_ERROR_CHECK(aht->cb.xfer(aht->user_data, &xfer));
raw->humidity = rx_data[1] << 12U;
raw->humidity |= rx_data[2] << 4U;
raw->humidity |= rx_data[3] >> 4U;
raw->temperature = (rx_data[3] & 0x0FU) << 16U;
raw->temperature |= rx_data[4] << 8U;
raw->temperature |= rx_data[5];
raw->status = rx_data[0];
return AHT10_OK;
}
aht10_ret_t aht10_init(aht10_t *aht) {
/* Check if we need initialization */
/* Delay 40ms after POR */
AHT10_ERROR_CHECK(aht->cb.delay(aht->user_data, 40));
aht10_raw_t raw;
/* Check 0x71 status byte, if uncalibrated then reset and calibrate it. */
AHT10_ERROR_CHECK(aht10_read_result(aht, &raw));
if ((raw.status & AHT10_STATUS_CALIBRATED_MASK) == 0) {
AHT10_ERROR_CHECK(aht10_software_reset(aht));
}
return AHT10_OK;
}
aht10_ret_t aht10_measure(aht10_t *aht, aht10_result_t *result) {
/* Start a measurement and read back result... */
AHT10_ERROR_CHECK(aht10_start_measurement(aht));
AHT10_ERROR_CHECK(aht->cb.delay(aht->user_data, 80));
aht10_raw_t raw;
uint8_t max_retries = 5U;
do {
AHT10_ERROR_CHECK(aht10_read_result(aht, &raw));
max_retries--;
if (max_retries == 0) {
return AHT10_FAIL;
}
#ifndef AHT10_SKIP_BUSY_CHECK
} while (raw.status & AHT10_STATUS_BUSY_MASK);
#else
} while (0);
#endif
result->temperature = ((double)raw.temperature * 200.0 / 1048576.0) - 50.0;
result->humidity = (double)raw.humidity * 100.0 / 1048576.0;
return AHT10_OK;
}