Add ESP32 support for BMPxxx sensors on two I2C busses

Add ESP32 support for BMPxxx sensors on two I2C busses (#17643)
This commit is contained in:
Theo Arends 2023-01-08 17:19:08 +01:00
parent 0781192c87
commit 9073fe01c1
4 changed files with 136 additions and 235 deletions

View File

@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
- Support for PCA9632 4-channel 8-bit PWM driver as light driver by Pascal Heinrich (#17557) - Support for PCA9632 4-channel 8-bit PWM driver as light driver by Pascal Heinrich (#17557)
- Berry `bytes()` now evaluates to `false` if empty - Berry `bytes()` now evaluates to `false` if empty
- Berry ``crypto.AES_CCM`` (required by Matter protocol) - Berry ``crypto.AES_CCM`` (required by Matter protocol)
- ESP32 support for BMPxxx sensors on two I2C busses (#17643)
### Breaking Changed ### Breaking Changed

View File

@ -119,6 +119,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
- Berry crypto add ``random`` to generate series of random bytes - Berry crypto add ``random`` to generate series of random bytes
- Berry crypto add ``HKDF_HMAC_SHA256`` - Berry crypto add ``HKDF_HMAC_SHA256``
- Berry crypto add ``SPAKE2P_Matter`` for Matter support - Berry crypto add ``SPAKE2P_Matter`` for Matter support
- ESP32 support for BMPxxx sensors on two I2C busses [#17643](https://github.com/arendst/Tasmota/issues/17643)
### Breaking Changed ### Breaking Changed

View File

@ -8,15 +8,12 @@
#ifdef USE_I2C #ifdef USE_I2C
/*********************************************************************************************\ /*********************************************************************************************\
* Basic I2C routines * Basic I2C routines supporting two busses
\*********************************************************************************************/ \*********************************************************************************************/
const uint8_t I2C_RETRY_COUNTER = 3; const uint8_t I2C_RETRY_COUNTER = 3;
uint32_t i2c_active[4] = { 0 }; uint32_t i2c_active[2][4] = { 0 };
#ifdef ESP32
uint32_t i2c_active_bus2[4] = { 0 }; // ESP32 can have two I2C buses
#endif
uint32_t i2c_buffer = 0; uint32_t i2c_buffer = 0;
bool I2cBegin(int sda, int scl, uint32_t frequency = 100000); bool I2cBegin(int sda, int scl, uint32_t frequency = 100000);
@ -48,8 +45,7 @@ bool I2c2Begin(int sda, int scl, uint32_t frequency) {
} }
#endif #endif
bool I2cValidRead(uint8_t addr, uint8_t reg, uint8_t size, uint8_t bus = 0) bool I2cValidRead(uint8_t addr, uint8_t reg, uint8_t size, uint8_t bus = 0) {
{
uint8_t retry = I2C_RETRY_COUNTER; uint8_t retry = I2C_RETRY_COUNTER;
bool status = false; bool status = false;
#ifdef ESP32 #ifdef ESP32
@ -58,7 +54,6 @@ bool I2cValidRead(uint8_t addr, uint8_t reg, uint8_t size, uint8_t bus = 0)
#else #else
TwoWire & myWire = Wire; TwoWire & myWire = Wire;
#endif #endif
i2c_buffer = 0; i2c_buffer = 0;
while (!status && retry) { while (!status && retry) {
myWire.beginTransmission(addr); // start transmission to device myWire.beginTransmission(addr); // start transmission to device
@ -78,83 +73,81 @@ bool I2cValidRead(uint8_t addr, uint8_t reg, uint8_t size, uint8_t bus = 0)
return status; return status;
} }
bool I2cValidRead8(uint8_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0) bool I2cValidRead8(uint8_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0) {
{
bool status = I2cValidRead(addr, reg, 1, bus); bool status = I2cValidRead(addr, reg, 1, bus);
*data = (uint8_t)i2c_buffer; *data = (uint8_t)i2c_buffer;
return status; return status;
} }
bool I2cValidRead16(uint16_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0)
{ bool I2cValidRead16(uint16_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0) {
bool status = I2cValidRead(addr, reg, 2, bus); bool status = I2cValidRead(addr, reg, 2, bus);
*data = (uint16_t)i2c_buffer; *data = (uint16_t)i2c_buffer;
return status; return status;
} }
bool I2cValidReadS16(int16_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0)
{ bool I2cValidReadS16(int16_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0) {
bool status = I2cValidRead(addr, reg, 2, bus); bool status = I2cValidRead(addr, reg, 2, bus);
*data = (int16_t)i2c_buffer; *data = (int16_t)i2c_buffer;
return status; return status;
} }
bool I2cValidRead16LE(uint16_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0)
{ bool I2cValidRead16LE(uint16_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0) {
uint16_t ldata; uint16_t ldata;
bool status = I2cValidRead16(&ldata, addr, reg, bus); bool status = I2cValidRead16(&ldata, addr, reg, bus);
*data = (ldata >> 8) | (ldata << 8); *data = (ldata >> 8) | (ldata << 8);
return status; return status;
} }
bool I2cValidReadS16_LE(int16_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0)
{ bool I2cValidReadS16_LE(int16_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0) {
uint16_t ldata; uint16_t ldata;
bool status = I2cValidRead16LE(&ldata, addr, reg, bus); bool status = I2cValidRead16LE(&ldata, addr, reg, bus);
*data = (int16_t)ldata; *data = (int16_t)ldata;
return status; return status;
} }
bool I2cValidRead24(int32_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0)
{ bool I2cValidRead24(int32_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0) {
bool status = I2cValidRead(addr, reg, 3, bus); bool status = I2cValidRead(addr, reg, 3, bus);
*data = i2c_buffer; *data = i2c_buffer;
return status; return status;
} }
uint8_t I2cRead8(uint8_t addr, uint8_t reg, uint8_t bus = 0)
{ uint8_t I2cRead8(uint8_t addr, uint8_t reg, uint8_t bus = 0) {
I2cValidRead(addr, reg, 1, bus); I2cValidRead(addr, reg, 1, bus);
return (uint8_t)i2c_buffer; return (uint8_t)i2c_buffer;
} }
uint16_t I2cRead16(uint8_t addr, uint8_t reg, uint8_t bus = 0)
{ uint16_t I2cRead16(uint8_t addr, uint8_t reg, uint8_t bus = 0) {
I2cValidRead(addr, reg, 2, bus); I2cValidRead(addr, reg, 2, bus);
return (uint16_t)i2c_buffer; return (uint16_t)i2c_buffer;
} }
int16_t I2cReadS16(uint8_t addr, uint8_t reg, uint8_t bus = 0)
{ int16_t I2cReadS16(uint8_t addr, uint8_t reg, uint8_t bus = 0) {
I2cValidRead(addr, reg, 2, bus); I2cValidRead(addr, reg, 2, bus);
return (int16_t)i2c_buffer; return (int16_t)i2c_buffer;
} }
uint16_t I2cRead16LE(uint8_t addr, uint8_t reg, uint8_t bus = 0)
{ uint16_t I2cRead16LE(uint8_t addr, uint8_t reg, uint8_t bus = 0) {
I2cValidRead(addr, reg, 2, bus); I2cValidRead(addr, reg, 2, bus);
uint16_t temp = (uint16_t)i2c_buffer; uint16_t temp = (uint16_t)i2c_buffer;
return (temp >> 8) | (temp << 8); return (temp >> 8) | (temp << 8);
} }
int16_t I2cReadS16_LE(uint8_t addr, uint8_t reg, uint8_t bus = 0)
{ int16_t I2cReadS16_LE(uint8_t addr, uint8_t reg, uint8_t bus = 0) {
return (int16_t)I2cRead16LE(addr, reg, bus); return (int16_t)I2cRead16LE(addr, reg, bus);
} }
int32_t I2cRead24(uint8_t addr, uint8_t reg, uint8_t bus = 0)
{ int32_t I2cRead24(uint8_t addr, uint8_t reg, uint8_t bus = 0) {
I2cValidRead(addr, reg, 3, bus); I2cValidRead(addr, reg, 3, bus);
return i2c_buffer; return i2c_buffer;
} }
bool I2cWrite(uint8_t addr, uint8_t reg, uint32_t val, uint8_t size, uint8_t bus = 0) bool I2cWrite(uint8_t addr, uint8_t reg, uint32_t val, uint8_t size, uint8_t bus = 0) {
{
uint8_t x = I2C_RETRY_COUNTER; uint8_t x = I2C_RETRY_COUNTER;
#ifdef ESP32 #ifdef ESP32
if (!TasmotaGlobal.i2c_enabled_2) { bus = 0; } if (!TasmotaGlobal.i2c_enabled_2) { bus = 0; }
TwoWire & myWire = (bus == 0) ? Wire : Wire1; TwoWire & myWire = (bus == 0) ? Wire : Wire1;
#else #else
if(0!=bus) {return false;} // second I2c bus ESP32 only if (bus != 0) { return false; } // Second I2c bus ESP32 only
TwoWire & myWire = Wire; TwoWire & myWire = Wire;
#endif #endif
do { do {
@ -168,23 +161,21 @@ bool I2cWrite(uint8_t addr, uint8_t reg, uint32_t val, uint8_t size, uint8_t bus
} while (myWire.endTransmission(true) != 0 && x != 0); // end transmission } while (myWire.endTransmission(true) != 0 && x != 0); // end transmission
return (x); return (x);
} }
bool I2cWrite8(uint8_t addr, uint8_t reg, uint32_t val, uint8_t bus = 0)
{ bool I2cWrite8(uint8_t addr, uint8_t reg, uint32_t val, uint8_t bus = 0) {
return I2cWrite(addr, reg, val, 1, bus); return I2cWrite(addr, reg, val, 1, bus);
} }
bool I2cWrite16(uint8_t addr, uint8_t reg, uint32_t val, uint8_t bus = 0) bool I2cWrite16(uint8_t addr, uint8_t reg, uint32_t val, uint8_t bus = 0) {
{
return I2cWrite(addr, reg, val, 2, bus); return I2cWrite(addr, reg, val, 2, bus);
} }
bool I2cReadBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len, uint8_t bus = 0) bool I2cReadBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len, uint8_t bus = 0) {
{
#ifdef ESP32 #ifdef ESP32
if (!TasmotaGlobal.i2c_enabled_2) { bus = 0; } if (!TasmotaGlobal.i2c_enabled_2) { bus = 0; }
TwoWire & myWire = (bus == 0) ? Wire : Wire1; TwoWire & myWire = (bus == 0) ? Wire : Wire1;
#else #else
if(0!=bus) {return false;} // second I2c bus ESP32 only if (bus != 0) { return false; } // Second I2c bus ESP32 only
TwoWire & myWire = Wire; TwoWire & myWire = Wire;
#endif #endif
myWire.beginTransmission((uint8_t)addr); myWire.beginTransmission((uint8_t)addr);
@ -200,13 +191,12 @@ bool I2cReadBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len, u
return 0; return 0;
} }
int8_t I2cWriteBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len, uint8_t bus = 0) int8_t I2cWriteBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len, uint8_t bus = 0) {
{
#ifdef ESP32 #ifdef ESP32
if (!TasmotaGlobal.i2c_enabled_2) { bus = 0; } if (!TasmotaGlobal.i2c_enabled_2) { bus = 0; }
TwoWire & myWire = (bus == 0) ? Wire : Wire1; TwoWire & myWire = (bus == 0) ? Wire : Wire1;
#else #else
if(0!=bus) {return false;} // second I2c bus ESP32 only if (bus != 0) { return false; } // Second I2c bus ESP32 only
TwoWire & myWire = Wire; TwoWire & myWire = Wire;
#endif #endif
myWire.beginTransmission((uint8_t)addr); myWire.beginTransmission((uint8_t)addr);
@ -219,8 +209,7 @@ int8_t I2cWriteBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len
return 0; return 0;
} }
void I2cScan(uint8_t bus = 0) void I2cScan(uint8_t bus = 0) {
{
// Return error codes defined in twi.h and core_esp8266_si2c.c // Return error codes defined in twi.h and core_esp8266_si2c.c
// I2C_OK 0 // I2C_OK 0
// I2C_SCL_HELD_LOW 1 = SCL held low by another device, no procedure available to recover // I2C_SCL_HELD_LOW 1 = SCL held low by another device, no procedure available to recover
@ -246,7 +235,7 @@ void I2cScan(uint8_t bus = 0)
if (!TasmotaGlobal.i2c_enabled_2) { bus = 0; } if (!TasmotaGlobal.i2c_enabled_2) { bus = 0; }
TwoWire & myWire = (bus == 0) ? Wire : Wire1; TwoWire & myWire = (bus == 0) ? Wire : Wire1;
#else #else
if(0!=bus) {return;} // second I2c bus ESP32 only if (bus != 0) { return; } // Second I2c bus ESP32 only
TwoWire & myWire = Wire; TwoWire & myWire = Wire;
#endif #endif
myWire.beginTransmission(address); myWire.beginTransmission(address);
@ -267,95 +256,56 @@ void I2cScan(uint8_t bus = 0)
} }
if (any) { if (any) {
ResponseAppend_P(PSTR("\"}")); ResponseAppend_P(PSTR("\"}"));
} } else {
else {
Response_P(PSTR("{\"" D_CMND_I2CSCAN "\":\"" D_JSON_I2CSCAN_NO_DEVICES_FOUND "\"}")); Response_P(PSTR("{\"" D_CMND_I2CSCAN "\":\"" D_JSON_I2CSCAN_NO_DEVICES_FOUND "\"}"));
} }
} }
void I2cResetActive(uint32_t addr, uint32_t count = 1, uint8_t bus = 0) void I2cResetActive(uint32_t addr, uint32_t count = 1, uint8_t bus = 0) {
{ #ifdef ESP8266
bus = 0;
#endif
addr &= 0x7F; // Max I2C address is 127 addr &= 0x7F; // Max I2C address is 127
count &= 0x7F; // Max 4 x 32 bits available count &= 0x7F; // Max 4 x 32 bits available
while (count-- && (addr < 128)) while (count-- && (addr < 128)) {
{ i2c_active[bus][addr / 32] &= ~(1 << (addr % 32));
#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++; addr++;
} }
// AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: Active %08X,%08X,%08X,%08X"), i2c_active[0], i2c_active[1], i2c_active[2], i2c_active[3]); // AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: Active %08X,%08X,%08X,%08X"), i2c_active[bus][0], i2c_active[bus][1], i2c_active[bus][2], i2c_active[bus][3]);
} }
void I2cSetActive(uint32_t addr, uint32_t count = 1, uint8_t bus = 0) void I2cSetActive(uint32_t addr, uint32_t count = 1, uint8_t bus = 0) {
{ #ifdef ESP8266
bus = 0;
#endif
addr &= 0x7F; // Max I2C address is 127 addr &= 0x7F; // Max I2C address is 127
count &= 0x7F; // Max 4 x 32 bits available count &= 0x7F; // Max 4 x 32 bits available
while (count-- && (addr < 128)) while (count-- && (addr < 128)) {
{ i2c_active[bus][addr / 32] |= (1 << (addr % 32));
#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++; addr++;
} }
// AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: Active %08X,%08X,%08X,%08X"), i2c_active[0], i2c_active[1], i2c_active[2], i2c_active[3]); // AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: Active %08X,%08X,%08X,%08X"), i2c_active[bus][0], i2c_active[bus][1], i2c_active[bus][2], i2c_active[bus][3]);
} }
void I2cSetActiveFound(uint32_t addr, const char *types, uint8_t bus = 0) void I2cSetActiveFound(uint32_t addr, const char *types, uint8_t bus = 0) {
{
I2cSetActive(addr, bus); I2cSetActive(addr, bus);
#ifdef ESP32 #ifdef ESP32
if (0 == bus) { if (1 == bus) {
AddLog(LOG_LEVEL_INFO, S_LOG_I2C_FOUND_AT, types, addr);
} else {
AddLog(LOG_LEVEL_INFO, S_LOG_I2C_FOUND_AT_PORT, types, addr, bus); AddLog(LOG_LEVEL_INFO, S_LOG_I2C_FOUND_AT_PORT, types, addr, bus);
} } else
#else
AddLog(LOG_LEVEL_INFO, S_LOG_I2C_FOUND_AT, types, addr);
#endif // ESP32 #endif // ESP32
} AddLog(LOG_LEVEL_INFO, S_LOG_I2C_FOUND_AT, types, 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_bus2[addr / 32] & (1 << (addr % 32))) {
return true;
}
return false;
#endif
} }
bool I2cSetDevice(uint32_t addr, uint8_t bus = 0) bool I2cActive(uint32_t addr, uint8_t bus = 0) {
{ #ifdef ESP8266
bus = 0;
#endif
addr &= 0x7F; // Max I2C address is 127
return (i2c_active[bus][addr / 32] & (1 << (addr % 32)));
}
bool I2cSetDevice(uint32_t addr, uint8_t bus = 0) {
#ifdef ESP32 #ifdef ESP32
if (!TasmotaGlobal.i2c_enabled_2) { bus = 0; } if (!TasmotaGlobal.i2c_enabled_2) { bus = 0; }
TwoWire & myWire = (bus == 0) ? Wire : Wire1; TwoWire & myWire = (bus == 0) ? Wire : Wire1;
@ -371,7 +321,7 @@ bool I2cSetDevice(uint32_t addr, uint8_t bus = 0)
uint32_t err = myWire.endTransmission(); uint32_t err = myWire.endTransmission();
if (err && (err != 2)) { if (err && (err != 2)) {
#ifdef ESP32 #ifdef ESP32
AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: Error %d at 0x%02x bus &d"), err, addr,bus); AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: Error %d at 0x%02x bus %d"), err, addr, bus);
#else #else
AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: Error %d at 0x%02x"), err, addr); AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: Error %d at 0x%02x"), err, addr);
#endif #endif

