94 lines
1.7 KiB
C++
94 lines
1.7 KiB
C++
|
|
#pragma once
|
|
|
|
/**
|
|
* humidity and temperature sensor
|
|
* https://www.mouser.com/datasheet/2/682/Sensirion_Humidity_Sensors_SHT3x_Datasheet_digital-971521.pdf
|
|
*
|
|
* sensor seems to be really good! and very easy to use!
|
|
*
|
|
*/
|
|
template <typename I2C> class SHT3x {
|
|
|
|
private:
|
|
|
|
I2C& i2c;
|
|
static constexpr const uint8_t ADDR = 0x44;
|
|
static constexpr const char* NAME = "SHT3x";
|
|
|
|
|
|
public:
|
|
|
|
SHT3x(I2C& i2c) : i2c(i2c) {
|
|
|
|
}
|
|
|
|
/** is the device present on the bus? */
|
|
bool isPresent() {
|
|
return i2c.query(ADDR);
|
|
}
|
|
|
|
struct Result {
|
|
float temp;
|
|
float humi;
|
|
};
|
|
|
|
/** trigger a single measurement */
|
|
Result singleMeasure() {
|
|
|
|
uint16_t cmd = 0x2400; // high quality, no clock stretching
|
|
sendCommand(cmd);
|
|
vTaskDelay(100 / portTICK_PERIOD_MS);
|
|
|
|
return readResult();
|
|
|
|
}
|
|
|
|
void startPeriodicMeasure() {
|
|
uint16_t cmd = 0x2130; // high quality, 1 measurement per second
|
|
sendCommand(cmd);
|
|
}
|
|
|
|
Result getLastResult() {
|
|
return readResult();
|
|
}
|
|
|
|
private:
|
|
|
|
Result readResult() {
|
|
|
|
uint8_t tmp[6];
|
|
i2c.readRaw(ADDR, 6, (uint8_t*)&tmp);
|
|
|
|
Result res;
|
|
res.temp = -45 + 175 * ((tmp[0]<<8) | (tmp[1]<<0)) / float((1<<16)-1);
|
|
res.humi = 100 * ((tmp[3]<<8) | (tmp[4]<<0)) / float((1<<16)-1);
|
|
return res;
|
|
|
|
}
|
|
|
|
void sendCommand(uint16_t cmd) {
|
|
uint8_t tmp[2];
|
|
tmp[0] = cmd >> 8;
|
|
tmp[1] = cmd >> 0;
|
|
i2c.writeRaw(ADDR, 2, tmp);
|
|
}
|
|
|
|
static uint8_t calcCRC(const uint8_t* data, uint8_t len) {
|
|
uint8_t crc = 0xff;
|
|
for (uint8_t i = 0; i < len; i++) {
|
|
crc ^= data[i];
|
|
for (uint8_t j = 0; j < 8; j++) {
|
|
if ((crc & 0x80) != 0) {
|
|
crc = (uint8_t)((crc << 1) ^ 0x31);
|
|
} else {
|
|
crc <<= 1;
|
|
}
|
|
}
|
|
}
|
|
return crc;
|
|
}
|
|
|
|
|
|
};
|