From 9e9d10618bd8a7eb29181d1446434085e34640c0 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Wed, 10 May 2023 15:15:25 +0200 Subject: [PATCH 1/6] SHT usermod MoonModules upgrade Use MM specific features in SHT usermod: * Join global I2C bus with pinManager.joinWire() * allow to compile without MQTT * use extended Usermod class features * prevent sensor starvation when running with > 600 LEDs --- usermods/sht/usermod_sht.h | 45 ++++++++++++++++++++++++++++++-------- wled00/usermods_list.cpp | 2 +- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/usermods/sht/usermod_sht.h b/usermods/sht/usermod_sht.h index 1123a10a..ab0ab677 100644 --- a/usermods/sht/usermod_sht.h +++ b/usermods/sht/usermod_sht.h @@ -1,5 +1,5 @@ #ifndef WLED_ENABLE_MQTT -#error "This user mod requires MQTT to be enabled." +#warning "This user mod expects MQTT to be enabled." #endif #pragma once @@ -14,7 +14,7 @@ class ShtUsermod : public Usermod { private: - bool enabled = false; // Is usermod enabled or not + //bool enabled = false; // Is usermod enabled or not //WLEDMM use public attribute of class UserMod bool firstRunDone = false; // Remembers if the first config load run had been done bool pinAllocDone = true; // Remembers if we have allocated pins bool initDone = false; // Remembers if the mod has been completely initialised @@ -44,8 +44,9 @@ class ShtUsermod : public Usermod void appendDeviceToMqttDiscoveryMessage(JsonDocument& root); public: + ShtUsermod(const char *name, bool enabled):Usermod(name, enabled) {} //WLEDMM // Strings to reduce flash memory usage (used more than twice) - static const char _name[]; + //static const char _name[]; //WLEDMM use public attribute of class UserMod static const char _enabled[]; static const char _shtType[]; static const char _unitOfTemp[]; @@ -71,7 +72,7 @@ class ShtUsermod : public Usermod }; // Strings to reduce flash memory usage (used more than twice) -const char ShtUsermod::_name[] PROGMEM = "SHT-Sensor"; +//const char ShtUsermod::_name[] PROGMEM = "SHT-Sensor"; //WLEDMM use public attribute of class UserMod const char ShtUsermod::_enabled[] PROGMEM = "Enabled"; const char ShtUsermod::_shtType[] PROGMEM = "SHT-Type"; const char ShtUsermod::_unitOfTemp[] PROGMEM = "Unit"; @@ -93,8 +94,11 @@ void ShtUsermod::initShtTempHumiditySensor() case USERMOD_SHT_TYPE_SHT35: shtTempHumidSensor = (SHT *) new SHT35(); break; case USERMOD_SHT_TYPE_SHT85: shtTempHumidSensor = (SHT *) new SHT85(); break; } - +#if 0 shtTempHumidSensor->begin(shtI2cAddress, i2c_sda, i2c_scl); +#else + shtTempHumidSensor->begin((uint8_t)shtI2cAddress); // WLEDMM this connects to an existing Wire (I2C) object, instead starting a new driver +#endif if (shtTempHumidSensor->readStatus() == 0xFFFF) { DEBUG_PRINTF("[%s] SHT init failed!\n", _name); cleanup(); @@ -131,12 +135,15 @@ void ShtUsermod::cleanup() cleanupShtTempHumiditySensor(); if (pinAllocDone) { +#if 0 // WLEDMM not needed PinManagerPinType pins[2] = { { i2c_sda, true }, { i2c_scl, true } }; pinManager.deallocateMultiplePins(pins, 2, PinOwner::HW_I2C); +#endif pinAllocDone = false; } enabled = false; + shtInitDone = false; // WLEDMM bugfix } /** @@ -158,6 +165,7 @@ bool ShtUsermod::isShtReady() * @return void */ void ShtUsermod::publishTemperatureAndHumidityViaMqtt() { +#ifdef WLED_ENABLED_MQTT if (!WLED_MQTT_CONNECTED) return; char buf[128]; @@ -165,6 +173,7 @@ void ShtUsermod::publishTemperatureAndHumidityViaMqtt() { mqtt->publish(buf, 0, false, String(getTemperature()).c_str()); snprintf_P(buf, 127, PSTR("%s/humidity"), mqttDeviceTopic); mqtt->publish(buf, 0, false, String(getHumidity()).c_str()); +#endif } /** @@ -177,6 +186,7 @@ void ShtUsermod::publishTemperatureAndHumidityViaMqtt() { * @return void */ void ShtUsermod::publishHomeAssistantAutodiscovery() { +#ifdef WLED_ENABLED_MQTT if (!WLED_MQTT_CONNECTED) return; char json_str[1024], buf[128]; @@ -214,6 +224,7 @@ void ShtUsermod::publishHomeAssistantAutodiscovery() { mqtt->publish(buf, 0, true, json_str, payload_size); haMqttDiscoveryDone = true; +#endif } /** @@ -221,6 +232,7 @@ void ShtUsermod::publishHomeAssistantAutodiscovery() { * * @return void */ +#ifdef WLED_ENABLED_MQTT void ShtUsermod::appendDeviceToMqttDiscoveryMessage(JsonDocument& root) { JsonObject device = root.createNestedObject(F("dev")); device[F("ids")] = escapedMac.c_str(); @@ -229,6 +241,7 @@ void ShtUsermod::appendDeviceToMqttDiscoveryMessage(JsonDocument& root) { device[F("mdl")] = ESP.getChipModel(); device[F("mf")] = F("espressif"); } +#endif /** * Setup the mod. @@ -246,16 +259,26 @@ void ShtUsermod::setup() if (enabled) { PinManagerPinType pins[2] = { { i2c_sda, true }, { i2c_scl, true } }; // GPIOs can be set to -1 and allocateMultiplePins() will return true, so check they're gt zero +#if 0 // WLEDMM done by pinManager.joinWire() if (i2c_sda < 0 || i2c_scl < 0 || !pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) { +#else + if (i2c_sda < 0 || i2c_scl < 0) { +#endif DEBUG_PRINTF("[%s] SHT pin allocation failed!\n", _name); cleanup(); return; } - pinAllocDone = true; + // WLEDMM join hardware I2C + if (pinManager.joinWire()) { // WLEDMM - this allocates global I2C pins, then starts Wire - if not started previously + pinAllocDone = true; - initShtTempHumiditySensor(); + initShtTempHumiditySensor(); - initDone = true; + initDone = true; + } else { + DEBUG_PRINTF("[%s] SHT I2C pin allocation failed!\n", _name); + return; + } } firstRunDone = true; @@ -276,7 +299,9 @@ void ShtUsermod::setup() */ void ShtUsermod::loop() { - if (!enabled || !initDone || strip.isUpdating()) return; + unsigned long last_runtime = 0; // WLEDMM ensure that strip.isUpdating() will not block longer that 1000ms + if (!enabled || !initDone || !pinAllocDone || (strip.isUpdating() && (millis()-last_runtime < 1000))) return; // WLEDMM be nice, but not too nice + last_runtime = millis(); if (isShtReady()) { if (millis() - shtLastTimeUpdated > 30000 && !shtDataRequested) { @@ -315,7 +340,9 @@ void ShtUsermod::loop() * @return void */ void ShtUsermod::onMqttConnect(bool sessionPresent) { +#ifdef WLED_ENABLED_MQTT if (haMqttDiscovery && !haMqttDiscoveryDone) publishHomeAssistantAutodiscovery(); +#endif } /** diff --git a/wled00/usermods_list.cpp b/wled00/usermods_list.cpp index 02af154a..24636ed1 100644 --- a/wled00/usermods_list.cpp +++ b/wled00/usermods_list.cpp @@ -374,7 +374,7 @@ void registerUsermods() #endif #ifdef USERMOD_SHT - usermods.add(new ShtUsermod()); + usermods.add(new ShtUsermod("SHT-Sensor", false)); #endif //WLEDMM ARTIFX From d79fa92e6c1d3324d8c3b0d20e778a510b1020cd Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Wed, 10 May 2023 17:12:48 +0200 Subject: [PATCH 2/6] SHT usermod added to MM "XL" config ... but commented out (experimental) --- platformio.ini | 2 ++ usermods/sht/usermod_sht.h | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index f1fece17..fbb0ba8f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -868,6 +868,7 @@ build_flags_XL = -D USERMOD_SN_PHOTORESISTOR -D USERMOD_BME280 -D USERMOD_DHT + ; -D USERMOD_SHT ;; experimental -D USERMOD_VL53L0X_GESTURES -D WLED_ENABLE_PIXART @@ -878,6 +879,7 @@ lib_deps_XL = ; adafruit/Adafruit Si7021 Library @ 1.4.0 ;; experimental for usermod USERMOD_SENSORSTOMQTT BME280@~3.0.0 ; for usermod USERMOD_BME280 https://github.com/alwynallan/DHT_nonblocking ; for usermod USERMOD_DHT + ; robtillaart/SHT85 @ ~0.4.0 ;; for usermod USERMOD_SHT pololu/VL53L0X @ ^1.3.0 ; for usermod USERMOD_VL53L0X_GESTURES ; end of common diff --git a/usermods/sht/usermod_sht.h b/usermods/sht/usermod_sht.h index ab0ab677..118d2d32 100644 --- a/usermods/sht/usermod_sht.h +++ b/usermods/sht/usermod_sht.h @@ -100,7 +100,7 @@ void ShtUsermod::initShtTempHumiditySensor() shtTempHumidSensor->begin((uint8_t)shtI2cAddress); // WLEDMM this connects to an existing Wire (I2C) object, instead starting a new driver #endif if (shtTempHumidSensor->readStatus() == 0xFFFF) { - DEBUG_PRINTF("[%s] SHT init failed!\n", _name); + USER_PRINTF("[%s] SHT init failed, Sensor not found!\n", _name); cleanup(); return; } @@ -282,6 +282,12 @@ void ShtUsermod::setup() } firstRunDone = true; + + if (enabled && initDone && pinAllocDone && isShtReady()) { + USER_PRINTF(PSTR("[%s] SHT sensor ready.\n"), _name); + } else { + USER_PRINTF(PSTR("[%s] SHT sensor not ready.\n"), _name); + } } /** From 3aad3a8ff7e9be8c904b71d816fa98e64690c419 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Wed, 10 May 2023 18:08:26 +0200 Subject: [PATCH 3/6] sht: replace _enabled by "enabled" ... so the usermod status shows correctly in UM overview. --- usermods/sht/usermod_sht.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/usermods/sht/usermod_sht.h b/usermods/sht/usermod_sht.h index 118d2d32..7cc9fe54 100644 --- a/usermods/sht/usermod_sht.h +++ b/usermods/sht/usermod_sht.h @@ -47,7 +47,7 @@ class ShtUsermod : public Usermod ShtUsermod(const char *name, bool enabled):Usermod(name, enabled) {} //WLEDMM // Strings to reduce flash memory usage (used more than twice) //static const char _name[]; //WLEDMM use public attribute of class UserMod - static const char _enabled[]; + //static const char _enabled[]; //WLEDMM not needed static const char _shtType[]; static const char _unitOfTemp[]; static const char _haMqttDiscovery[]; @@ -73,7 +73,7 @@ class ShtUsermod : public Usermod // Strings to reduce flash memory usage (used more than twice) //const char ShtUsermod::_name[] PROGMEM = "SHT-Sensor"; //WLEDMM use public attribute of class UserMod -const char ShtUsermod::_enabled[] PROGMEM = "Enabled"; +//const char ShtUsermod::_enabled[] PROGMEM = "Enabled"; //WLEDMM not needed const char ShtUsermod::_shtType[] PROGMEM = "SHT-Type"; const char ShtUsermod::_unitOfTemp[] PROGMEM = "Unit"; const char ShtUsermod::_haMqttDiscovery[] PROGMEM = "Add-To-HA-MQTT-Discovery"; @@ -390,7 +390,7 @@ void ShtUsermod::addToConfig(JsonObject &root) { JsonObject top = root.createNestedObject(FPSTR(_name)); // usermodname - top[FPSTR(_enabled)] = enabled; + top[FPSTR("enabled")] = enabled; top[FPSTR(_shtType)] = shtType; top[FPSTR(_unitOfTemp)] = unitOfTemp; top[FPSTR(_haMqttDiscovery)] = haMqttDiscovery; @@ -421,7 +421,7 @@ bool ShtUsermod::readFromConfig(JsonObject &root) byte oldUnitOfTemp = unitOfTemp; bool oldHaMqttDiscovery = haMqttDiscovery; - getJsonValue(top[FPSTR(_enabled)], enabled); + getJsonValue(top[FPSTR("enabled")], enabled); getJsonValue(top[FPSTR(_shtType)], shtType); getJsonValue(top[FPSTR(_unitOfTemp)], unitOfTemp); getJsonValue(top[FPSTR(_haMqttDiscovery)], haMqttDiscovery); From 50061ddae8b98a35f875004ee42bdbe09f4de0f6 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Wed, 10 May 2023 20:14:10 +0200 Subject: [PATCH 4/6] UM BH1750 adapted to "MM style", 8266 build fixes * UM BH1750 adjustments to use new MM features * UM BH1750 check sensor status before tryig to read new value (avoids blocking LED updates) * UM temperature: ensure that measurements continue with many LEDs running (strip.isUpdating() will be true all the time) * all usermods: solved compile problems on 8266 --- usermods/BH1750_v2/usermod_bh1750.h | 44 ++++++++++++---------- usermods/Temperature/usermod_temperature.h | 4 +- usermods/sht/usermod_sht.h | 4 +- wled00/usermods_list.cpp | 2 +- 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/usermods/BH1750_v2/usermod_bh1750.h b/usermods/BH1750_v2/usermod_bh1750.h index 77a57efb..0cb4bf18 100644 --- a/usermods/BH1750_v2/usermod_bh1750.h +++ b/usermods/BH1750_v2/usermod_bh1750.h @@ -48,11 +48,11 @@ private: bool getLuminanceComplete = false; // flag set at startup - bool enabled = true; + //bool enabled = true; //WLEDMM not needed as we use global attributes // strings to reduce flash memory usage (used more than twice) - static const char _name[]; - static const char _enabled[]; + //static const char _name[]; //WLEDMM not needed as we use global attributes + //static const char _enabled[]; //WLEDMM not needed as we use global attributes static const char _maxReadInterval[]; static const char _minReadInterval[]; static const char _offset[]; @@ -76,7 +76,7 @@ private: bool sensorFound = false; // Home Assistant and MQTT - String mqttLuminanceTopic = F(""); + String mqttLuminanceTopic = FPSTR(""); bool mqttInitialized = false; bool HomeAssistantDiscovery = true; // Publish Home Assistant Discovery messages @@ -132,6 +132,8 @@ private: } public: + Usermod_BH1750(const char *name, bool enabled):Usermod(name, enabled) {} //WLEDMM + void setup() { #if 0 @@ -157,22 +159,22 @@ public: if (!pinManager.joinWire()) { // WLEDMM - this allocates global I2C pins, then starts Wire - if not started previously sensorFound = false; //enabled = false; - USER_PRINTLN(F("BH1750: failed to join I2C bus.")); + USER_PRINTLN(F("[BH1750]: failed to join I2C bus.")); return; } - sensorFound = lightMeter.begin(); - if (sensorFound) { USER_PRINTLN(F("BH1750 sensor found.")); } - else{ USER_PRINTLN(F("BH1750 sensor not found.")); } + sensorFound = lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE); // WLEDMM set mode explicitly + if (sensorFound) { USER_PRINTLN(F("[BH1750] sensor found.")); } + else{ USER_PRINTLN(F("[BH1750] sensor not found.")); } initDone = true; } void loop() { - if ((!enabled) || strip.isUpdating()) + if (!sensorFound || !initDone) return; // WLEDMM bugfix + if ((!enabled) || (strip.isUpdating() && (millis() - lastMeasurement < 450))) // WLEDMM be nice, but not too nice return; - if (!sensorFound) return; // WLEDMM bugfix unsigned long now = millis(); // check to see if we are due for taking a measurement @@ -184,10 +186,12 @@ public: } bool shouldUpdate = now - lastSend > maxReadingInterval; - - float lux = lightMeter.readLightLevel(); - lastMeasurement = millis(); - getLuminanceComplete = true; + float lux = lastLux; + if (lightMeter.measurementReady()) { //WLEDMM do not block in case the sensor is still busy + lux = lightMeter.readLightLevel(); + lastMeasurement = millis(); + getLuminanceComplete = true; + } if (shouldUpdate || checkBoundSensor(lux, lastLux, offset)) { @@ -255,7 +259,7 @@ public: { // we add JSON object. JsonObject top = root.createNestedObject(FPSTR(_name)); // usermodname - top[FPSTR(_enabled)] = enabled; + top[F("enabled")] = enabled; top[FPSTR(_maxReadInterval)] = maxReadingInterval; top[FPSTR(_minReadInterval)] = minReadingInterval; top[FPSTR(_HomeAssistantDiscovery)] = HomeAssistantDiscovery; @@ -269,7 +273,7 @@ public: // top[F("help4Pins")] = F("SCL,SDA"); // help for Settings page - DEBUG_PRINTLN(F("BH1750 config saved.")); + DEBUG_PRINTLN(F("[BH1750] config saved.")); } // called before setup() to populate properties from values stored in cfg.json @@ -283,13 +287,13 @@ public: if (top.isNull()) { DEBUG_PRINT(FPSTR(_name)); - DEBUG_PRINT(F("BH1750")); + DEBUG_PRINT(F("[BH1750]")); DEBUG_PRINTLN(F(": No config found. (Using defaults.)")); return false; } bool configComplete = !top.isNull(); - configComplete &= getJsonValue(top[FPSTR(_enabled)], enabled, false); + configComplete &= getJsonValue(top[F("enabled")], enabled, false); configComplete &= getJsonValue(top[FPSTR(_maxReadInterval)], maxReadingInterval, 10000); //ms configComplete &= getJsonValue(top[FPSTR(_minReadInterval)], minReadingInterval, 500); //ms configComplete &= getJsonValue(top[FPSTR(_HomeAssistantDiscovery)], HomeAssistantDiscovery, false); @@ -335,8 +339,8 @@ public: }; // strings to reduce flash memory usage (used more than twice) -const char Usermod_BH1750::_name[] PROGMEM = "BH1750"; -const char Usermod_BH1750::_enabled[] PROGMEM = "enabled"; +//const char Usermod_BH1750::_name[] PROGMEM = "BH1750"; //WLEDMM not needed as we use global attributes +//const char Usermod_BH1750::_enabled[] PROGMEM = "enabled"; //WLEDMM not needed as we use global attributes const char Usermod_BH1750::_maxReadInterval[] PROGMEM = "max-read-interval-ms"; const char Usermod_BH1750::_minReadInterval[] PROGMEM = "min-read-interval-ms"; const char Usermod_BH1750::_HomeAssistantDiscovery[] PROGMEM = "HomeAssistantDiscoveryLux"; diff --git a/usermods/Temperature/usermod_temperature.h b/usermods/Temperature/usermod_temperature.h index 1c49163a..0d51e21a 100644 --- a/usermods/Temperature/usermod_temperature.h +++ b/usermods/Temperature/usermod_temperature.h @@ -194,7 +194,9 @@ class UsermodTemperature : public Usermod { } void loop() { - if (!enabled || !sensorFound || strip.isUpdating()) return; + unsigned long last_runtime = 0; // WLEDMM ensure that strip.isUpdating() will not block longer that 4000ms + if (!enabled || !sensorFound || (strip.isUpdating() && (millis()-last_runtime < 4000))) return; // WLEDMM be nice, but not too nice + last_runtime = millis(); static uint8_t errorCount = 0; unsigned long now = millis(); diff --git a/usermods/sht/usermod_sht.h b/usermods/sht/usermod_sht.h index 7cc9fe54..8a124bbb 100644 --- a/usermods/sht/usermod_sht.h +++ b/usermods/sht/usermod_sht.h @@ -390,7 +390,7 @@ void ShtUsermod::addToConfig(JsonObject &root) { JsonObject top = root.createNestedObject(FPSTR(_name)); // usermodname - top[FPSTR("enabled")] = enabled; + top[F("enabled")] = enabled; top[FPSTR(_shtType)] = shtType; top[FPSTR(_unitOfTemp)] = unitOfTemp; top[FPSTR(_haMqttDiscovery)] = haMqttDiscovery; @@ -421,7 +421,7 @@ bool ShtUsermod::readFromConfig(JsonObject &root) byte oldUnitOfTemp = unitOfTemp; bool oldHaMqttDiscovery = haMqttDiscovery; - getJsonValue(top[FPSTR("enabled")], enabled); + getJsonValue(top[F("enabled")], enabled); getJsonValue(top[FPSTR(_shtType)], shtType); getJsonValue(top[FPSTR(_unitOfTemp)], unitOfTemp); getJsonValue(top[FPSTR(_haMqttDiscovery)], haMqttDiscovery); diff --git a/wled00/usermods_list.cpp b/wled00/usermods_list.cpp index 24636ed1..4226821d 100644 --- a/wled00/usermods_list.cpp +++ b/wled00/usermods_list.cpp @@ -238,7 +238,7 @@ void registerUsermods() #endif #ifdef USERMOD_BH1750 - usermods.add(new Usermod_BH1750()); + usermods.add(new Usermod_BH1750("BH1750", false)); #endif #ifdef USERMOD_BME280 From cb740d34d7339790a1a14fbe62ea07295fec6c7d Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Wed, 10 May 2023 21:09:28 +0200 Subject: [PATCH 5/6] Bugfix - SHT enable/disable crash --- usermods/sht/usermod_sht.h | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/usermods/sht/usermod_sht.h b/usermods/sht/usermod_sht.h index 8a124bbb..3c0d96b7 100644 --- a/usermods/sht/usermod_sht.h +++ b/usermods/sht/usermod_sht.h @@ -22,7 +22,7 @@ class ShtUsermod : public Usermod bool haMqttDiscoveryDone = false; // Remembers if we already published the HA discovery topics // SHT vars - SHT *shtTempHumidSensor; // Instance of SHT lib + SHT *shtTempHumidSensor = nullptr; // Instance of SHT lib byte shtType = 0; // SHT sensor type to be used. Default: SHT30 byte unitOfTemp = 0; // Temperature unit to be used. Default: Celsius (0 = Celsius, 1 = Fahrenheit) bool shtInitDone = false; // Remembers if SHT sensor has been initialised @@ -37,7 +37,7 @@ class ShtUsermod : public Usermod void initShtTempHumiditySensor(); void cleanupShtTempHumiditySensor(); void cleanup(); - bool isShtReady(); + inline bool isShtReady() { return shtInitDone; } // Checks if the SHT sensor has been initialised. void publishTemperatureAndHumidityViaMqtt(); void publishHomeAssistantAutodiscovery(); @@ -117,8 +117,11 @@ void ShtUsermod::initShtTempHumiditySensor() */ void ShtUsermod::cleanupShtTempHumiditySensor() { - if (isShtReady()) shtTempHumidSensor->reset(); - delete shtTempHumidSensor; + if (isShtReady()) { + shtTempHumidSensor->reset(); + delete shtTempHumidSensor; + shtTempHumidSensor = nullptr; + } shtInitDone = false; } @@ -146,16 +149,6 @@ void ShtUsermod::cleanup() shtInitDone = false; // WLEDMM bugfix } -/** - * Checks if the SHT sensor has been initialised. - * - * @return bool - */ -bool ShtUsermod::isShtReady() -{ - return shtInitDone; -} - /** * Publish temperature and humidity to WLED device topic. * @@ -496,7 +489,19 @@ void ShtUsermod::addToJsonInfo(JsonObject& root) jsonHumidity.add(F(" RH")); jsonTemp.add(getTemperature()); - jsonTemp.add(unitOfTemp ? "°F" : "°C"); + jsonTemp.add(getUnitString()); + + // sensor object + JsonObject sensor = root[F("sensor")]; + if (sensor.isNull()) sensor = root.createNestedObject(F("sensor")); + + jsonTemp = sensor.createNestedArray(F("temp")); + jsonTemp.add(getTemperature()); + jsonTemp.add(getUnitString()); + + jsonHumidity = sensor.createNestedArray(F("humidity")); + jsonHumidity.add(getHumidity()); + jsonHumidity.add(F(" RH")); } /** From 692d30048d0224f21715e6dbca3bfd178660c2b1 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Thu, 11 May 2023 13:34:40 +0200 Subject: [PATCH 6/6] four-line-display: SSD1309 I2C driver * SSD1309 I2C driver added (SPI driver was already included) * minor cleanup to avoid exhaustive "if" for isSPI --- .../usermod_v2_four_line_display_ALT.h | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h b/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h index 85862888..354af71b 100644 --- a/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h +++ b/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h @@ -93,10 +93,11 @@ typedef enum { SSD1306_64, // U8X8_SSD1306_128X64_NONAME_HW_I2C SSD1305, // U8X8_SSD1305_128X32_ADAFRUIT_HW_I2C SSD1305_64, // U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C - SSD1306_SPI, // U8X8_SSD1306_128X32_NONAME_HW_SPI + SSD1306_SPI, // U8X8_SSD1306_128X32_NONAME_HW_SPI SSD1306_SPI64=7, // U8X8_SSD1306_128X64_NONAME_HW_SPI SSD1309_SPI64=8, // U8X8_SSD1309_128X64_NONAME0_4W_HW_SPI - SSD1327_SPI128=9 // U8X8_SSD1327_WS_128X128_4W_SW_SPI + SSD1327_SPI128=9,// U8X8_SSD1327_WS_128X128_4W_SW_SPI + SSD1309_64=10 // U8X8_SSD1309_128X64_NONAME2_HW_I2C } DisplayType; @@ -213,6 +214,20 @@ class FourLineDisplayUsermod : public Usermod { // or check the gallery: // https://github.com/olikraus/u8g2/wiki/gallery + // is this display using SPI? + bool displayIsSPI(DisplayType disp) { + switch(disp) { + case SSD1306_SPI: // falls thru + case SSD1306_SPI64: // falls thru + case SSD1309_SPI64: // falls thru + case SSD1327_SPI128: + return true; // yes its SPI + break; // makes compiler happy + default: + return false; // no anything else is I2C + } + } + // some displays need this to properly apply contrast void setVcomh(bool highContrast) { if (!typeOK || !enabled) return; // WLEDMM make sure the display is initialized before we try to draw on it @@ -418,7 +433,8 @@ class FourLineDisplayUsermod : public Usermod { void setup() { if (!enabled) return; // typeOK = true will be set after successful setup - bool isHW, isSPI = (type == SSD1306_SPI || type == SSD1306_SPI64 || type > 7); + bool isHW = false; + bool isSPI = displayIsSPI(type); PinOwner po = PinOwner::UM_FourLineDisplay; if (isSPI) { if (ioPin[0] < 0 || ioPin[1] < 0) { @@ -529,6 +545,10 @@ class FourLineDisplayUsermod : public Usermod { if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset else u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA break; + case SSD1309_64: + if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1309_128X64_NONAME2_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset + else u8x8 = (U8X8 *) new U8X8_SSD1309_128X64_NONAME2_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA + break; case SSD1305: if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1305_128X32_NONAME_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset else u8x8 = (U8X8 *) new U8X8_SSD1305_128X32_ADAFRUIT_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA @@ -1259,13 +1279,14 @@ class FourLineDisplayUsermod : public Usermod { oappend(SET_F("addOption(dd,'SSD1306',1);")); oappend(SET_F("addOption(dd,'SH1106',2);")); oappend(SET_F("addOption(dd,'SSD1306 128x64',3);")); + oappend(SET_F("addOption(dd,'SSD1309 128x64',10);")); oappend(SET_F("addOption(dd,'SSD1305',4);")); oappend(SET_F("addOption(dd,'SSD1305 128x64',5);")); oappend(SET_F("addOption(dd,'SSD1306 SPI',6);")); oappend(SET_F("addOption(dd,'SSD1306 SPI 128x64',7);")); oappend(SET_F("addOption(dd,'SSD1309 SPI 128x64',8);")); oappend(SET_F("addOption(dd,'SSD1327 SPI 128x128',9);")); - bool isSPI = (type == SSD1306_SPI || type == SSD1306_SPI64 || type > 7); + bool isSPI = displayIsSPI(type); // WLEDMM add defaults oappend(SET_F("addInfo('4LineDisplay:pin[]',0,'','I2C/SPI CLK');")); oappend(SET_F("dRO('4LineDisplay:pin[]',0);")); // disable read only pins @@ -1328,7 +1349,7 @@ class FourLineDisplayUsermod : public Usermod { void addToConfig(JsonObject& root) { // determine if we are using global HW pins (data & clock) int8_t hw_dta, hw_clk; - if ((type == SSD1306_SPI || type == SSD1306_SPI64) || (type > 7)) { + if (displayIsSPI(type)) { hw_clk = spi_sclk; hw_dta = spi_mosi; } else { @@ -1394,7 +1415,7 @@ class FourLineDisplayUsermod : public Usermod { clockMode = top[FPSTR(_clockMode)] | clockMode; showSeconds = top[FPSTR(_showSeconds)] | showSeconds; contrastFix = top[FPSTR(_contrastFix)] | contrastFix; - if (newType == SSD1306_SPI || newType == SSD1306_SPI64 || newType > 7) + if (displayIsSPI(newType)) ioFrequency = min(20000, max(500, (int)(top[FPSTR(_busClkFrequency)] | ioFrequency/1000))) * 1000; // limit frequency else ioFrequency = min(3400, max(100, (int)(top[FPSTR(_busClkFrequency)] | ioFrequency/1000))) * 1000; // limit frequency @@ -1424,7 +1445,7 @@ class FourLineDisplayUsermod : public Usermod { USER_PRINTLN(F("Display terminated.")); } PinOwner po = PinOwner::UM_FourLineDisplay; - bool isSPI = (type == SSD1306_SPI || type == SSD1306_SPI64 || type > 7); + bool isSPI = displayIsSPI(type); if (isSPI) { pinManager.deallocateMultiplePins((const uint8_t *)(&oldPin[2]), 3, po); bool isHW = (oldPin[0]==spi_sclk && oldPin[1]==spi_mosi);