From 43d024fe429c5f519fb50f80fe75c8d184c64aea Mon Sep 17 00:00:00 2001 From: Michael Bisbjerg Date: Fri, 10 May 2024 22:43:55 +0200 Subject: [PATCH 1/3] Make BME280 usermod i2c address changeable --- usermods/BME280_v2/README.md | 1 + usermods/BME280_v2/usermod_bme280.h | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/usermods/BME280_v2/README.md b/usermods/BME280_v2/README.md index 0a4afbf1f4..51e93336d4 100644 --- a/usermods/BME280_v2/README.md +++ b/usermods/BME280_v2/README.md @@ -7,6 +7,7 @@ This Usermod is designed to read a `BME280` or `BMP280` sensor and output the fo - Dew Point (`BME280` only) Configuration is performed via the Usermod menu. There are no parameters to set in code! The following settings can be configured in the Usermod Menu: +- The i2c address in decimal. Set it to either 118 (0x76, the default) or 119 (0x77). **Requires reboot**. - Temperature Decimals (number of decimal places to output) - Humidity Decimals - Pressure Decimals diff --git a/usermods/BME280_v2/usermod_bme280.h b/usermods/BME280_v2/usermod_bme280.h index ae6eba89d6..0040c5efa8 100644 --- a/usermods/BME280_v2/usermod_bme280.h +++ b/usermods/BME280_v2/usermod_bme280.h @@ -28,6 +28,7 @@ class UsermodBME280 : public Usermod bool UseCelsius = true; // Use Celsius for Reporting bool HomeAssistantDiscovery = false; // Publish Home Assistant Device Information bool enabled = true; + BME280I2C::I2CAddr i2cAddress = BME280I2C::I2CAddr_0x76; // Default i2c address for BME280 // set the default pins based on the architecture, these get overridden by Usermod menu settings #ifdef ESP8266 @@ -48,7 +49,7 @@ class UsermodBME280 : public Usermod BME280I2C::I2CAddr_0x76 // I2C address. I2C specific. Default 0x76 }; - BME280I2C bme{settings}; + BME280I2C bme; uint8_t sensorType; @@ -186,6 +187,9 @@ class UsermodBME280 : public Usermod { if (i2c_scl<0 || i2c_sda<0) { enabled = false; sensorType = 0; return; } + settings.bme280Addr = i2cAddress; + bme = BME280I2C(settings); + if (!bme.begin()) { sensorType = 0; @@ -399,6 +403,7 @@ class UsermodBME280 : public Usermod { JsonObject top = root.createNestedObject(FPSTR(_name)); top[FPSTR(_enabled)] = enabled; + top[F("I2CAddress")] = i2cAddress; top[F("TemperatureDecimals")] = TemperatureDecimals; top[F("HumidityDecimals")] = HumidityDecimals; top[F("PressureDecimals")] = PressureDecimals; @@ -426,6 +431,10 @@ class UsermodBME280 : public Usermod configComplete &= getJsonValue(top[FPSTR(_enabled)], enabled); // A 3-argument getJsonValue() assigns the 3rd argument as a default value if the Json value is missing + uint8_t tmpI2cAddress; + configComplete &= getJsonValue(top[F("I2CAddress")], tmpI2cAddress, 0x76); + i2cAddress = static_cast(tmpI2cAddress); + configComplete &= getJsonValue(top[F("TemperatureDecimals")], TemperatureDecimals, 1); configComplete &= getJsonValue(top[F("HumidityDecimals")], HumidityDecimals, 0); configComplete &= getJsonValue(top[F("PressureDecimals")], PressureDecimals, 0); From bd10a9aa26e21ddef1e900a65cac4383b2cbdd2f Mon Sep 17 00:00:00 2001 From: Michael Bisbjerg Date: Mon, 13 May 2024 18:35:02 +0200 Subject: [PATCH 2/3] Change BME280I2C to be reused between configs --- usermods/BME280_v2/README.md | 2 +- usermods/BME280_v2/usermod_bme280.h | 80 +++++++++++++++++------------ 2 files changed, 49 insertions(+), 33 deletions(-) diff --git a/usermods/BME280_v2/README.md b/usermods/BME280_v2/README.md index 51e93336d4..a4fc229a38 100644 --- a/usermods/BME280_v2/README.md +++ b/usermods/BME280_v2/README.md @@ -7,7 +7,7 @@ This Usermod is designed to read a `BME280` or `BMP280` sensor and output the fo - Dew Point (`BME280` only) Configuration is performed via the Usermod menu. There are no parameters to set in code! The following settings can be configured in the Usermod Menu: -- The i2c address in decimal. Set it to either 118 (0x76, the default) or 119 (0x77). **Requires reboot**. +- The i2c address in decimal. Set it to either 118 (0x76, the default) or 119 (0x77). - Temperature Decimals (number of decimal places to output) - Humidity Decimals - Pressure Decimals diff --git a/usermods/BME280_v2/usermod_bme280.h b/usermods/BME280_v2/usermod_bme280.h index 0040c5efa8..1bb9d460f9 100644 --- a/usermods/BME280_v2/usermod_bme280.h +++ b/usermods/BME280_v2/usermod_bme280.h @@ -28,7 +28,6 @@ class UsermodBME280 : public Usermod bool UseCelsius = true; // Use Celsius for Reporting bool HomeAssistantDiscovery = false; // Publish Home Assistant Device Information bool enabled = true; - BME280I2C::I2CAddr i2cAddress = BME280I2C::I2CAddr_0x76; // Default i2c address for BME280 // set the default pins based on the architecture, these get overridden by Usermod menu settings #ifdef ESP8266 @@ -49,7 +48,7 @@ class UsermodBME280 : public Usermod BME280I2C::I2CAddr_0x76 // I2C address. I2C specific. Default 0x76 }; - BME280I2C bme; + BME280I2C bme{settings}; uint8_t sensorType; @@ -182,36 +181,38 @@ class UsermodBME280 : public Usermod } } -public: - void setup() - { - if (i2c_scl<0 || i2c_sda<0) { enabled = false; sensorType = 0; return; } - - settings.bme280Addr = i2cAddress; - bme = BME280I2C(settings); - - if (!bme.begin()) - { - sensorType = 0; - DEBUG_PRINTLN(F("Could not find BME280 I2C sensor!")); - } - else + void initializeBmeComms() { - switch (bme.chipModel()) + if (!bme.begin()) { - case BME280::ChipModel_BME280: - sensorType = 1; - DEBUG_PRINTLN(F("Found BME280 sensor! Success.")); - break; - case BME280::ChipModel_BMP280: - sensorType = 2; - DEBUG_PRINTLN(F("Found BMP280 sensor! No Humidity available.")); - break; - default: sensorType = 0; - DEBUG_PRINTLN(F("Found UNKNOWN sensor! Error!")); + DEBUG_PRINTLN(F("Could not find BME280 I2C sensor!")); + } + else + { + switch (bme.chipModel()) + { + case BME280::ChipModel_BME280: + sensorType = 1; + DEBUG_PRINTLN(F("Found BME280 sensor! Success.")); + break; + case BME280::ChipModel_BMP280: + sensorType = 2; + DEBUG_PRINTLN(F("Found BMP280 sensor! No Humidity available.")); + break; + default: + sensorType = 0; + DEBUG_PRINTLN(F("Found UNKNOWN sensor! Error!")); + } } } + +public: + void setup() + { + if (i2c_scl<0 || i2c_sda<0) { enabled = false; sensorType = 0; return; } + + initializeBmeComms(); initDone=true; } @@ -369,7 +370,6 @@ class UsermodBME280 : public Usermod } else if (sensorType==2) //BMP280 { - JsonArray temperature_json = user.createNestedArray(F("Temperature")); JsonArray pressure_json = user.createNestedArray(F("Pressure")); temperature_json.add(roundf(sensorTemperature * powf(10, TemperatureDecimals)) / powf(10, TemperatureDecimals)); @@ -403,7 +403,7 @@ class UsermodBME280 : public Usermod { JsonObject top = root.createNestedObject(FPSTR(_name)); top[FPSTR(_enabled)] = enabled; - top[F("I2CAddress")] = i2cAddress; + top[F("I2CAddress")] = static_cast(settings.bme280Addr); top[F("TemperatureDecimals")] = TemperatureDecimals; top[F("HumidityDecimals")] = HumidityDecimals; top[F("PressureDecimals")] = PressureDecimals; @@ -433,8 +433,6 @@ class UsermodBME280 : public Usermod // A 3-argument getJsonValue() assigns the 3rd argument as a default value if the Json value is missing uint8_t tmpI2cAddress; configComplete &= getJsonValue(top[F("I2CAddress")], tmpI2cAddress, 0x76); - i2cAddress = static_cast(tmpI2cAddress); - configComplete &= getJsonValue(top[F("TemperatureDecimals")], TemperatureDecimals, 1); configComplete &= getJsonValue(top[F("HumidityDecimals")], HumidityDecimals, 0); configComplete &= getJsonValue(top[F("PressureDecimals")], PressureDecimals, 0); @@ -444,13 +442,31 @@ class UsermodBME280 : public Usermod configComplete &= getJsonValue(top[F("UseCelsius")], UseCelsius, true); configComplete &= getJsonValue(top[F("HomeAssistantDiscovery")], HomeAssistantDiscovery, false); + settings.bme280Addr = static_cast(tmpI2cAddress); + bme.setSettings(settings); + DEBUG_PRINT(FPSTR(_name)); if (!initDone) { // first run: reading from cfg.json DEBUG_PRINTLN(F(" config loaded.")); } else { - DEBUG_PRINTLN(F(" config (re)loaded.")); // changing parameters from settings page + DEBUG_PRINTLN(F(" config (re)loaded.")); + + // Reset all known values + sensorType = 0; + sensorTemperature = 0; + sensorHumidity = 0; + sensorHeatIndex = 0; + sensorDewPoint = 0; + sensorPressure = 0; + lastTemperature = 0; + lastHumidity = 0; + lastHeatIndex = 0; + lastDewPoint = 0; + lastPressure = 0; + + initializeBmeComms(); } return configComplete; From 60075f6e8c18dcf96dc7a6caf6ed80f5bb805a52 Mon Sep 17 00:00:00 2001 From: Michael Bisbjerg Date: Mon, 13 May 2024 20:22:31 +0200 Subject: [PATCH 3/3] Avoid storing the settings of bme280 globally --- usermods/BME280_v2/usermod_bme280.h | 38 ++++++++++++++--------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/usermods/BME280_v2/usermod_bme280.h b/usermods/BME280_v2/usermod_bme280.h index 1bb9d460f9..9168f42291 100644 --- a/usermods/BME280_v2/usermod_bme280.h +++ b/usermods/BME280_v2/usermod_bme280.h @@ -24,6 +24,7 @@ class UsermodBME280 : public Usermod uint8_t PressureDecimals = 0; // Number of decimal places in published pressure values uint16_t TemperatureInterval = 5; // Interval to measure temperature (and humidity, dew point if available) in seconds uint16_t PressureInterval = 300; // Interval to measure pressure in seconds + BME280I2C::I2CAddr I2CAddress = BME280I2C::I2CAddr_0x76; // i2c address, defaults to 0x76 bool PublishAlways = false; // Publish values even when they have not changed bool UseCelsius = true; // Use Celsius for Reporting bool HomeAssistantDiscovery = false; // Publish Home Assistant Device Information @@ -35,20 +36,7 @@ class UsermodBME280 : public Usermod #endif bool initDone = false; - // BME280 sensor settings - BME280I2C::Settings settings{ - BME280::OSR_X16, // Temperature oversampling x16 - BME280::OSR_X16, // Humidity oversampling x16 - BME280::OSR_X16, // Pressure oversampling x16 - // Defaults - BME280::Mode_Forced, - BME280::StandbyTime_1000ms, - BME280::Filter_Off, - BME280::SpiEnable_False, - BME280I2C::I2CAddr_0x76 // I2C address. I2C specific. Default 0x76 - }; - - BME280I2C bme{settings}; + BME280I2C bme; uint8_t sensorType; @@ -183,6 +171,19 @@ class UsermodBME280 : public Usermod void initializeBmeComms() { + BME280I2C::Settings settings{ + BME280::OSR_X16, // Temperature oversampling x16 + BME280::OSR_X16, // Humidity oversampling x16 + BME280::OSR_X16, // Pressure oversampling x16 + BME280::Mode_Forced, + BME280::StandbyTime_1000ms, + BME280::Filter_Off, + BME280::SpiEnable_False, + I2CAddress + }; + + bme.setSettings(settings); + if (!bme.begin()) { sensorType = 0; @@ -213,7 +214,7 @@ class UsermodBME280 : public Usermod if (i2c_scl<0 || i2c_sda<0) { enabled = false; sensorType = 0; return; } initializeBmeComms(); - initDone=true; + initDone = true; } void loop() @@ -403,7 +404,7 @@ class UsermodBME280 : public Usermod { JsonObject top = root.createNestedObject(FPSTR(_name)); top[FPSTR(_enabled)] = enabled; - top[F("I2CAddress")] = static_cast(settings.bme280Addr); + top[F("I2CAddress")] = static_cast(I2CAddress); top[F("TemperatureDecimals")] = TemperatureDecimals; top[F("HumidityDecimals")] = HumidityDecimals; top[F("PressureDecimals")] = PressureDecimals; @@ -433,6 +434,8 @@ class UsermodBME280 : public Usermod // A 3-argument getJsonValue() assigns the 3rd argument as a default value if the Json value is missing uint8_t tmpI2cAddress; configComplete &= getJsonValue(top[F("I2CAddress")], tmpI2cAddress, 0x76); + I2CAddress = static_cast(tmpI2cAddress); + configComplete &= getJsonValue(top[F("TemperatureDecimals")], TemperatureDecimals, 1); configComplete &= getJsonValue(top[F("HumidityDecimals")], HumidityDecimals, 0); configComplete &= getJsonValue(top[F("PressureDecimals")], PressureDecimals, 0); @@ -442,9 +445,6 @@ class UsermodBME280 : public Usermod configComplete &= getJsonValue(top[F("UseCelsius")], UseCelsius, true); configComplete &= getJsonValue(top[F("HomeAssistantDiscovery")], HomeAssistantDiscovery, false); - settings.bme280Addr = static_cast(tmpI2cAddress); - bme.setSettings(settings); - DEBUG_PRINT(FPSTR(_name)); if (!initDone) { // first run: reading from cfg.json