#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 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; } };