99 lines
1.9 KiB
C++
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;
|
|
|
|
}
|
|
|
|
};
|