diff --git a/RELEASENOTES.md b/RELEASENOTES.md index bf2983136..f0f2c1e69 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -71,3 +71,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add Zigbee options to ``ZbSend`` to write and report attributes - Add ``CpuFrequency`` to ``status 2`` - Add ``FlashFrequency`` to ``status 4`` +- Add support for up to two BH1750 sensors controlled by commands ``BH1750Resolution`` and ``BH1750MTime`` (#8139) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 8e48a6302..60563404f 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -14,6 +14,7 @@ - Add Zigbee options to ``ZbSend`` to write and report attributes - Add ``CpuFrequency`` to ``status 2`` - Add ``FlashFrequency`` to ``status 4`` +- Add support for up to two BH1750 sensors controlled by commands ``BH1750Resolution`` and ``BH1750MTime`` (#8139) ### 8.3.1.1 20200518 diff --git a/tasmota/settings.h b/tasmota/settings.h index accf21842..0ad7a3533 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -232,9 +232,8 @@ typedef union { struct { uint8_t spare0 : 1; uint8_t spare1 : 1; - uint8_t spare2 : 1; - uint8_t spare3 : 1; - uint8_t bh1750_resolution : 2; // Sensor10 1,2,3 + uint8_t bh1750_2_resolution : 2; + uint8_t bh1750_1_resolution : 2; // Sensor10 1,2,3 uint8_t hx711_json_weight_change : 1; // Sensor34 8,x - Enable JSON message on weight change uint8_t mhz19b_abc_disable : 1; // Disable ABC (Automatic Baseline Correction for MHZ19(B) (0 = Enabled (default), 1 = Disabled with Sensor15 command) }; diff --git a/tasmota/xsns_10_bh1750.ino b/tasmota/xsns_10_bh1750.ino index a098166df..7af8e3960 100644 --- a/tasmota/xsns_10_bh1750.ino +++ b/tasmota/xsns_10_bh1750.ino @@ -22,6 +22,11 @@ /*********************************************************************************************\ * BH1750 - Ambient Light Intensity * + * Bh1750Resolution1 0..2 - Set BH1750 1 resolution mode + * Bh1750Resolution2 0..2 - Set BH1750 2 resolution mode + * Bh1750MTime1 30..255 - Set BH1750 1 MT register + * Bh1750MTime2 30..255 - Set BH1750 2 MT register + * * I2C Address: 0x23 or 0x5C \*********************************************************************************************/ @@ -38,119 +43,148 @@ #define BH1750_MEASUREMENT_TIME_HIGH 0x40 // Measurement Time register high 3 bits #define BH1750_MEASUREMENT_TIME_LOW 0x60 // Measurement Time register low 5 bits -struct BH1750DATA { - uint8_t address; +#define D_PRFX_BH1750 "Bh1750" +#define D_CMND_RESOLUTION "Resolution" +#define D_CMND_MTREG "MTime" + +const char kBh1750Commands[] PROGMEM = D_PRFX_BH1750 "|" // Prefix + D_CMND_RESOLUTION "|" D_CMND_MTREG ; + +void (* const Bh1750Command[])(void) PROGMEM = { + &CmndBh1750Resolution, &CmndBh1750MTime }; + +struct { uint8_t addresses[2] = { BH1750_ADDR1, BH1750_ADDR2 }; uint8_t resolution[3] = { BH1750_CONTINUOUS_HIGH_RES_MODE, BH1750_CONTINUOUS_HIGH_RES_MODE2, BH1750_CONTINUOUS_LOW_RES_MODE }; - uint8_t type = 0; - uint8_t valid = 0; - uint8_t mtreg = 69; // Default Measurement Time - uint16_t illuminance = 0; + uint8_t count = 0; char types[7] = "BH1750"; } Bh1750; +struct { + uint8_t address; + uint8_t valid = 0; + uint8_t mtreg = 69; // Default Measurement Time + uint16_t illuminance = 0; +} Bh1750_sensors[2]; + /*********************************************************************************************/ -bool Bh1750SetResolution(void) -{ - Wire.beginTransmission(Bh1750.address); - Wire.write(Bh1750.resolution[Settings.SensorBits1.bh1750_resolution]); +uint8_t Bh1750Resolution(uint32_t sensor_index) { + uint8_t settings_resolution = Settings.SensorBits1.bh1750_1_resolution; + if (1 == sensor_index) { + settings_resolution = Settings.SensorBits1.bh1750_2_resolution; + } + return settings_resolution; +} + +bool Bh1750SetResolution(uint32_t sensor_index) { + Wire.beginTransmission(Bh1750_sensors[sensor_index].address); + Wire.write(Bh1750.resolution[Bh1750Resolution(sensor_index)]); return (!Wire.endTransmission()); } -bool Bh1750SetMTreg(void) -{ - Wire.beginTransmission(Bh1750.address); - uint8_t data = BH1750_MEASUREMENT_TIME_HIGH | ((Bh1750.mtreg >> 5) & 0x07); +bool Bh1750SetMTreg(uint32_t sensor_index) { + Wire.beginTransmission(Bh1750_sensors[sensor_index].address); + uint8_t data = BH1750_MEASUREMENT_TIME_HIGH | ((Bh1750_sensors[sensor_index].mtreg >> 5) & 0x07); Wire.write(data); if (Wire.endTransmission()) { return false; } - Wire.beginTransmission(Bh1750.address); - data = BH1750_MEASUREMENT_TIME_LOW | (Bh1750.mtreg & 0x1F); + Wire.beginTransmission(Bh1750_sensors[sensor_index].address); + data = BH1750_MEASUREMENT_TIME_LOW | (Bh1750_sensors[sensor_index].mtreg & 0x1F); Wire.write(data); if (Wire.endTransmission()) { return false; } - return Bh1750SetResolution(); + return Bh1750SetResolution(sensor_index); } -bool Bh1750Read(void) -{ - if (Bh1750.valid) { Bh1750.valid--; } +bool Bh1750Read(uint32_t sensor_index) { + if (Bh1750_sensors[sensor_index].valid) { Bh1750_sensors[sensor_index].valid--; } + + if (2 != Wire.requestFrom(Bh1750_sensors[sensor_index].address, (uint8_t)2)) { return false; } - if (2 != Wire.requestFrom(Bh1750.address, (uint8_t)2)) { return false; } float illuminance = (Wire.read() << 8) | Wire.read(); - illuminance /= (1.2 * (69 / (float)Bh1750.mtreg)); - if (1 == Settings.SensorBits1.bh1750_resolution) { + illuminance /= (1.2 * (69 / (float)Bh1750_sensors[sensor_index].mtreg)); + if (1 == Bh1750Resolution(sensor_index)) { illuminance /= 2; } - Bh1750.illuminance = illuminance; + Bh1750_sensors[sensor_index].illuminance = illuminance; - Bh1750.valid = SENSOR_MAX_MISS; + Bh1750_sensors[sensor_index].valid = SENSOR_MAX_MISS; return true; } /********************************************************************************************/ -void Bh1750Detect(void) -{ +void Bh1750Detect(void) { for (uint32_t i = 0; i < sizeof(Bh1750.addresses); i++) { - Bh1750.address = Bh1750.addresses[i]; - if (I2cActive(Bh1750.address)) { continue; } + if (I2cActive(Bh1750.addresses[i])) { continue; } - if (Bh1750SetMTreg()) { - I2cSetActiveFound(Bh1750.address, Bh1750.types); - Bh1750.type = 1; - break; + Bh1750_sensors[Bh1750.count].address = Bh1750.addresses[i]; + if (Bh1750SetMTreg(Bh1750.count)) { + I2cSetActiveFound(Bh1750_sensors[Bh1750.count].address, Bh1750.types); + Bh1750.count++; } } } -void Bh1750EverySecond(void) -{ - // 1mS - if (!Bh1750Read()) { - AddLogMissed(Bh1750.types, Bh1750.valid); +void Bh1750EverySecond(void) { + for (uint32_t i = 0; i < Bh1750.count; i++) { + // 1mS + if (!Bh1750Read(i)) { +// AddLogMissed(Bh1750.types, Bh1750.valid); + } } } /*********************************************************************************************\ - * Command Sensor10 - * - * 0 - High resolution mode (default) - * 1 - High resolution mode 2 - * 2 - Low resolution mode - * 31..254 - Measurement Time value (not persistent, default is 69) + * Commands \*********************************************************************************************/ -bool Bh1750CommandSensor(void) -{ - if (XdrvMailbox.data_len) { +void CmndBh1750Resolution(void) { + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= Bh1750.count)) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) { - Settings.SensorBits1.bh1750_resolution = XdrvMailbox.payload; - Bh1750SetResolution(); - } - else if ((XdrvMailbox.payload > 30) && (XdrvMailbox.payload < 255)) { - Bh1750.mtreg = XdrvMailbox.payload; - Bh1750SetMTreg(); + if (1 == XdrvMailbox.index) { + Settings.SensorBits1.bh1750_1_resolution = XdrvMailbox.payload; + } else { + Settings.SensorBits1.bh1750_2_resolution = XdrvMailbox.payload; + } + Bh1750SetResolution(XdrvMailbox.index -1); } + ResponseCmndIdxNumber(Bh1750Resolution(XdrvMailbox.index -1)); } - Response_P(PSTR("{\"" D_CMND_SENSOR "10\":{\"Resolution\":%d,\"MTime\":%d}}"), Settings.SensorBits1.bh1750_resolution, Bh1750.mtreg); - - return true; } -void Bh1750Show(bool json) -{ - if (Bh1750.valid) { - if (json) { - ResponseAppend_P(JSON_SNS_ILLUMINANCE, Bh1750.types, Bh1750.illuminance); -#ifdef USE_DOMOTICZ - if (0 == tele_period) { - DomoticzSensor(DZ_ILLUMINANCE, Bh1750.illuminance); +void CmndBh1750MTime(void) { + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= Bh1750.count)) { + if ((XdrvMailbox.payload > 30) && (XdrvMailbox.payload < 255)) { + Bh1750_sensors[XdrvMailbox.index -1].mtreg = XdrvMailbox.payload; + Bh1750SetMTreg(XdrvMailbox.index -1); + } + ResponseCmndIdxNumber(Bh1750_sensors[XdrvMailbox.index -1].mtreg); + } +} + +/********************************************************************************************/ + +void Bh1750Show(bool json) { + for (uint32_t sensor_index = 0; sensor_index < Bh1750.count; sensor_index++) { + if (Bh1750_sensors[sensor_index].valid) { + char sensor_name[10]; + strlcpy(sensor_name, Bh1750.types, sizeof(sensor_name)); + if (Bh1750.count > 1) { + snprintf_P(sensor_name, sizeof(sensor_name), PSTR("%s%c%d"), sensor_name, IndexSeparator(), sensor_index +1); // BH1750-1 } + + if (json) { + ResponseAppend_P(JSON_SNS_ILLUMINANCE, sensor_name, Bh1750_sensors[sensor_index].illuminance); +#ifdef USE_DOMOTICZ + if ((0 == tele_period) && (0 == sensor_index)) { + DomoticzSensor(DZ_ILLUMINANCE, Bh1750_sensors[sensor_index].illuminance); + } #endif // USE_DOMOTICZ #ifdef USE_WEBSERVER - } else { - WSContentSend_PD(HTTP_SNS_ILLUMINANCE, Bh1750.types, Bh1750.illuminance); + } else { + WSContentSend_PD(HTTP_SNS_ILLUMINANCE, sensor_name, Bh1750_sensors[sensor_index].illuminance); #endif // USE_WEBSERVER + } } } } @@ -159,8 +193,7 @@ void Bh1750Show(bool json) * Interface \*********************************************************************************************/ -bool Xsns10(uint8_t function) -{ +bool Xsns10(uint8_t function) { if (!I2cEnabled(XI2C_11)) { return false; } bool result = false; @@ -168,15 +201,13 @@ bool Xsns10(uint8_t function) if (FUNC_INIT == function) { Bh1750Detect(); } - else if (Bh1750.type) { + else if (Bh1750.count) { switch (function) { case FUNC_EVERY_SECOND: Bh1750EverySecond(); break; - case FUNC_COMMAND_SENSOR: - if (XSNS_10 == XdrvMailbox.index) { - result = Bh1750CommandSensor(); - } + case FUNC_COMMAND: + result = DecodeCommand(kBh1750Commands, Bh1750Command); break; case FUNC_JSON_APPEND: Bh1750Show(1);