View File

@ -49,7 +49,7 @@
#define BMP_CMND_RESET 0xB6 // I2C Parameter for RESET to put BMP into reset state #define BMP_CMND_RESET 0xB6 // I2C Parameter for RESET to put BMP into reset state
#ifdef ESP32 #ifdef ESP32
#define BMP_MAX_SENSORS 4 #define BMP_MAX_SENSORS 4 // 2 busses
#else #else
#define BMP_MAX_SENSORS 2 #define BMP_MAX_SENSORS 2
#endif #endif
@ -114,8 +114,7 @@ typedef struct {
bmp180_cal_data_t *bmp180_cal_data = nullptr; bmp180_cal_data_t *bmp180_cal_data = nullptr;
bool Bmp180Calibration(uint8_t bmp_idx) bool Bmp180Calibration(uint8_t bmp_idx) {
{
if (!bmp180_cal_data) { if (!bmp180_cal_data) {
bmp180_cal_data = (bmp180_cal_data_t*)malloc(BMP_MAX_SENSORS * sizeof(bmp180_cal_data_t)); bmp180_cal_data = (bmp180_cal_data_t*)malloc(BMP_MAX_SENSORS * sizeof(bmp180_cal_data_t));
} }
@ -160,33 +159,21 @@ bool Bmp180Calibration(uint8_t bmp_idx)
return true; return true;
} }
void Bmp180Read(uint8_t bmp_idx) void Bmp180Read(uint8_t bmp_idx) {
{
if (!bmp180_cal_data) { return; } 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 uint8_t bus = bmp_idx >>1; // First two BMP's at bus 0, additional at bus 1
I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BMP180_REG_CONTROL, BMP180_TEMPERATURE, bus); I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BMP180_REG_CONTROL, BMP180_TEMPERATURE, bus);
delay(5); // 5ms conversion time delay(5); // 5ms conversion time
int ut = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_REG_RESULT, bus); 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 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 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; int32_t bmp180_b5 = xt1 + xt2;
bmp_sensors[bmp_idx].bmp_temperature = ((bmp180_b5 + 8) >> 4) / 10.0f; 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 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 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); 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); up >>= (8 - BMP180_OSS);
int32_t b6 = bmp180_b5 - 4000; int32_t b6 = bmp180_b5 - 4000;
@ -270,8 +257,7 @@ typedef struct {
Bme280CalibrationData_t *Bme280CalibrationData = nullptr; Bme280CalibrationData_t *Bme280CalibrationData = nullptr;
bool Bmx280Calibrate(uint8_t bmp_idx) bool Bmx280Calibrate(uint8_t bmp_idx) {
{
// if (I2cRead8(bmp_address, BMP_REGISTER_CHIPID) != BME280_CHIPID) return false; // if (I2cRead8(bmp_address, BMP_REGISTER_CHIPID) != BME280_CHIPID) return false;
if (!Bme280CalibrationData) { if (!Bme280CalibrationData) {
@ -279,7 +265,7 @@ bool Bmx280Calibrate(uint8_t bmp_idx)
} }
if (!Bme280CalibrationData) { return false; } if (!Bme280CalibrationData) { return false; }
uint8_t bus= (bmp_idx>=2) ? 1 : 0; // first two BMP's at bus 0, additional at bus 1 (ESP32 32 only) uint8_t bus = bmp_idx >>1; // First two BMP's at bus 0, additional at bus 1
Bme280CalibrationData[bmp_idx].dig_T1 = I2cRead16LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_T1, bus); 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_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_T3 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_T3, bus);
@ -310,15 +296,11 @@ bool Bmx280Calibrate(uint8_t bmp_idx)
return true; return true;
} }
void Bme280Read(uint8_t bmp_idx) void Bme280Read(uint8_t bmp_idx) {
{
if (!Bme280CalibrationData) { return; } if (!Bme280CalibrationData) { return; }
#ifdef ESP32 uint8_t bus = bmp_idx >>1; // First two BMP's at bus 0, additional at bus 1
int32_t adc_T = I2cRead24(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_TEMPDATA,bmp_idx>>1); int32_t adc_T = I2cRead24(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_TEMPDATA, bus);
#else
int32_t adc_T = I2cRead24(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_TEMPDATA);
#endif
adc_T >>= 4; 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; int32_t vart1 = ((((adc_T >> 3) - ((int32_t)Bme280CalibrationData[bmp_idx].dig_T1 << 1))) * ((int32_t)Bme280CalibrationData[bmp_idx].dig_T2)) >> 11;
@ -327,11 +309,8 @@ void Bme280Read(uint8_t bmp_idx)
int32_t t_fine = vart1 + vart2; int32_t t_fine = vart1 + vart2;
float T = (t_fine * 5 + 128) >> 8; float T = (t_fine * 5 + 128) >> 8;
bmp_sensors[bmp_idx].bmp_temperature = T / 100.0f; 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); int32_t adc_P = I2cRead24(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_PRESSUREDATA, bus);
#else
int32_t adc_P = I2cRead24(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_PRESSUREDATA);
#endif
adc_P >>= 4; adc_P >>= 4;
int64_t var1 = ((int64_t)t_fine) - 128000; int64_t var1 = ((int64_t)t_fine) - 128000;
@ -351,11 +330,9 @@ void Bme280Read(uint8_t bmp_idx)
bmp_sensors[bmp_idx].bmp_pressure = (float)p / 25600.0f; bmp_sensors[bmp_idx].bmp_pressure = (float)p / 25600.0f;
if (BMP280_CHIPID == bmp_sensors[bmp_idx].bmp_type) { return; } 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); int32_t adc_H = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_HUMIDDATA, bus);
#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)); int32_t v_x1_u32r = (t_fine - ((int32_t)76800));
v_x1_u32r = (((((adc_H << 14) - (((int32_t)Bme280CalibrationData[bmp_idx].dig_H4) << 20) - 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) * (((int32_t)Bme280CalibrationData[bmp_idx].dig_H5) * v_x1_u32r)) + ((int32_t)16384)) >> 15) *
@ -440,8 +417,7 @@ bool Bme680Init(uint8_t bmp_idx) {
return true; return true;
} }
void Bme680Read(uint8_t bmp_idx) void Bme680Read(uint8_t bmp_idx) {
{
if (!bme_dev) { return; } if (!bme_dev) { return; }
int8_t rslt = BME68X_OK; int8_t rslt = BME68X_OK;
@ -488,8 +464,7 @@ void Bme680Read(uint8_t bmp_idx)
/********************************************************************************************/ /********************************************************************************************/
void BmpDetect(void) void BmpDetect(void) {
{
int bmp_sensor_size = BMP_MAX_SENSORS * sizeof(bmp_sensors_t); int bmp_sensor_size = BMP_MAX_SENSORS * sizeof(bmp_sensors_t);
if (!bmp_sensors) { if (!bmp_sensors) {
bmp_sensors = (bmp_sensors_t*)malloc(bmp_sensor_size); bmp_sensors = (bmp_sensors_t*)malloc(bmp_sensor_size);
@ -498,19 +473,14 @@ void BmpDetect(void)
memset(bmp_sensors, 0, bmp_sensor_size); // Init defaults to 0 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++) {
uint8_t bmp_type = 0; uint8_t bus = i >>1;
#ifdef ESP32
uint8_t bus = (i>=2) ? 1 : 0;
if (!I2cSetDevice(bmp_addresses[i], bus)) { continue; } if (!I2cSetDevice(bmp_addresses[i], bus)) { continue; }
bmp_type = I2cRead8(bmp_addresses[i], BMP_REGISTER_CHIPID, bus); uint8_t bmp_type = I2cRead8(bmp_addresses[i], BMP_REGISTER_CHIPID, bus);
#else
if (!I2cSetDevice(bmp_addresses[i])) { continue; }
bmp_type = I2cRead8(bmp_addresses[i], BMP_REGISTER_CHIPID);
#endif
if (bmp_type) { if (bmp_type) {
bmp_sensors[bmp_count].bmp_address = bmp_addresses[i]; bmp_sensors[bmp_count].bmp_address = bmp_addresses[i];
bmp_sensors[bmp_count].bmp_type = bmp_type; bmp_sensors[bmp_count].bmp_type = bmp_type;
bmp_sensors[bmp_count].bmp_model = 0; bmp_sensors[bmp_count].bmp_model = 0;
bool success = false; bool success = false;
switch (bmp_type) { switch (bmp_type) {
case BMP180_CHIPID: case BMP180_CHIPID:
@ -531,19 +501,14 @@ void BmpDetect(void)
} }
if (success) { if (success) {
GetTextIndexed(bmp_sensors[bmp_count].bmp_name, sizeof(bmp_sensors[bmp_count].bmp_name), bmp_sensors[bmp_count].bmp_model, kBmpTypes); 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); 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++; bmp_count++;
} }
} }
} }
} }
void BmpRead(void) void BmpRead(void) {
{
for (uint32_t bmp_idx = 0; bmp_idx < bmp_count; bmp_idx++) { for (uint32_t bmp_idx = 0; bmp_idx < bmp_count; bmp_idx++) {
switch (bmp_sensors[bmp_idx].bmp_type) { switch (bmp_sensors[bmp_idx].bmp_type) {
case BMP180_CHIPID: case BMP180_CHIPID:
@ -569,30 +534,20 @@ void BmpShow(bool json)
float bmp_sealevel = ConvertPressureForSeaLevel(bmp_sensors[bmp_idx].bmp_pressure); float bmp_sealevel = ConvertPressureForSeaLevel(bmp_sensors[bmp_idx].bmp_pressure);
float bmp_temperature = ConvertTemp(bmp_sensors[bmp_idx].bmp_temperature); float bmp_temperature = ConvertTemp(bmp_sensors[bmp_idx].bmp_temperature);
float bmp_pressure = ConvertPressure(bmp_sensors[bmp_idx].bmp_pressure); float bmp_pressure = ConvertPressure(bmp_sensors[bmp_idx].bmp_pressure);
#ifdef ESP32
char name[12]; char name[12];
if (TasmotaGlobal.i2c_enabled_2)
{
strlcpy(name, bmp_sensors[bmp_idx].bmp_name, sizeof(bmp_sensors[bmp_idx].bmp_name)); strlcpy(name, bmp_sensors[bmp_idx].bmp_name, sizeof(bmp_sensors[bmp_idx].bmp_name));
uint8_t bus= (bmp_idx>=2) ? 1 : 0; #ifdef ESP32
if (TasmotaGlobal.i2c_enabled_2) {
uint8_t bus = bmp_idx >>1;
if (bmp_count > 1) { 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 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
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 #endif
if (bmp_count > 1) {
snprintf_P(name, sizeof(name), PSTR("%s%c%02X"), name, IndexSeparator(), bmp_sensors[bmp_idx].bmp_address); // BMXXXX-XX
}
char pressure[33]; char pressure[33];
dtostrfd(bmp_pressure, Settings->flag2.pressure_resolution, pressure); dtostrfd(bmp_pressure, Settings->flag2.pressure_resolution, pressure);
@ -672,20 +627,14 @@ void BmpShow(bool json)
#ifdef USE_DEEPSLEEP #ifdef USE_DEEPSLEEP
void BMP_EnterSleep(void) void BMP_EnterSleep(void) {
{
if (DeepSleepEnabled()) { if (DeepSleepEnabled()) {
for (uint32_t bmp_idx = 0; bmp_idx < bmp_count; bmp_idx++) { for (uint32_t bmp_idx = 0; bmp_idx < bmp_count; bmp_idx++) {
switch (bmp_sensors[bmp_idx].bmp_type) { switch (bmp_sensors[bmp_idx].bmp_type) {
case BMP180_CHIPID: case BMP180_CHIPID:
case BMP280_CHIPID: case BMP280_CHIPID:
case BME280_CHIPID: case BME280_CHIPID:
#ifdef ESP32 I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BMP_REGISTER_RESET, BMP_CMND_RESET, bmp_idx >>1);
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; break;
default: default:
break; break;