Skip to content

Commit

Permalink
Merge pull request #4321 from fmuntean/P014-SI70xx
Browse files Browse the repository at this point in the history
[P014 si70xx] fixing support for htu21D
  • Loading branch information
TD-er authored Nov 2, 2022
2 parents 22cc1fb + ce04d10 commit cff4e44
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 11 deletions.
3 changes: 3 additions & 0 deletions src/_P014_SI70xx.ino
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ boolean Plugin_014(uint8_t function, struct EventStruct *event, String& string)

case PLUGIN_INIT:
{
if (P014_I2C_ADDRESS == 0) {
P014_I2C_ADDRESS = SI70xx_I2C_ADDRESS; // Use default address if not (yet) set
}
initPluginTaskData(event->TaskIndex, new (std::nothrow) P014_data_struct());
P014_data_struct *P014_data = static_cast<P014_data_struct *>(getPluginTaskData(event->TaskIndex));

Expand Down
69 changes: 59 additions & 10 deletions src/src/PluginStructs/P014_data_struct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,22 @@ bool P014_data_struct::update(uint8_t i2caddr, uint8_t resolution, uint8_t filte
return true;
}

if (!readTemperature(i2caddr,resolution)){
last_measurement_time = millis();

if (chip_id == CHIP_ID_HTU21D){
if (!I2C_write8(i2caddr,SI70xx_CMD_MEASURE_TEMP)) { //HTU21D can't read temperature from humidity measurement
addLog(LOG_LEVEL_ERROR,F("SI70xx: startConv Failed!"));
return false;
}
state = P014_state::Wait_for_temperature_samples;
return false;
}

if (!readTemperatureFromHumidity(i2caddr,resolution)){
state = P014_state::Ready; //we go back to request the reading again
return true;
}

last_measurement_time = millis();
if (chip_id == CHIP_ID_SI7013){
if(!enablePowerForADC(i2caddr)){
state = P014_state::Ready; //we go back to request the reading again
Expand All @@ -198,7 +208,20 @@ bool P014_data_struct::update(uint8_t i2caddr, uint8_t resolution, uint8_t filte
return true;
//break;

case P014_state ::RequestADC:
case P014_state::Wait_for_temperature_samples:
if (!timeOutReached(last_measurement_time + SI70xx_MEASUREMENT_DELAY)) {
return false;
}

if (!readTemperature(i2caddr,resolution)){
state = P014_state::Ready; //we go back to request the reading again
return true;
}

state = P014_state::New_Values_Available;
return true;

case P014_state::RequestADC:
//make sure we wait for the power to stabilize
if (!timeOutReached(last_measurement_time + SI70xx_MEASUREMENT_DELAY)) {
return false;
Expand Down Expand Up @@ -504,7 +527,7 @@ bool P014_data_struct::readHumidity(uint8_t i2caddr, uint8_t resolution)

// Comes back in three bytes, data(MSB) / data(LSB) / Checksum
raw = ((uint16_t) Wire.read()) << 8;
raw |= Wire.read();
raw |= Wire.read();
uint8_t checksum = Wire.read();


Expand Down Expand Up @@ -533,12 +556,42 @@ bool P014_data_struct::readHumidity(uint8_t i2caddr, uint8_t resolution)
return true;
}

bool P014_data_struct::readTemperature(uint8_t i2caddr, uint8_t resolution)
{
uint16_t raw;
uint8_t bytes = Wire.requestFrom(i2caddr, 3u); //asking to read 3 bytes
if ( bytes < 3 ) {
return false;
}

// Comes back in three bytes, data(MSB) / data(LSB) / Checksum
raw = ((uint16_t) Wire.read()) << 8;
raw |= Wire.read();

uint8_t checksum = Wire.read();

// Check CRC of data received
if(checkCRC(raw, checksum) != 0) {
addLog(LOG_LEVEL_ERROR,F("SI70xx : checksum error!"));
return false;
}

temperature = convertRawTemperature(raw & 0xFFFC,resolution);
return true;
}

bool P014_data_struct::readTemperature(uint8_t i2caddr, uint8_t resolution){
bool P014_data_struct::readTemperatureFromHumidity(uint8_t i2caddr, uint8_t resolution){
// Temperature
//Request a reading
uint16_t raw = I2C_read16_reg(i2caddr,SI70xx_CMD_READ_TEMP_FROM_HUM);

// save value
temperature = convertRawTemperature(raw,resolution);

return true;
}

int16_t P014_data_struct::convertRawTemperature(uint16_t raw, uint8_t resolution){
// Convert raw value to Temperature (*100)
// for 23.45C value will be 2345
int16_t data = ((17572 * (long)raw) >> 16) - 4685;
Expand All @@ -553,11 +606,7 @@ bool P014_data_struct::readTemperature(uint8_t i2caddr, uint8_t resolution){
data *= 10;
}

// save value
temperature = data;

return true;
return data;
}


#endif // ifdef USES_P014
6 changes: 5 additions & 1 deletion src/src/PluginStructs/P014_data_struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
// ######################## Plugin 014 SI70xx I2C Temperature Humidity Sensor ###########################
// #######################################################################################################
// 12-10-2015 Charles-Henri Hallard, see my projects and blog at https://hallard.me
// 07-22-2022 MFD, Adding support for SI7013 with ADC
// 07-22-2022 MFD, Adding support for SI7013 with ADC
// 10-28-2022 MFD, fixing support for HTU21D (as this sensor does not have the command read temperature from humidity)


// SI70xx Sensor resolution
Expand Down Expand Up @@ -55,6 +56,7 @@
#define CHIP_ID_SI7013 13 // 0x0D=13=Si7013
#define CHIP_ID_SI7020 20 // 0x14=20=Si7020
#define CHIP_ID_SI7021 21 // 0x15=21=Si7021
#define CHIP_ID_HTU21D 50 // as measured by the plugin (the datasheet does not have this info)

#define SI70xx_RESET_DELAY 50 //delay in miliseconds for the reset to settle down
#define SI70xx_MEASUREMENT_TIMEOUT 100
Expand Down Expand Up @@ -104,9 +106,11 @@ struct P014_data_struct : public PluginTaskData_base {
bool requestADC(uint8_t i2caddr);
bool readADC(uint8_t i2caddr, uint8_t filter_power);
bool readHumidity(uint8_t i2caddr, uint8_t resolution);
bool readTemperatureFromHumidity(uint8_t i2caddr, uint8_t resolution);
bool readTemperature(uint8_t i2caddr, uint8_t resolution);
bool startInit(uint8_t i2caddr);
bool finalizeInit(uint8_t i2caddr, uint8_t resolution);
int16_t convertRawTemperature(uint16_t raw, uint8_t resolution);

public:
P014_data_struct();
Expand Down

0 comments on commit cff4e44

Please sign in to comment.