Files
ESP8266lib/ext/sens/AHT2x.h

99 lines
1.9 KiB
C++

#pragma once
/**
* humidity and temperature sensor
* https://asairsensors.com/wp-content/uploads/2021/09/Data-Sheet-AHT21-Humidity-and-Temperature-Sensor-ASAIR-V1.0.03.pdf
*/
template <typename I2C> class AHT2x {
private:
I2C& i2c;
static constexpr const uint8_t ADDR = 0x38;
static constexpr const char* NAME = "AHT2x";
static constexpr const uint8_t BIT_BUSY = 0x80;
static constexpr const uint8_t BIT_CALIBRATED = 0x08;
public:
struct Result {
float temp;
float humi;
};
public:
AHT2x(I2C& i2c) : i2c(i2c) {
}
void init() {
softReset();
int ok = calibrate();
printf("aht calib: %d\n", ok);
}
/** is the device present on the bus? */
bool isPresent() {
return i2c.query(ADDR);
}
void softReset() {
uint8_t cmd = 0xBA;
i2c.writeRaw(ADDR, 1, &cmd);
DELAY_MS(100);
}
bool calibrate() {
uint8_t cmdCalibrate[3] = {0xBE, 0x08, 0x00};
i2c.writeRaw(ADDR, 3, cmdCalibrate);
waitUntilDone();
return readStatus() & BIT_CALIBRATED;
}
void waitUntilDone() {
for (uint8_t i = 0; i < 200; ++i) {
printf(".");
if (!(readStatus() & BIT_BUSY)) {break;}
DELAY_MS(1);
}
printf("x\n");
}
uint8_t readStatus() {
uint8_t status = 0;
i2c.readRaw(ADDR, 1, &status);
return status;
}
Result measure() {
// trigger measurement
uint8_t cmdMeasure[3] = {0xAC, 0x33, 0x00};
i2c.writeRaw(ADDR, 3, cmdMeasure);
// fetch result, also waits until the busy-bit is cleared
uint8_t raw[6];
for(uint8_t i = 0; i < 50; ++i) {
DELAY_MS(10);
i2c.readRaw(ADDR, 6, raw);
bool busy = (raw[0] & BIT_BUSY);
if (!busy) {break;}
}
// calculate
Result res;
uint32_t _humi = ((raw[1] << 16) | (raw[2] << 8) | (raw[3] << 0)) >> 4;
res.humi = _humi * 100 / 1048576.0f;
uint32_t _temp = ((raw[3] & 0x0F) << 16) | (raw[4] << 8) | (raw[5] << 0);
res.temp = (_temp * 200 / 1048576.0f) - 50;
return res;
}
};