From d80b763f979c5f0d2af0962e8ddbe9eb0660e6a0 Mon Sep 17 00:00:00 2001 From: Ralph Maschotta Date: Sun, 8 Jan 2023 15:57:34 +0100 Subject: [PATCH] Enable more than two and up to four BMP/BME sensors on two I2C buses for ESP32 (only two addresses (76, 77) per I2C bus are possible). (enhancement of #10827,#1049, #2707) (#17643) --- tasmota/tasmota_support/support.ino | 205 ++++++++++++-------- tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino | 152 ++++++++++----- 2 files changed, 227 insertions(+), 130 deletions(-) diff --git a/tasmota/tasmota_support/support.ino b/tasmota/tasmota_support/support.ino index 489961737..38d35d094 100755 --- a/tasmota/tasmota_support/support.ino +++ b/tasmota/tasmota_support/support.ino @@ -2179,6 +2179,9 @@ bool TimeReachedUsec(uint32_t timer) const uint8_t I2C_RETRY_COUNTER = 3; uint32_t i2c_active[4] = { 0 }; +#ifdef ESP32 +uint32_t i2c_active_bus2[4] = { 0 }; // ESP32 can have two I2C buses +#endif uint32_t i2c_buffer = 0; bool I2cBegin(int sda, int scl, uint32_t frequency = 100000); @@ -2208,12 +2211,9 @@ bool I2c2Begin(int sda, int scl, uint32_t frequency) { // AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: Bus2 %d"), result); return result; } - -bool I2cValidRead(uint8_t addr, uint8_t reg, uint8_t size, uint32_t bus = 0); -bool I2cValidRead(uint8_t addr, uint8_t reg, uint8_t size, uint32_t bus) -#else -bool I2cValidRead(uint8_t addr, uint8_t reg, uint8_t size) #endif + +bool I2cValidRead(uint8_t addr, uint8_t reg, uint8_t size, uint8_t bus = 0) { uint8_t retry = I2C_RETRY_COUNTER; bool status = false; @@ -2243,102 +2243,85 @@ bool I2cValidRead(uint8_t addr, uint8_t reg, uint8_t size) return status; } -bool I2cValidRead8(uint8_t *data, uint8_t addr, uint8_t reg) +bool I2cValidRead8(uint8_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0) { - bool status = I2cValidRead(addr, reg, 1); + bool status = I2cValidRead(addr, reg, 1,bus); *data = (uint8_t)i2c_buffer; return status; } - -bool I2cValidRead16(uint16_t *data, uint8_t addr, uint8_t reg) +bool I2cValidRead16(uint16_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0) { - bool status = I2cValidRead(addr, reg, 2); + bool status = I2cValidRead(addr, reg, 2,bus); *data = (uint16_t)i2c_buffer; return status; } - -bool I2cValidReadS16(int16_t *data, uint8_t addr, uint8_t reg) +bool I2cValidReadS16(int16_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0) { - bool status = I2cValidRead(addr, reg, 2); + bool status = I2cValidRead(addr, reg, 2, bus); *data = (int16_t)i2c_buffer; return status; } - -bool I2cValidRead16LE(uint16_t *data, uint8_t addr, uint8_t reg) +bool I2cValidRead16LE(uint16_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0) { uint16_t ldata; - bool status = I2cValidRead16(&ldata, addr, reg); + bool status = I2cValidRead16(&ldata, addr, reg, bus); *data = (ldata >> 8) | (ldata << 8); return status; } - -bool I2cValidReadS16_LE(int16_t *data, uint8_t addr, uint8_t reg) +bool I2cValidReadS16_LE(int16_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0) { uint16_t ldata; - bool status = I2cValidRead16LE(&ldata, addr, reg); + bool status = I2cValidRead16LE(&ldata, addr, reg, bus); *data = (int16_t)ldata; return status; } - -bool I2cValidRead24(int32_t *data, uint8_t addr, uint8_t reg) +bool I2cValidRead24(int32_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0) { - bool status = I2cValidRead(addr, reg, 3); + bool status = I2cValidRead(addr, reg, 3, bus); *data = i2c_buffer; return status; } - -uint8_t I2cRead8(uint8_t addr, uint8_t reg) +uint8_t I2cRead8(uint8_t addr, uint8_t reg, uint8_t bus = 0) { - I2cValidRead(addr, reg, 1); + I2cValidRead(addr, reg, 1, bus); return (uint8_t)i2c_buffer; } - -uint16_t I2cRead16(uint8_t addr, uint8_t reg) +uint16_t I2cRead16(uint8_t addr, uint8_t reg, uint8_t bus = 0) { - I2cValidRead(addr, reg, 2); + I2cValidRead(addr, reg, 2, bus); return (uint16_t)i2c_buffer; } - -int16_t I2cReadS16(uint8_t addr, uint8_t reg) +int16_t I2cReadS16(uint8_t addr, uint8_t reg, uint8_t bus = 0) { - I2cValidRead(addr, reg, 2); + I2cValidRead(addr, reg, 2, bus); return (int16_t)i2c_buffer; } - -uint16_t I2cRead16LE(uint8_t addr, uint8_t reg) +uint16_t I2cRead16LE(uint8_t addr, uint8_t reg, uint8_t bus = 0) { - I2cValidRead(addr, reg, 2); + I2cValidRead(addr, reg, 2, bus); uint16_t temp = (uint16_t)i2c_buffer; return (temp >> 8) | (temp << 8); } - -int16_t I2cReadS16_LE(uint8_t addr, uint8_t reg) +int16_t I2cReadS16_LE(uint8_t addr, uint8_t reg, uint8_t bus = 0) { - return (int16_t)I2cRead16LE(addr, reg); + return (int16_t)I2cRead16LE(addr, reg, bus); } - -int32_t I2cRead24(uint8_t addr, uint8_t reg) +int32_t I2cRead24(uint8_t addr, uint8_t reg, uint8_t bus = 0) { - I2cValidRead(addr, reg, 3); + I2cValidRead(addr, reg, 3, bus); return i2c_buffer; } -#ifdef ESP32 -bool I2cWrite(uint8_t addr, uint8_t reg, uint32_t val, uint8_t size, uint32_t bus = 0); -bool I2cWrite(uint8_t addr, uint8_t reg, uint32_t val, uint8_t size, uint32_t bus) -#else -bool I2cWrite(uint8_t addr, uint8_t reg, uint32_t val, uint8_t size) -#endif +bool I2cWrite(uint8_t addr, uint8_t reg, uint32_t val, uint8_t size, uint8_t bus = 0) { uint8_t x = I2C_RETRY_COUNTER; - #ifdef ESP32 if (!TasmotaGlobal.i2c_enabled_2) { bus = 0; } TwoWire & myWire = (bus == 0) ? Wire : Wire1; #else + if(0!=bus) {return false;} // second I2c bus ESP32 only TwoWire & myWire = Wire; #endif - do { myWire.beginTransmission((uint8_t)addr); // start transmission to device myWire.write(reg); // sends register address to write to @@ -2350,46 +2333,59 @@ bool I2cWrite(uint8_t addr, uint8_t reg, uint32_t val, uint8_t size) } while (myWire.endTransmission(true) != 0 && x != 0); // end transmission return (x); } - -bool I2cWrite8(uint8_t addr, uint8_t reg, uint16_t val) +bool I2cWrite8(uint8_t addr, uint8_t reg, uint32_t val, uint8_t bus = 0) { - return I2cWrite(addr, reg, val, 1); + return I2cWrite(addr, reg, val, 1,bus); } -bool I2cWrite16(uint8_t addr, uint8_t reg, uint16_t val) +bool I2cWrite16(uint8_t addr, uint8_t reg, uint32_t val, uint8_t bus = 0) { - return I2cWrite(addr, reg, val, 2); + return I2cWrite(addr, reg, val, 2,bus); } -int8_t I2cReadBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len) +bool I2cReadBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len, uint8_t bus = 0) { - Wire.beginTransmission((uint8_t)addr); - Wire.write((uint8_t)reg); - Wire.endTransmission(); - if (len != Wire.requestFrom((uint8_t)addr, (uint8_t)len)) { +#ifdef ESP32 + if (!TasmotaGlobal.i2c_enabled_2) { bus = 0; } + TwoWire & myWire = (bus == 0) ? Wire : Wire1; +#else + if(0!=bus) {return false;} // second I2c bus ESP32 only + TwoWire & myWire = Wire; +#endif + myWire.beginTransmission((uint8_t)addr); + myWire.write((uint8_t)reg); + myWire.endTransmission(); + if (len != myWire.requestFrom((uint8_t)addr, (uint8_t)len)) { return 1; } while (len--) { - *reg_data = (uint8_t)Wire.read(); + *reg_data = (uint8_t)myWire.read(); reg_data++; } return 0; } -int8_t I2cWriteBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len) +int8_t I2cWriteBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len, uint8_t bus = 0) { - Wire.beginTransmission((uint8_t)addr); - Wire.write((uint8_t)reg); +#ifdef ESP32 + if (!TasmotaGlobal.i2c_enabled_2) { bus = 0; } + TwoWire & myWire = (bus == 0) ? Wire : Wire1; +#else + if(0!=bus) {return false;} // second I2c bus ESP32 only + TwoWire & myWire = Wire; +#endif + myWire.beginTransmission((uint8_t)addr); + myWire.write((uint8_t)reg); while (len--) { - Wire.write(*reg_data); + myWire.write(*reg_data); reg_data++; } - Wire.endTransmission(); + myWire.endTransmission(); return 0; } -void I2cScan(uint32_t bus = 0); -void I2cScan(uint32_t bus) { +void I2cScan(uint8_t bus = 0) +{ // Return error codes defined in twi.h and core_esp8266_si2c.c // I2C_OK 0 // I2C_SCL_HELD_LOW 1 = SCL held low by another device, no procedure available to recover @@ -2415,17 +2411,22 @@ void I2cScan(uint32_t bus) { if (!TasmotaGlobal.i2c_enabled_2) { bus = 0; } TwoWire & myWire = (bus == 0) ? Wire : Wire1; #else + if(0!=bus) {return;} // second I2c bus ESP32 only TwoWire & myWire = Wire; #endif myWire.beginTransmission(address); error = myWire.endTransmission(); if (0 == error) { any = 1; +#ifdef ESP32 + ResponseAppend_P(PSTR(" 0x%02x:%d"), address, bus); +#else ResponseAppend_P(PSTR(" 0x%02x"), address); +#endif } else if (error != 2) { // Seems to happen anyway using this scan any = 2; - Response_P(PSTR("{\"" D_CMND_I2CSCAN "\":\"Error %d at 0x%02x"), error, address); + Response_P(PSTR("{\"" D_CMND_I2CSCAN "\":\"Error %d at 0x%02x bus %d"), error, address, bus); break; } } @@ -2437,31 +2438,55 @@ void I2cScan(uint32_t bus) { } } -void I2cResetActive(uint32_t addr, uint32_t count = 1) +void I2cResetActive(uint32_t addr, uint32_t count = 1, uint8_t bus = 0) { addr &= 0x7F; // Max I2C address is 127 count &= 0x7F; // Max 4 x 32 bits available - while (count-- && (addr < 128)) { - i2c_active[addr / 32] &= ~(1 << (addr % 32)); + while (count-- && (addr < 128)) + { +#ifdef ESP32 + if(0==bus) + { +#endif + i2c_active[addr / 32] &= ~(1 << (addr % 32)); +#ifdef ESP32 + } + else + { + i2c_active_bus2[addr / 32] &= ~(1 << (addr % 32)); + } +#endif addr++; } // AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: Active %08X,%08X,%08X,%08X"), i2c_active[0], i2c_active[1], i2c_active[2], i2c_active[3]); } -void I2cSetActive(uint32_t addr, uint32_t count = 1) +void I2cSetActive(uint32_t addr, uint32_t count = 1, uint8_t bus = 0) { addr &= 0x7F; // Max I2C address is 127 count &= 0x7F; // Max 4 x 32 bits available - while (count-- && (addr < 128)) { - i2c_active[addr / 32] |= (1 << (addr % 32)); + while (count-- && (addr < 128)) + { +#ifdef ESP32 + if(0==bus) + { +#endif + i2c_active[addr / 32] |= (1 << (addr % 32)); +#ifdef ESP32 + } + else + { + i2c_active_bus2[addr / 32] |= (1 << (addr % 32)); + } +#endif addr++; } // AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: Active %08X,%08X,%08X,%08X"), i2c_active[0], i2c_active[1], i2c_active[2], i2c_active[3]); } -void I2cSetActiveFound(uint32_t addr, const char *types, uint32_t bus = 0); -void I2cSetActiveFound(uint32_t addr, const char *types, uint32_t bus) { - I2cSetActive(addr); +void I2cSetActiveFound(uint32_t addr, const char *types, uint8_t bus = 0) +{ + I2cSetActive(addr,bus); #ifdef ESP32 if (0 == bus) { AddLog(LOG_LEVEL_INFO, S_LOG_I2C_FOUND_AT, types, addr); @@ -2472,18 +2497,30 @@ void I2cSetActiveFound(uint32_t addr, const char *types, uint32_t bus) { AddLog(LOG_LEVEL_INFO, S_LOG_I2C_FOUND_AT, types, addr); #endif // ESP32 } - -bool I2cActive(uint32_t addr) +bool I2cActive(uint32_t addr, uint8_t bus = 0) { +#ifdef ESP32 + if(0==bus) + { +#endif + addr &= 0x7F; // Max I2C address is 127 + if (i2c_active[addr / 32] & (1 << (addr % 32))) { + return true; + } + return false; +#ifdef ESP32 + } + // else addr &= 0x7F; // Max I2C address is 127 - if (i2c_active[addr / 32] & (1 << (addr % 32))) { + if (i2c_active_bus2[addr / 32] & (1 << (addr % 32))) { return true; } return false; +#endif } -bool I2cSetDevice(uint32_t addr, uint32_t bus = 0); -bool I2cSetDevice(uint32_t addr, uint32_t bus) { +bool I2cSetDevice(uint32_t addr, uint8_t bus = 0) +{ #ifdef ESP32 if (!TasmotaGlobal.i2c_enabled_2) { bus = 0; } TwoWire & myWire = (bus == 0) ? Wire : Wire1; @@ -2491,14 +2528,18 @@ bool I2cSetDevice(uint32_t addr, uint32_t bus) { TwoWire & myWire = Wire; #endif addr &= 0x7F; // Max I2C address is 127 - if (I2cActive(addr)) { + if (I2cActive(addr,bus)) { return false; // If already active report as not present; } myWire.beginTransmission((uint8_t)addr); // return (0 == myWire.endTransmission()); uint32_t err = myWire.endTransmission(); if (err && (err != 2)) { +#ifdef ESP32 + AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: Error %d at 0x%02x bus &d"), err, addr,bus); +#else AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: Error %d at 0x%02x"), err, addr); +#endif } return (0 == err); } diff --git a/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino b/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino index 503b8ff3e..adeda6696 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino @@ -48,7 +48,11 @@ #define BMP_CMND_RESET 0xB6 // I2C Parameter for RESET to put BMP into reset state -#define BMP_MAX_SENSORS 2 +#ifdef ESP32 + #define BMP_MAX_SENSORS 4 +#else + #define BMP_MAX_SENSORS 2 +#endif const char kBmpTypes[] PROGMEM = "BMP180|BMP280|BME280|BME680"; @@ -66,7 +70,7 @@ typedef struct { float bmp_humidity; } bmp_sensors_t; -uint8_t bmp_addresses[] = { BMP_ADDR1, BMP_ADDR2 }; +uint8_t bmp_addresses[] = { BMP_ADDR1, BMP_ADDR2, BMP_ADDR1, BMP_ADDR2}; uint8_t bmp_count = 0; uint8_t bmp_once = 1; @@ -116,18 +120,17 @@ bool Bmp180Calibration(uint8_t bmp_idx) bmp180_cal_data = (bmp180_cal_data_t*)malloc(BMP_MAX_SENSORS * sizeof(bmp180_cal_data_t)); } if (!bmp180_cal_data) { return false; } - - bmp180_cal_data[bmp_idx].cal_ac1 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC1); - bmp180_cal_data[bmp_idx].cal_ac2 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC2); - bmp180_cal_data[bmp_idx].cal_ac3 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC3); - bmp180_cal_data[bmp_idx].cal_ac4 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC4); - bmp180_cal_data[bmp_idx].cal_ac5 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC5); - bmp180_cal_data[bmp_idx].cal_ac6 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC6); - bmp180_cal_data[bmp_idx].cal_b1 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_VB1); - bmp180_cal_data[bmp_idx].cal_b2 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_VB2); - bmp180_cal_data[bmp_idx].cal_mc = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_MC); - bmp180_cal_data[bmp_idx].cal_md = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_MD); - + uint8_t bus= (bmp_idx>=2) ? 1 : 0; // first two BMP's at bus 0, additional at bus 1 (ESP32 32 only) + bmp180_cal_data[bmp_idx].cal_ac1 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC1,bus); + bmp180_cal_data[bmp_idx].cal_ac2 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC2,bus); + bmp180_cal_data[bmp_idx].cal_ac3 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC3,bus); + bmp180_cal_data[bmp_idx].cal_ac4 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC4,bus); + bmp180_cal_data[bmp_idx].cal_ac5 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC5,bus); + bmp180_cal_data[bmp_idx].cal_ac6 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC6,bus); + bmp180_cal_data[bmp_idx].cal_b1 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_VB1,bus); + bmp180_cal_data[bmp_idx].cal_b2 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_VB2,bus); + bmp180_cal_data[bmp_idx].cal_mc = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_MC,bus); + bmp180_cal_data[bmp_idx].cal_md = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_MD,bus); // Check for Errors in calibration data. Value never is 0x0000 or 0xFFFF if (!bmp180_cal_data[bmp_idx].cal_ac1 | !bmp180_cal_data[bmp_idx].cal_ac2 | @@ -160,18 +163,30 @@ bool Bmp180Calibration(uint8_t bmp_idx) void Bmp180Read(uint8_t bmp_idx) { if (!bmp180_cal_data) { return; } - +#ifdef ESP32 + uint8_t bus= (bmp_idx>=2) ? 1 : 0; // first two BMP's at bus 0, additional at bus 1 + I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BMP180_REG_CONTROL, BMP180_TEMPERATURE,bus); + delay(5); // 5ms conversion time + int ut = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_REG_RESULT,bus); +#else I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BMP180_REG_CONTROL, BMP180_TEMPERATURE); delay(5); // 5ms conversion time int ut = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_REG_RESULT); +#endif int32_t xt1 = (ut - (int32_t)bmp180_cal_data[bmp_idx].cal_ac6) * ((int32_t)bmp180_cal_data[bmp_idx].cal_ac5) >> 15; int32_t xt2 = ((int32_t)bmp180_cal_data[bmp_idx].cal_mc << 11) / (xt1 + (int32_t)bmp180_cal_data[bmp_idx].cal_md); int32_t bmp180_b5 = xt1 + xt2; bmp_sensors[bmp_idx].bmp_temperature = ((bmp180_b5 + 8) >> 4) / 10.0f; +#ifdef ESP32 + I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BMP180_REG_CONTROL, BMP180_PRESSURE3,bus); // Highest resolution + delay(2 + (4 << BMP180_OSS)); // 26ms conversion time at ultra high resolution + uint32_t up = I2cRead24(bmp_sensors[bmp_idx].bmp_address, BMP180_REG_RESULT,bus); +#else I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BMP180_REG_CONTROL, BMP180_PRESSURE3); // Highest resolution delay(2 + (4 << BMP180_OSS)); // 26ms conversion time at ultra high resolution uint32_t up = I2cRead24(bmp_sensors[bmp_idx].bmp_address, BMP180_REG_RESULT); +#endif up >>= (8 - BMP180_OSS); int32_t b6 = bmp180_b5 - 4000; @@ -264,34 +279,34 @@ bool Bmx280Calibrate(uint8_t bmp_idx) } if (!Bme280CalibrationData) { return false; } - Bme280CalibrationData[bmp_idx].dig_T1 = I2cRead16LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_T1); - Bme280CalibrationData[bmp_idx].dig_T2 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_T2); - Bme280CalibrationData[bmp_idx].dig_T3 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_T3); - Bme280CalibrationData[bmp_idx].dig_P1 = I2cRead16LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P1); - Bme280CalibrationData[bmp_idx].dig_P2 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P2); - Bme280CalibrationData[bmp_idx].dig_P3 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P3); - Bme280CalibrationData[bmp_idx].dig_P4 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P4); - Bme280CalibrationData[bmp_idx].dig_P5 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P5); - Bme280CalibrationData[bmp_idx].dig_P6 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P6); - Bme280CalibrationData[bmp_idx].dig_P7 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P7); - Bme280CalibrationData[bmp_idx].dig_P8 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P8); - Bme280CalibrationData[bmp_idx].dig_P9 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P9); + uint8_t bus= (bmp_idx>=2) ? 1 : 0; // first two BMP's at bus 0, additional at bus 1 (ESP32 32 only) + Bme280CalibrationData[bmp_idx].dig_T1 = I2cRead16LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_T1,bus); + Bme280CalibrationData[bmp_idx].dig_T2 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_T2,bus); + Bme280CalibrationData[bmp_idx].dig_T3 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_T3,bus); + Bme280CalibrationData[bmp_idx].dig_P1 = I2cRead16LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P1,bus); + Bme280CalibrationData[bmp_idx].dig_P2 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P2,bus); + Bme280CalibrationData[bmp_idx].dig_P3 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P3,bus); + Bme280CalibrationData[bmp_idx].dig_P4 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P4,bus); + Bme280CalibrationData[bmp_idx].dig_P5 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P5,bus); + Bme280CalibrationData[bmp_idx].dig_P6 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P6,bus); + Bme280CalibrationData[bmp_idx].dig_P7 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P7,bus); + Bme280CalibrationData[bmp_idx].dig_P8 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P8,bus); + Bme280CalibrationData[bmp_idx].dig_P9 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P9,bus); if (BME280_CHIPID == bmp_sensors[bmp_idx].bmp_type) { // #1051 - Bme280CalibrationData[bmp_idx].dig_H1 = I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H1); - Bme280CalibrationData[bmp_idx].dig_H2 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H2); - Bme280CalibrationData[bmp_idx].dig_H3 = I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H3); - Bme280CalibrationData[bmp_idx].dig_H4 = (I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H4) << 4) | (I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H4 + 1) & 0xF); - Bme280CalibrationData[bmp_idx].dig_H5 = (I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H5 + 1) << 4) | (I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H5) >> 4); - Bme280CalibrationData[bmp_idx].dig_H6 = (int8_t)I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H6); - I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_CONTROL, 0x00); // sleep mode since writes to config can be ignored in normal mode (Datasheet 5.4.5/6 page 27) + Bme280CalibrationData[bmp_idx].dig_H1 = I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H1,bus); + Bme280CalibrationData[bmp_idx].dig_H2 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H2,bus); + Bme280CalibrationData[bmp_idx].dig_H3 = I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H3,bus); + Bme280CalibrationData[bmp_idx].dig_H4 = (I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H4,bus) << 4) | (I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H4 + 1,bus) & 0xF); + Bme280CalibrationData[bmp_idx].dig_H5 = (I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H5 + 1,bus) << 4) | (I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H5,bus>>1) >> 4); + Bme280CalibrationData[bmp_idx].dig_H6 = (int8_t)I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H6,bus); + I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_CONTROL, 0x00,bus); // sleep mode since writes to config can be ignored in normal mode (Datasheet 5.4.5/6 page 27) // Set before CONTROL_meas (DS 5.4.3) - I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_CONTROLHUMID, 0x01); // 1x oversampling - I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_CONFIG, 0xA0); // 1sec standby between measurements (to limit self heating), IIR filter off - I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_CONTROL, 0x27); // 1x oversampling, normal mode + I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_CONTROLHUMID, 0x01,bus); // 1x oversampling + I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_CONFIG, 0xA0,bus); // 1sec standby between measurements (to limit self heating), IIR filter off + I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_CONTROL, 0x27,bus); // 1x oversampling, normal mode } else { - I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_CONTROL, 0xB7); // 16x oversampling, normal mode (Adafruit) + I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_CONTROL, 0xB7,bus); // 16x oversampling, normal mode (Adafruit) } - return true; } @@ -299,7 +314,11 @@ void Bme280Read(uint8_t bmp_idx) { if (!Bme280CalibrationData) { return; } +#ifdef ESP32 + int32_t adc_T = I2cRead24(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_TEMPDATA,bmp_idx>>1); +#else int32_t adc_T = I2cRead24(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_TEMPDATA); +#endif adc_T >>= 4; int32_t vart1 = ((((adc_T >> 3) - ((int32_t)Bme280CalibrationData[bmp_idx].dig_T1 << 1))) * ((int32_t)Bme280CalibrationData[bmp_idx].dig_T2)) >> 11; @@ -308,8 +327,11 @@ void Bme280Read(uint8_t bmp_idx) int32_t t_fine = vart1 + vart2; float T = (t_fine * 5 + 128) >> 8; bmp_sensors[bmp_idx].bmp_temperature = T / 100.0f; - +#ifdef ESP32 + int32_t adc_P = I2cRead24(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_PRESSUREDATA,bmp_idx>>1); +#else int32_t adc_P = I2cRead24(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_PRESSUREDATA); +#endif adc_P >>= 4; int64_t var1 = ((int64_t)t_fine) - 128000; @@ -329,9 +351,11 @@ void Bme280Read(uint8_t bmp_idx) bmp_sensors[bmp_idx].bmp_pressure = (float)p / 25600.0f; if (BMP280_CHIPID == bmp_sensors[bmp_idx].bmp_type) { return; } - +#ifdef ESP32 + int32_t adc_H = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_HUMIDDATA,bmp_idx>>1); +#else int32_t adc_H = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_HUMIDDATA); - +#endif int32_t v_x1_u32r = (t_fine - ((int32_t)76800)); v_x1_u32r = (((((adc_H << 14) - (((int32_t)Bme280CalibrationData[bmp_idx].dig_H4) << 20) - (((int32_t)Bme280CalibrationData[bmp_idx].dig_H5) * v_x1_u32r)) + ((int32_t)16384)) >> 15) * @@ -362,12 +386,10 @@ struct bme68x_heatr_conf *bme_heatr_conf = nullptr; static void Bme68x_Delayus(uint32_t period, void *intf_ptr) { delayMicroseconds(period); } - int8_t Bme68x_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) { uint8_t dev_addr = *(uint8_t*)intf_ptr; return I2cReadBuffer(dev_addr, reg_addr, reg_data, (uint16_t)len); } - int8_t Bme68x_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr) { uint8_t dev_addr = *(uint8_t*)intf_ptr; return I2cWriteBuffer(dev_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len); @@ -475,14 +497,21 @@ void BmpDetect(void) if (!bmp_sensors) { return; } memset(bmp_sensors, 0, bmp_sensor_size); // Init defaults to 0 - for (uint32_t i = 0; i < BMP_MAX_SENSORS; i++) { + for (uint32_t i = 0; i < BMP_MAX_SENSORS; i++) + { +#ifdef ESP32 + uint8_t bmp_type =0; + uint8_t bus= (i>=2) ? 1 : 0; + if (!I2cSetDevice(bmp_addresses[i], bus)) { continue; } + bmp_type = I2cRead8(bmp_addresses[i], BMP_REGISTER_CHIPID, bus); +#else if (!I2cSetDevice(bmp_addresses[i])) { continue; } - uint8_t bmp_type = I2cRead8(bmp_addresses[i], BMP_REGISTER_CHIPID); + bmp_type = I2cRead8(bmp_addresses[i], BMP_REGISTER_CHIPID)); +#endif if (bmp_type) { bmp_sensors[bmp_count].bmp_address = bmp_addresses[i]; bmp_sensors[bmp_count].bmp_type = bmp_type; bmp_sensors[bmp_count].bmp_model = 0; - bool success = false; switch (bmp_type) { case BMP180_CHIPID: @@ -503,7 +532,11 @@ void BmpDetect(void) } if (success) { GetTextIndexed(bmp_sensors[bmp_count].bmp_name, sizeof(bmp_sensors[bmp_count].bmp_name), bmp_sensors[bmp_count].bmp_model, kBmpTypes); +#ifdef ESP32 + I2cSetActiveFound(bmp_sensors[bmp_count].bmp_address, bmp_sensors[bmp_count].bmp_name,bus); +#else I2cSetActiveFound(bmp_sensors[bmp_count].bmp_address, bmp_sensors[bmp_count].bmp_name); +#endif bmp_count++; } } @@ -537,12 +570,30 @@ void BmpShow(bool json) float bmp_sealevel = ConvertPressureForSeaLevel(bmp_sensors[bmp_idx].bmp_pressure); float bmp_temperature = ConvertTemp(bmp_sensors[bmp_idx].bmp_temperature); float bmp_pressure = ConvertPressure(bmp_sensors[bmp_idx].bmp_pressure); - +#ifdef ESP32 + char name[12]; + if (TasmotaGlobal.i2c_enabled_2) + { + strlcpy(name, bmp_sensors[bmp_idx].bmp_name, sizeof(bmp_sensors[bmp_idx].bmp_name)); + uint8_t bus= (bmp_idx>=2) ? 1 : 0; + if (bmp_count > 1) { + snprintf_P(name, sizeof(name), PSTR("%s%c%02X%c%1d"), name, IndexSeparator(), bmp_sensors[bmp_idx].bmp_address,IndexSeparator(),bus); // BMXXXX-XX-X + } + } + else + { + strlcpy(name, bmp_sensors[bmp_idx].bmp_name, sizeof(bmp_sensors[bmp_idx].bmp_name)); + if (bmp_count > 1) { + snprintf_P(name, sizeof(name), PSTR("%s%c%02X"), name, IndexSeparator(), bmp_sensors[bmp_idx].bmp_address); // BMXXXX-XX + } + } +#else char name[10]; strlcpy(name, bmp_sensors[bmp_idx].bmp_name, sizeof(name)); if (bmp_count > 1) { snprintf_P(name, sizeof(name), PSTR("%s%c%02X"), name, IndexSeparator(), bmp_sensors[bmp_idx].bmp_address); // BMXXXX-XX } +#endif char pressure[33]; dtostrfd(bmp_pressure, Settings->flag2.pressure_resolution, pressure); @@ -630,7 +681,12 @@ void BMP_EnterSleep(void) case BMP180_CHIPID: case BMP280_CHIPID: case BME280_CHIPID: +#ifdef ESP32 + uint8_t bus= (bmp_idx>=2) ? 1 : 0; + I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BMP_REGISTER_RESET, BMP_CMND_RESET,bus); +#else I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BMP_REGISTER_RESET, BMP_CMND_RESET); +#endif break; default: break;