From 92643e89d023aafbfc4af8e09cc4de9771f5627b Mon Sep 17 00:00:00 2001 From: Robert Jaakke Date: Mon, 8 Jun 2020 20:37:04 +0200 Subject: [PATCH] Added support for multiple i2c addresses --- lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp | 32 +++---- lib/LOLIN_HP303B/src/LOLIN_HP303B.h | 10 +-- tasmota/xsns_73_hp303b.ino | 115 ++++++++++++++------------ 3 files changed, 84 insertions(+), 73 deletions(-) diff --git a/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp b/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp index fdeebd6a0..7f7f60a3f 100644 --- a/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp +++ b/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp @@ -35,7 +35,7 @@ LOLIN_HP303B::~LOLIN_HP303B(void) * &bus: I2CBus which connects MC to HP303B * slaveAddress: Address of the HP303B (0x77 or 0x76) */ -void LOLIN_HP303B::begin(TwoWire &bus, uint8_t slaveAddress) +uint8_t LOLIN_HP303B::begin(TwoWire &bus, uint8_t slaveAddress) { //this flag will show if the initialization was successful m_initFail = 0U; @@ -50,20 +50,20 @@ void LOLIN_HP303B::begin(TwoWire &bus, uint8_t slaveAddress) delay(50); //startup time of HP303B - init(); + return init(); } -void LOLIN_HP303B::begin(uint8_t slaveAddress) +uint8_t LOLIN_HP303B::begin(uint8_t slaveAddress) { - begin(Wire,slaveAddress); + return begin(Wire,slaveAddress); } /** * SPI begin function for HP303B with 4-wire SPI */ -void LOLIN_HP303B::begin(SPIClass &bus, int32_t chipSelect) +uint8_t LOLIN_HP303B::begin(SPIClass &bus, int32_t chipSelect) { - begin(bus, chipSelect, 0U); + return begin(bus, chipSelect, 0U); } /** @@ -74,7 +74,7 @@ void LOLIN_HP303B::begin(SPIClass &bus, int32_t chipSelect) * threeWire: 1 if HP303B is connected with 3-wire SPI * 0 if HP303B is connected with 4-wire SPI (standard) */ -void LOLIN_HP303B::begin(SPIClass &bus, int32_t chipSelect, uint8_t threeWire) +uint8_t LOLIN_HP303B::begin(SPIClass &bus, int32_t chipSelect, uint8_t threeWire) { //this flag will show if the initialization was successful m_initFail = 0U; @@ -102,11 +102,11 @@ void LOLIN_HP303B::begin(SPIClass &bus, int32_t chipSelect, uint8_t threeWire) if(writeByte(HP303B__REG_ADR_SPI3W, HP303B__REG_CONTENT_SPI3W)) { m_initFail = 1U; - return; + return 0U; } } - init(); + return init(); } /** @@ -840,14 +840,14 @@ int16_t LOLIN_HP303B::correctTemp(void) * This function has to be called from begin() * and requires a valid bus initialization. */ -void LOLIN_HP303B::init(void) +uint8_t LOLIN_HP303B::init(void) { int16_t prodId = readByteBitfield(HP303B__REG_INFO_PROD_ID); if(prodId != HP303B__PROD_ID) { //Connected device is not a HP303B m_initFail = 1U; - return; + return 0U; } m_productID = prodId; @@ -855,7 +855,7 @@ void LOLIN_HP303B::init(void) if(revId < 0) { m_initFail = 1U; - return; + return 0U; } m_revisionID = revId; @@ -864,7 +864,7 @@ void LOLIN_HP303B::init(void) if(sensor < 0) { m_initFail = 1U; - return; + return 0U; } //...and use this sensor for temperature measurement @@ -872,14 +872,14 @@ void LOLIN_HP303B::init(void) if(writeByteBitfield((uint8_t)sensor, HP303B__REG_INFO_TEMP_SENSOR) < 0) { m_initFail = 1U; - return; + return 0U; } //read coefficients if(readcoeffs() < 0) { m_initFail = 1U; - return; + return 0U; } //set to standby for further configuration @@ -901,6 +901,8 @@ void LOLIN_HP303B::init(void) // Fix IC with a fuse bit problem, which lead to a wrong temperature // Should not affect ICs without this problem correctTemp(); + + return 1U; } diff --git a/lib/LOLIN_HP303B/src/LOLIN_HP303B.h b/lib/LOLIN_HP303B/src/LOLIN_HP303B.h index ce65e17f1..651b80380 100644 --- a/lib/LOLIN_HP303B/src/LOLIN_HP303B.h +++ b/lib/LOLIN_HP303B/src/LOLIN_HP303B.h @@ -19,10 +19,10 @@ public: //destructor ~LOLIN_HP303B(void); //begin - void begin(TwoWire &bus, uint8_t slaveAddress); - void begin(uint8_t slaveAddress=HP303B__STD_SLAVE_ADDRESS); - void begin(SPIClass &bus, int32_t chipSelect); - void begin(SPIClass &bus, int32_t chipSelect, uint8_t threeWire); + uint8_t begin(TwoWire &bus, uint8_t slaveAddress); + uint8_t begin(uint8_t slaveAddress=HP303B__STD_SLAVE_ADDRESS); + uint8_t begin(SPIClass &bus, int32_t chipSelect); + uint8_t begin(SPIClass &bus, int32_t chipSelect, uint8_t threeWire); //end void end(void); @@ -115,7 +115,7 @@ private: uint8_t m_threeWire; //measurement - void init(void); + uint8_t init(void); int16_t readcoeffs(void); int16_t setOpMode(uint8_t background, uint8_t temperature, uint8_t pressure); int16_t setOpMode(uint8_t opMode); diff --git a/tasmota/xsns_73_hp303b.ino b/tasmota/xsns_73_hp303b.ino index ad439e555..b56fa6ded 100644 --- a/tasmota/xsns_73_hp303b.ino +++ b/tasmota/xsns_73_hp303b.ino @@ -29,45 +29,47 @@ #define XSNS_73 73 #define XI2C_52 52 // See I2CDEVICES.md -#define HP303B_ADDR1 0x77 -#define HP303B_ADDR2 0x76 - #include -// HP303B Opject +// HP303B Object LOLIN_HP303B HP303BSensor = LOLIN_HP303B(); -uint8_t bhp303b_addresses[2] = {HP303B_ADDR1, HP303B_ADDR2}; + +#define HP303B_MAX_SENSORS 2 +#define HP303B_START_ADDRESS 0x76 + +struct { +char types[7] = "HP303B"; +uint8_t count = 0; +int16_t oversampling = 7; +} hp303b_cfg; struct BHP303B { uint8_t address; - uint8_t type = 0; uint8_t valid = 0; - float temperature; - float pressure; - int16_t oversampling = 7; - char name[7] = "HP303B"; -} bhp303b_sensor; + float temperature = NAN; + float pressure = NAN; +} hp303b_sensor[HP303B_MAX_SENSORS]; /*********************************************************************************************/ -bool HP303B_Read() +bool HP303B_Read(uint8_t hp303b_idx) { - if (bhp303b_sensor.valid) { bhp303b_sensor.valid--; } + if (hp303b_sensor[hp303b_idx].valid) { hp303b_sensor[hp303b_idx].valid--; } float t; float p; int16_t ret; - ret = HP303BSensor.measureTempOnce(t, bhp303b_sensor.oversampling); + ret = HP303BSensor.measureTempOnce(t, hp303b_cfg.oversampling); if (ret != 0) return false; - ret = HP303BSensor.measurePressureOnce(p, bhp303b_sensor.oversampling); + ret = HP303BSensor.measurePressureOnce(p, hp303b_cfg.oversampling); if (ret != 0) return false; - bhp303b_sensor.temperature = (float)ConvertTemp(t); - bhp303b_sensor.pressure = (float)ConvertPressure(p) / 100; //conversion to hPa + hp303b_sensor[hp303b_idx].temperature = (float)ConvertTemp(t); + hp303b_sensor[hp303b_idx].pressure = (float)ConvertPressure(p) / 100; //conversion to hPa - bhp303b_sensor.valid = SENSOR_MAX_MISS; + hp303b_sensor[hp303b_idx].valid = SENSOR_MAX_MISS; return true; } @@ -75,18 +77,15 @@ bool HP303B_Read() void HP303B_Detect(void) { - for (uint32_t i = 0; i < sizeof(bhp303b_addresses); i++) + for (uint32_t i = 0; i < HP303B_MAX_SENSORS; i++) { - if (I2cActive(bhp303b_addresses[i])) { return; } + if (I2cActive(HP303B_START_ADDRESS + i)) { return; } - bhp303b_sensor.address = bhp303b_addresses[i]; - - HP303BSensor.begin( bhp303b_sensor.address); - - if (HP303B_Read()) + if (HP303BSensor.begin(HP303B_START_ADDRESS + i)) { - I2cSetActiveFound(bhp303b_sensor.address, bhp303b_sensor.name); - bhp303b_sensor.type = 1; + hp303b_sensor[hp303b_cfg.count].address = HP303B_START_ADDRESS + i; + I2cSetActiveFound(hp303b_sensor[hp303b_cfg.count].address, hp303b_cfg.types); + hp303b_cfg.count++; break; } } @@ -94,39 +93,49 @@ void HP303B_Detect(void) void HP303B_EverySecond(void) { - if (uptime &1) { - if (!HP303B_Read()) { - AddLogMissed(bhp303b_sensor.name, bhp303b_sensor.valid); + for (uint32_t i = 0; i < hp303b_cfg.count; i++) { + if (uptime &1) { + if (!HP303B_Read(i)) { + AddLogMissed(hp303b_cfg.types, hp303b_sensor[i].valid); } } + } } void HP303B_Show(bool json) { - if (bhp303b_sensor.valid) - { - char str_temperature[33]; - dtostrfd(bhp303b_sensor.temperature, Settings.flag2.temperature_resolution, str_temperature); - char str_pressure[33]; - dtostrfd(bhp303b_sensor.pressure, Settings.flag2.pressure_resolution, str_pressure); - - if (json) - { - ResponseAppend_P(PSTR(",\"HP303B\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_PRESSURE "\":%s"), str_temperature, str_pressure); - ResponseJsonEnd(); -#ifdef USE_DOMOTICZ - if (0 == tele_period) - { - DomoticzSensor(DZ_TEMP, bhp303b_sensor.temperature); - } -#endif // USE_DOMOTICZ -#ifdef USE_WEBSERVER + for (uint32_t i = 0; i < hp303b_cfg.count; i++) { + char sensor_name[12]; + strlcpy(sensor_name, hp303b_cfg.types, sizeof(sensor_name)); + if (hp303b_cfg.count > 1) { + snprintf_P(sensor_name, sizeof(sensor_name), PSTR("%s%c0x%02X"), sensor_name, IndexSeparator(), hp303b_sensor[i].address); // MCP9808-18, MCP9808-1A etc. } - else + + if (hp303b_sensor[i].valid) { - WSContentSend_PD(HTTP_SNS_TEMP, "HP303B", str_temperature, TempUnit()); - WSContentSend_PD(HTTP_SNS_PRESSURE, "HP303B", str_pressure, PressureUnit().c_str()); -#endif // USE_WEBSERVER + char str_temperature[33]; + dtostrfd(hp303b_sensor[i].temperature, Settings.flag2.temperature_resolution, str_temperature); + char str_pressure[33]; + dtostrfd(hp303b_sensor[i].pressure, Settings.flag2.pressure_resolution, str_pressure); + + if (json) + { + ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_PRESSURE "\":%s"), sensor_name, str_temperature, str_pressure); + ResponseJsonEnd(); + #ifdef USE_DOMOTICZ + if (0 == tele_period) + { + DomoticzSensor(DZ_TEMP, hp303b_sensor[i].temperature); + } + #endif // USE_DOMOTICZ + #ifdef USE_WEBSERVER + } + else + { + WSContentSend_PD(HTTP_SNS_TEMP, sensor_name, str_temperature, TempUnit()); + WSContentSend_PD(HTTP_SNS_PRESSURE, sensor_name, str_pressure, PressureUnit().c_str()); + #endif // USE_WEBSERVER + } } } } @@ -144,7 +153,7 @@ bool Xsns73(uint8_t function) if (FUNC_INIT == function) { HP303B_Detect(); } - else if (bhp303b_sensor.type) + else if (hp303b_cfg.count) { switch (function) {