From dae6de76f179c171d3f631d5eecbe46e6c9e6f13 Mon Sep 17 00:00:00 2001 From: Frank Date: Sat, 17 Dec 2022 19:45:45 +0100 Subject: [PATCH] Improve co-existence of usermods sharing I2C Improve co-existence of several popular usermods with respect to shared I2C bus. - ensure that i2c_sda and i2c_scl are used when defined - ensure that HW_PIN_SDA / HW_PIN_SCL are not overwritten - ensure that Wire.begin()nis always called with user-defined pins (remove rogue Wire.begin() without parameters) - ensure that set.cpp / cfg.cpp use esp32-specific global Wire objects. --- usermods/BH1750_v2/usermod_bh1750.h | 30 +++++++++++++++---- usermods/RTC/usermod_rtc.h | 13 ++++++++ usermods/mpu6050_imu/usermod_mpu6050_imu.h | 17 +++++++++-- .../usermod_v2_four_line_display_ALT.h | 5 ++++ wled00/cfg.cpp | 3 ++ wled00/set.cpp | 3 ++ wled00/src/dependencies/time/DS1307RTC.h | 2 +- 7 files changed, 63 insertions(+), 10 deletions(-) diff --git a/usermods/BH1750_v2/usermod_bh1750.h b/usermods/BH1750_v2/usermod_bh1750.h index a69e2751..57b8a8fb 100644 --- a/usermods/BH1750_v2/usermod_bh1750.h +++ b/usermods/BH1750_v2/usermod_bh1750.h @@ -3,8 +3,10 @@ #pragma once -#include "wled.h" +#include // WLEDMM: make sure that I2C drivers have the "right" Wire Object #include + +#include "wled.h" #include // the max frequency to check photoresistor, 10 seconds @@ -53,9 +55,13 @@ private: static const char _HomeAssistantDiscovery[]; // set the default pins based on the architecture, these get overridden by Usermod menu settings - #ifdef ARDUINO_ARCH_ESP32 // ESP32 boards - #define HW_PIN_SCL 22 - #define HW_PIN_SDA 21 + #ifdef ARDUINO_ARCH_ESP32 // ESP32 boards -- WLEDMM: don't override already defined HW pins + #ifndef HW_PIN_SDA + #define HW_PIN_SCL 22 + #endif + #ifndef HW_PIN_SDA + #define HW_PIN_SDA 21 + #endif #else // ESP8266 boards #define HW_PIN_SCL 5 #define HW_PIN_SDA 4 @@ -121,11 +127,20 @@ public: { bool HW_Pins_Used = (ioPin[0]==HW_PIN_SCL && ioPin[1]==HW_PIN_SDA); // note whether architecture-based hardware SCL/SDA pins used PinOwner po = PinOwner::UM_BH1750; // defaults to being pinowner for SCL/SDA pins - PinManagerPinType pins[2] = { { ioPin[0], true }, { ioPin[1], true } }; // allocate pins if (HW_Pins_Used) po = PinOwner::HW_I2C; // allow multiple allocations of HW I2C bus pins + if ((i2c_scl >= 0) && (i2c_sda >=0)) { // WLEDMM: make sure that global HW pins are used if defined + ioPin[0] = i2c_scl; + ioPin[1] = i2c_sda; + po = PinOwner::HW_I2C; + } + PinManagerPinType pins[2] = { { ioPin[0], true }, { ioPin[1], true } }; // allocate pins // WLEDMM: after selecting final pins if (!pinManager.allocateMultiplePins(pins, 2, po)) return; - Wire.begin(ioPin[1], ioPin[0]); +#if defined(ARDUINO_ARCH_ESP32) + Wire.begin(pins[1].pin, pins[0].pin); // WLEDMM this might silently fail, which is OK as it just means that I2C bus is already running. +#else + Wire.begin(); // WLEDMM - i2c pins on 8266 are fixed. +#endif sensorFound = lightMeter.begin(); initDone = true; @@ -136,6 +151,7 @@ public: if ((!enabled) || strip.isUpdating()) return; + if (!sensorFound) return; // WLEDMM bugfix unsigned long now = millis(); // check to see if we are due for taking a measurement @@ -179,6 +195,8 @@ public: void addToJsonInfo(JsonObject &root) { + if ((!enabled) || (!sensorFound)) return; // WLEDMM bugfix + JsonObject user = root[F("u")]; if (user.isNull()) user = root.createNestedObject(F("u")); diff --git a/usermods/RTC/usermod_rtc.h b/usermods/RTC/usermod_rtc.h index fd9a4054..c520d3f3 100644 --- a/usermods/RTC/usermod_rtc.h +++ b/usermods/RTC/usermod_rtc.h @@ -1,5 +1,8 @@ #pragma once +#include // WLEDMM: make sure that I2C drivers have the "right" Wire Object +#include + #include "src/dependencies/time/DS1307RTC.h" #include "wled.h" @@ -13,7 +16,17 @@ class RTCUsermod : public Usermod { void setup() { PinManagerPinType pins[2] = { { i2c_scl, true }, { i2c_sda, true } }; +#if defined(ARDUINO_ARCH_ESP32) && defined(HW_PIN_SDA) && defined(HW_PIN_SCL) + if (pins[0].pin < 0) pins[0].pin = HW_PIN_SCL; //WLEDMM + if (pins[1].pin < 0) pins[1].pin = HW_PIN_SDA; //WLEDMM +#endif if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) { disabled = true; return; } +#if defined(ARDUINO_ARCH_ESP32) + Wire.begin(pins[1].pin, pins[0].pin); // WLEDMM this might silently fail, which is OK as it just means that I2C bus is already running. +#else + Wire.begin(); // WLEDMM - i2c pins on 8266 are fixed. +#endif + RTC.begin(); time_t rtcTime = RTC.get(); if (rtcTime) { diff --git a/usermods/mpu6050_imu/usermod_mpu6050_imu.h b/usermods/mpu6050_imu/usermod_mpu6050_imu.h index 8a3c7c7a..8be53666 100644 --- a/usermods/mpu6050_imu/usermod_mpu6050_imu.h +++ b/usermods/mpu6050_imu/usermod_mpu6050_imu.h @@ -1,5 +1,8 @@ #pragma once +#include // WLEDMM: make sure that I2C drivers have the "right" Wire Object +#include + #include "wled.h" // #define MPU6050_INT_GPIO 13 // WLEDMM - better choice on ESP32 @@ -44,9 +47,12 @@ 5. Wire up the MPU6050 as detailed above. */ -#include "I2Cdev.h" +// WLEDMM: make sure that the "standard" Wire object is used +#define I2CDEV_IMPLEMENTATION I2CDEV_ARDUINO_WIRE -#include "MPU6050_6Axis_MotionApps20.h" +#include + +#include // WLEDMM - need to re-define WLED DEBUG_PRINT maros, because the were overwritten by MPU6050_6Axis_MotionApps20.h #undef DEBUG_PRINT @@ -132,7 +138,12 @@ class MPU6050Driver : public Usermod { // join I2C bus (I2Cdev library doesn't do this automatically) #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE - Wire.begin(); // WLEDMM fixme - this completely ignores any PINS +#if defined(ARDUINO_ARCH_ESP32) + Wire.begin(pins[1].pin, pins[0].pin); // WLEDMM fix - need to use proper pins, in case that Wire was not started yet. Call will silently fail if Wire is initialized already. +#else + Wire.begin(); // WLEDMM - i2c pins on 8266 are fixed. +#endif + Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); 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 da42734a..79b2676c 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 @@ -1,5 +1,10 @@ #pragma once +#include // WLEDMM: make sure that I2C drivers have the "right" Wire Object +#include +#undef U8X8_NO_HW_I2C // WLEDMM: we do want I2C hardware drivers - if possible +//#define WIRE_INTERFACES_COUNT 2 // experimental - tell U8x8Lib that there is a econd Wire unit + #include "wled.h" #include // from https://github.com/olikraus/u8g2/ #include "4LD_wled_fonts.c" diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index a12f1667..f9911373 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -1,3 +1,6 @@ +#include // WLEDMM: make sure that I2C drivers have the "right" Wire Object +#include + #include "wled.h" #include "wled_ethernet.h" diff --git a/wled00/set.cpp b/wled00/set.cpp index 3b50f5d2..397dd096 100644 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -1,3 +1,6 @@ +#include // WLEDMM: make sure that I2C drivers have the "right" Wire Object +#include + #include "wled.h" /* diff --git a/wled00/src/dependencies/time/DS1307RTC.h b/wled00/src/dependencies/time/DS1307RTC.h index 551ae996..621feb20 100644 --- a/wled00/src/dependencies/time/DS1307RTC.h +++ b/wled00/src/dependencies/time/DS1307RTC.h @@ -14,7 +14,7 @@ class DS1307RTC // user-accessible "public" interface public: DS1307RTC() {} - static void begin() { Wire.begin(); } + static void begin() { /*Wire.begin();*/ } static time_t get(); static bool set(time_t t); static bool read(tmElements_t &tm);