From 2df98a0cfe1a7df2aa6770fe42e84c3328f34889 Mon Sep 17 00:00:00 2001 From: fmuntean Date: Sun, 31 Jul 2022 16:15:58 -0400 Subject: [PATCH] [FIX] multiple fixes and updates: Init had to be split as delay is required after reset --- src/_P014_SI70xx.ino | 8 +- src/src/PluginStructs/P014_data_struct.cpp | 89 ++++++++++++++-------- src/src/PluginStructs/P014_data_struct.h | 9 ++- 3 files changed, 67 insertions(+), 39 deletions(-) diff --git a/src/_P014_SI70xx.ino b/src/_P014_SI70xx.ino index 9cba0843d..fbc055570 100644 --- a/src/_P014_SI70xx.ino +++ b/src/_P014_SI70xx.ino @@ -152,13 +152,13 @@ boolean Plugin_014(uint8_t function, struct EventStruct *event, String& string) if (nullptr == P014_data) { return success; } - if (P014_data->init(P014_I2C_ADDRESS, P014_RESOLUTION)) { - success = true; - }else{ + //if (P014_data->init(P014_I2C_ADDRESS, P014_RESOLUTION)) { + // success = true; + //}else{ UserVar[event->BaseVarIndex] = NAN; UserVar[event->BaseVarIndex + 1] = NAN; UserVar[event->BaseVarIndex + 2] = NAN; - } + //} break; } diff --git a/src/src/PluginStructs/P014_data_struct.cpp b/src/src/PluginStructs/P014_data_struct.cpp index 1b1a7a496..5d639ed73 100644 --- a/src/src/PluginStructs/P014_data_struct.cpp +++ b/src/src/PluginStructs/P014_data_struct.cpp @@ -9,7 +9,7 @@ P014_data_struct::P014_data_struct() { } -bool P014_data_struct::init(uint8_t i2caddr, uint8_t resolution) +bool P014_data_struct::startInit(uint8_t i2caddr) { state = P014_state::Uninitialized; @@ -31,19 +31,29 @@ bool P014_data_struct::init(uint8_t i2caddr, uint8_t resolution) return false; } + return true; +} + + +bool P014_data_struct::finalizeInit(uint8_t i2caddr, uint8_t resolution) +{ //read the device ID and revision - //sHT devices do not have this capability so we are continuing if not available - ret = readSerialNumber(i2caddr); //this will also set the device ID + //SHT devices do not have this capability so we are continuing if not available + int8_t ret = readSerialNumber(i2caddr); //this will also set the device ID if (ret){ - String log = F("SI70xx : Not able to read SN: "); + String log = F("SI70xx : Not able to read SN: addr=0x"); log += String(i2caddr, HEX); + log += F(" err="); + log += String(ret, DEC); addLog(LOG_LEVEL_ERROR, log); //return false; } //at this point we know the chip_id - + String log = F("P014: chip_id="); + log += String(chip_id, DEC); + addLog(LOG_LEVEL_INFO, log); if (chip_id == CHIP_ID_SI7013){ if (!I2C_write8_reg(i2caddr,SI7013_WRITE_REG2, SI7013_REG2_DEFAULT )){ return false; @@ -59,7 +69,7 @@ bool P014_data_struct::init(uint8_t i2caddr, uint8_t resolution) } //SI7013 has ADC and we need to start the first measurement - if (chip_id = CHIP_ID_SI7013){ + if (chip_id == CHIP_ID_SI7013){ if (!requestADC(i2caddr)) return false; } @@ -74,9 +84,7 @@ bool P014_data_struct::init(uint8_t i2caddr, uint8_t resolution) //Only perform the measurements with big interval to prevent the sensor from warming up. //returns true when the state changes and false otherwise bool P014_data_struct::update(uint8_t i2caddr, uint8_t resolution, uint8_t filter_power) { - //const unsigned long current_time = millis(); - //int8_t ret=0; - + switch(state){ case P014_state::Uninitialized: //make sure we do not try to initialize too often @@ -99,9 +107,8 @@ bool P014_data_struct::update(uint8_t i2caddr, uint8_t resolution, uint8_t filte return false; } - if (init(i2caddr, resolution)){ - state = P014_state::Initialized; - errCount = 0; + if (startInit(i2caddr)){ + state = P014_state::Wait_for_reset; return true; } @@ -109,6 +116,23 @@ bool P014_data_struct::update(uint8_t i2caddr, uint8_t resolution, uint8_t filte return false; //break; + case P014_state::Wait_for_reset: + //we need to wait for the chip to reset + if (!timeOutReached(last_measurement_time + SI70xx_RESET_DELAY)) { + return false; + } + + if (!finalizeInit(i2caddr,resolution)){ + state = P014_state::Uninitialized; + errCount++; + return true; + } + + errCount = 0; + state = P014_state::Initialized; + return true; + //break; + case P014_state::Initialized: if (chip_id == CHIP_ID_SI7013){ //we need to wait for the read of ADC @@ -145,21 +169,21 @@ bool P014_data_struct::update(uint8_t i2caddr, uint8_t resolution, uint8_t filte } if (!readHumidity(i2caddr, resolution)) { - return false; + state = P014_state::Ready; //we go back to request the reading again + return true; } if (!readTemperature(i2caddr,resolution)){ state = P014_state::Ready; //we go back to request the reading again - return false; + 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 - return false; + return true; } - state = P014_state::RequestADC; }else{ state = P014_state::New_Values_Available; @@ -175,7 +199,7 @@ bool P014_data_struct::update(uint8_t i2caddr, uint8_t resolution, uint8_t filte if (!requestADC(i2caddr)){ state = P014_state::Ready; //we go back to request the reading again - return false; + return true; } state = P014_state::Wait_for_adc_samples; @@ -283,11 +307,11 @@ bool P014_data_struct::setResolution(uint8_t i2caddr, uint8_t resolution) inline bool P014_data_struct::softReset(uint8_t i2caddr){ // Prepare to write to the register value bool ret = I2C_write8(i2caddr, SI70xx_CMD_SOFT_RESET); - //delay(50); //MFD: check the datasheet return ret; } +#ifndef LIMIT_BUILD_SIZE int8_t P014_data_struct::readRevision(uint8_t i2caddr) { Wire.beginTransmission(i2caddr); Wire.write((uint8_t)(SI70xx_CMD_FIRMREV >> 8)); @@ -312,6 +336,8 @@ int8_t P014_data_struct::readRevision(uint8_t i2caddr) { return -1; // Error timeout } +#endif + /*! * @brief Reads serial number and stores It in sernum_a and sernum_b variable */ @@ -319,48 +345,47 @@ int8_t P014_data_struct::readSerialNumber(uint8_t i2caddr) { bool ok = I2C_write8_reg(i2caddr,(uint8_t)(SI70xx_CMD_ID1 >> 8),(uint8_t)(SI70xx_CMD_ID1 & 0xFF)); if (!ok) return -1; //error on sending command - - if (Wire.requestFrom(i2caddr, 8u) != 8u) { return -2; //time out on the SNA read } - uint32_t sernum_a = Wire.read(); + uint32_t sernum_a = Wire.read(); //SNA_3 Wire.read(); //ignore CRC sernum_a <<= 8; - sernum_a |= Wire.read(); + sernum_a |= Wire.read(); //SNA_2 Wire.read(); //ignore CRC sernum_a <<= 8; - sernum_a |= Wire.read(); + sernum_a |= Wire.read(); //SNA_1 Wire.read(); //ignore CRC sernum_a <<= 8; - sernum_a |= Wire.read(); + sernum_a |= Wire.read(); //SNA_0 Wire.read(); //ignore CRC ok = I2C_write8_reg(i2caddr,(uint8_t)(SI70xx_CMD_ID2 >> 8),(uint8_t)(SI70xx_CMD_ID2 & 0xFF)); if (!ok) return -3; //error on sending command - if (Wire.requestFrom(i2caddr, 8u) != 8u) { + if (Wire.requestFrom(i2caddr, 6u) != 6u) { return -4; //time out on the SNA read } - uint32_t sernum_b = Wire.read(); //Device ID + uint32_t sernum_b = Wire.read(); //SNB_3 (Device ID) chip_id = sernum_b; //we save the chip identifier + //Wire.read(); //ignore CRC + sernum_b <<= 8; + sernum_b |= Wire.read(); //SNB_2 Wire.read(); //ignore CRC sernum_b <<= 8; - sernum_b |= Wire.read(); - Wire.read(); //ignore CRC + sernum_b |= Wire.read(); //SNB_1 + //Wire.read(); //ignore CRC sernum_b <<= 8; - sernum_b |= Wire.read(); - Wire.read(); //ignore CRC - sernum_b <<= 8; - sernum_b |= Wire.read(); + sernum_b |= Wire.read(); //SNB_0 Wire.read(); //ignore CRC String log = F("SI7013 : sn="); log += String(sernum_a,HEX); + log += F("-"); log += String(sernum_b,HEX); addLog(LOG_LEVEL_INFO,log); diff --git a/src/src/PluginStructs/P014_data_struct.h b/src/src/PluginStructs/P014_data_struct.h index 76f42e96e..26051fe82 100644 --- a/src/src/PluginStructs/P014_data_struct.h +++ b/src/src/PluginStructs/P014_data_struct.h @@ -56,6 +56,7 @@ #define CHIP_ID_SI7020 20 // 0x14=20=Si7020 #define CHIP_ID_SI7021 21 // 0x15=21=Si7021 +#define SI70xx_RESET_DELAY 50 //delay in miliseconds for the reset to settle down #define SI70xx_MEASUREMENT_TIMEOUT 100 #define SI70xx_INIT_DELAY 1000 //delay in miliseconds between inits #define SI70xx_MEASUREMENT_DELAY 100 //delay in milliseconds for reading the values @@ -78,6 +79,7 @@ measurement (use approximately 100 msec for the 0.1 µF filter, which has a time enum class P014_state { Uninitialized = 0, + Wait_for_reset, Initialized, Ready, Wait_for_temperature_samples, @@ -93,7 +95,9 @@ struct P014_data_struct : public PluginTaskData_base { uint8_t checkCRC(uint16_t data, uint8_t check); bool setResolution(uint8_t i2caddr, uint8_t resolution); bool softReset(uint8_t i2caddr); + #ifndef LIMIT_BUILD_SIZE int8_t readRevision(uint8_t i2caddr); + #endif int8_t readSerialNumber(uint8_t i2caddr); bool enablePowerForADC(uint8_t i2caddr); bool disablePowerForADC(uint8_t i2caddr); @@ -101,13 +105,12 @@ struct P014_data_struct : public PluginTaskData_base { bool readADC(uint8_t i2caddr, uint8_t filter_power); bool readHumidity(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); public: P014_data_struct(); - bool init(uint8_t i2caddr, uint8_t resolution); - - // Only perform the measurements with big interval to prevent the sensor from warming up. //This method runs the FSM step by step on each call bool update(uint8_t i2caddr, uint8_t resolution, uint8_t filter_power);