102 lines
2.0 KiB
C++
102 lines
2.0 KiB
C++
|
|
|
|
#pragma once
|
|
|
|
/**
|
|
* humidity and temperature sensor
|
|
* https://www.ttieurope.com/content/dam/tti-europe/manufacturers/te-connectivity/resources/ENG_DS_HPC199_6_A6.pdf
|
|
*
|
|
* this sensor seems to be a bit stubborn.. requiring active polling until it is finished
|
|
* just waiting some time does not seem to work
|
|
*
|
|
*/
|
|
template <typename I2C> class HTU2x {
|
|
|
|
private:
|
|
|
|
I2C& i2c;
|
|
static constexpr const uint8_t ADDR = 0x40;
|
|
static constexpr const char* NAME = "HTU2x";
|
|
|
|
static constexpr const uint8_t CMD_QUERY_TEMP = 0xF3;
|
|
static constexpr const uint8_t CMD_QUERY_HUMI = 0xF5;
|
|
static constexpr const uint8_t CMD_READ_USER_REG = 0xE7;
|
|
static constexpr const uint8_t CMD_SOFT_RESET = 0xFE;
|
|
|
|
|
|
|
|
public:
|
|
|
|
HTU2x(I2C& i2c) : i2c(i2c) {
|
|
|
|
}
|
|
|
|
/** is the device present on the bus? */
|
|
bool isPresent() {
|
|
return i2c.query(ADDR);
|
|
}
|
|
|
|
struct Result {
|
|
float temp;
|
|
float humi;
|
|
float humiComp;
|
|
};
|
|
|
|
/** trigger a single measurement */
|
|
Result singleMeasure() {
|
|
|
|
uint8_t tmp[3]; // 2 bytes + checksum
|
|
Result res;
|
|
|
|
sendCMD(CMD_QUERY_TEMP);
|
|
if (waitForStart()) {
|
|
i2c.readBytes(tmp, 3);
|
|
i2c.stop();
|
|
uint16_t t = ((tmp[0]<<8)|(tmp[1]<<0)) & 0xFFFC;
|
|
//printf("a: %d\n", t);
|
|
res.temp = -46.85f + 175.72 * t / float(1<<16);
|
|
}
|
|
|
|
sendCMD(CMD_QUERY_HUMI);
|
|
if (waitForStart()) {
|
|
i2c.readBytes(tmp, 3);
|
|
i2c.stop();
|
|
uint16_t h = ((tmp[0]<<8)|(tmp[1]<<0)) & 0xFFFC;
|
|
//printf("b: %d\n", h);
|
|
res.humi = -6 + 125 * h / float(1<<16);
|
|
res.humiComp = res.humi + (-0.15 * (25 - res.temp));
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
bool waitForStart() {
|
|
for (int i = 0; i < 1024; ++i) {
|
|
if (i2c.startRead(ADDR)) {return true;}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void sendCMD(uint8_t cmd) {
|
|
i2c.writeRaw(ADDR, 1, &cmd);
|
|
}
|
|
|
|
void readUserRegister() {
|
|
|
|
i2c.writeRaw(ADDR, 1, &CMD_SOFT_RESET);
|
|
|
|
vTaskDelay(100 / portTICK_PERIOD_MS);
|
|
|
|
uint8_t val = 0xaa;
|
|
i2c.readReg(ADDR, CMD_READ_USER_REG, 1, &val);
|
|
|
|
printf("user: %d\n", val);
|
|
|
|
}
|
|
|
|
|
|
};
|