From cf48ad06ed24b5317c5fc60cb4261b75d146ef71 Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Wed, 21 Jun 2023 23:31:15 +0200 Subject: [PATCH] New SPI display SSD1309 for 4LD. Fixed global I2C usage (no pin allocation in usermods). Enabled option dor Multi relay. --- usermods/BH1750_v2/usermod_bh1750.h | 7 +- usermods/BME280_v2/usermod_bme280.h | 3 +- usermods/RTC/usermod_rtc.h | 7 +- .../usermod_vl53l0x_gestures.h | 3 +- usermods/mpu6050_imu/usermod_mpu6050_imu.h | 3 +- usermods/multi_relay/usermod_multi_relay.h | 9 ++- usermods/sht/usermod_sht.h | 18 +---- .../usermod_v2_four_line_display_ALT.h | 78 ++++++++----------- .../usermod_v2_rotary_encoder_ui_ALT.h | 2 +- wled00/wled.h | 2 +- 10 files changed, 55 insertions(+), 77 deletions(-) diff --git a/usermods/BH1750_v2/usermod_bh1750.h b/usermods/BH1750_v2/usermod_bh1750.h index 8e52612c0..5e597d015 100644 --- a/usermods/BH1750_v2/usermod_bh1750.h +++ b/usermods/BH1750_v2/usermod_bh1750.h @@ -113,8 +113,7 @@ private: public: void setup() { - PinManagerPinType pins[2] = { { i2c_sda, true }, { i2c_scl, true } }; // allocate pins - if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) return; + if (i2c_scl<0 || i2c_sda<0) { enabled = false; return; } sensorFound = lightMeter.begin(); initDone = true; } @@ -174,7 +173,9 @@ public: user = root.createNestedObject(F("u")); JsonArray lux_json = user.createNestedArray(F("Luminance")); - if (!sensorFound) { + if (!enabled) { + lux_json.add(F("disabled")); + } else if (!sensorFound) { // if no sensor lux_json.add(F("BH1750 ")); lux_json.add(F("Not Found")); diff --git a/usermods/BME280_v2/usermod_bme280.h b/usermods/BME280_v2/usermod_bme280.h index f4fcb5f0c..c7d25ec15 100644 --- a/usermods/BME280_v2/usermod_bme280.h +++ b/usermods/BME280_v2/usermod_bme280.h @@ -184,8 +184,7 @@ private: public: void setup() { - PinManagerPinType pins[2] = { { i2c_sda, true }, { i2c_scl, true } }; // allocate pins - if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) { sensorType=0; return; } + if (i2c_scl<0 || i2c_sda<0) { enabled = false; sensorType = 0; return; } if (!bme.begin()) { diff --git a/usermods/RTC/usermod_rtc.h b/usermods/RTC/usermod_rtc.h index fd9a40544..42965e3af 100644 --- a/usermods/RTC/usermod_rtc.h +++ b/usermods/RTC/usermod_rtc.h @@ -12,8 +12,7 @@ class RTCUsermod : public Usermod { public: void setup() { - PinManagerPinType pins[2] = { { i2c_scl, true }, { i2c_sda, true } }; - if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) { disabled = true; return; } + if (i2c_scl<0 || i2c_sda<0) { disabled = true; return; } RTC.begin(); time_t rtcTime = RTC.get(); if (rtcTime) { @@ -25,8 +24,8 @@ class RTCUsermod : public Usermod { } void loop() { - if (strip.isUpdating()) return; - if (!disabled && toki.isTick()) { + if (disabled || strip.isUpdating()) return; + if (toki.isTick()) { time_t t = toki.second(); if (t != RTC.get()) RTC.set(t); //set RTC to NTP/UI-provided value } diff --git a/usermods/VL53L0X_gestures/usermod_vl53l0x_gestures.h b/usermods/VL53L0X_gestures/usermod_vl53l0x_gestures.h index 80e73b530..fe6b958f5 100644 --- a/usermods/VL53L0X_gestures/usermod_vl53l0x_gestures.h +++ b/usermods/VL53L0X_gestures/usermod_vl53l0x_gestures.h @@ -50,8 +50,7 @@ class UsermodVL53L0XGestures : public Usermod { public: void setup() { - PinManagerPinType pins[2] = { { i2c_scl, true }, { i2c_sda, true } }; - if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) { enabled = false; return; } + if (i2c_scl<0 || i2c_sda<0) { enabled = false; return; } sensor.setTimeout(150); if (!sensor.init()) diff --git a/usermods/mpu6050_imu/usermod_mpu6050_imu.h b/usermods/mpu6050_imu/usermod_mpu6050_imu.h index 8a6c3dc29..748ddf1a6 100644 --- a/usermods/mpu6050_imu/usermod_mpu6050_imu.h +++ b/usermods/mpu6050_imu/usermod_mpu6050_imu.h @@ -85,8 +85,7 @@ class MPU6050Driver : public Usermod { * setup() is called once at boot. WiFi is not yet connected at this point. */ void setup() { - PinManagerPinType pins[2] = { { i2c_scl, true }, { i2c_sda, true } }; - if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) { enabled = false; return; } + if (i2c_scl<0 || i2c_sda<0) { enabled = false; return; } #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.setClock(400000U); // 400kHz I2C clock. Comment this line if having compilation difficulties #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE diff --git a/usermods/multi_relay/usermod_multi_relay.h b/usermods/multi_relay/usermod_multi_relay.h index d51163fc1..7234df908 100644 --- a/usermods/multi_relay/usermod_multi_relay.h +++ b/usermods/multi_relay/usermod_multi_relay.h @@ -14,6 +14,9 @@ #ifndef MULTI_RELAY_PINS #define MULTI_RELAY_PINS -1 + #define MULTI_RELAY_ENABLED false +#else + #define MULTI_RELAY_ENABLED true #endif #define WLED_DEBOUNCE_THRESHOLD 50 //only consider button input of at least 50ms as valid (debouncing) @@ -336,7 +339,7 @@ byte MultiRelay::IOexpanderRead(int address) { MultiRelay::MultiRelay() : _switchTimerStart(0) - , enabled(false) + , enabled(MULTI_RELAY_ENABLED) , initDone(false) , usePcf8574(USE_PCF8574) , addrPcf8574(PCF8574_ADDRESS) @@ -479,7 +482,7 @@ void MultiRelay::publishHomeAssistantAutodiscovery() { void MultiRelay::setup() { // pins retrieved from cfg.json (readFromConfig()) prior to running setup() // if we want PCF8574 expander I2C pins need to be valid - if (i2c_sda == i2c_scl && i2c_sda == -1) usePcf8574 = false; + if (i2c_sda<0 || i2c_scl<0) usePcf8574 = false; uint8_t state = 0; for (int i=0; ibegin(shtI2cAddress, i2c_sda, i2c_scl); + shtTempHumidSensor->begin(shtI2cAddress); // uses &Wire if (shtTempHumidSensor->readStatus() == 0xFFFF) { DEBUG_PRINTF("[%s] SHT init failed!\n", _name); cleanup(); @@ -132,13 +131,6 @@ void ShtUsermod::cleanupShtTempHumiditySensor() void ShtUsermod::cleanup() { cleanupShtTempHumiditySensor(); - - if (pinAllocDone) { - PinManagerPinType pins[2] = { { i2c_sda, true }, { i2c_scl, true } }; - pinManager.deallocateMultiplePins(pins, 2, PinOwner::HW_I2C); - pinAllocDone = false; - } - enabled = false; } @@ -237,14 +229,12 @@ void ShtUsermod::appendDeviceToMqttDiscoveryMessage(JsonDocument& root) { 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 (i2c_sda < 0 || i2c_scl < 0 || !pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) { - DEBUG_PRINTF("[%s] SHT pin allocation failed!\n", _name); + // GPIOs can be set to -1 , so check they're gt zero + if (i2c_sda < 0 || i2c_scl < 0) { + DEBUG_PRINTF("[%s] I2C bus not initialised!\n", _name); cleanup(); return; } - pinAllocDone = true; initShtTempHumiditySensor(); 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 afc1bb63a..5a99c3cdb 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 @@ -82,13 +82,14 @@ void DisplayTaskCode(void * parameter); typedef enum { NONE = 0, - SSD1306, // U8X8_SSD1306_128X32_UNIVISION_HW_I2C - SH1106, // U8X8_SH1106_128X64_WINSTAR_HW_I2C - 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_SPI64 // U8X8_SSD1306_128X64_NONAME_HW_SPI + SSD1306, // U8X8_SSD1306_128X32_UNIVISION_HW_I2C + SH1106, // U8X8_SH1106_128X64_WINSTAR_HW_I2C + 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_SPI64, // U8X8_SSD1306_128X64_NONAME_HW_SPI + SSD1309_SPI64 // U8X8_SSD1309_128X64_NONAME0_4W_HW_SPI } DisplayType; @@ -533,24 +534,18 @@ void FourLineDisplayUsermod::sleepOrClock(bool enabled) { // gets called once at boot. Do all initialization that doesn't depend on // network here void FourLineDisplayUsermod::setup() { - if (type == NONE || !enabled) return; - - bool isSPI = (type == SSD1306_SPI || type == SSD1306_SPI64); + bool isSPI = (type == SSD1306_SPI || type == SSD1306_SPI64 || type == SSD1309_SPI64); // check if pins are -1 and disable usermod as PinManager::allocateMultiplePins() will accept -1 as a valid pin if (isSPI) { - PinManagerPinType cspins[3] = { { ioPin[0], true }, { ioPin[1], true }, { ioPin[2], true } }; - if (ioPin[0]==-1 || ioPin[1]==-1 || ioPin[1]==-1) { type=NONE; return; } - if (!pinManager.allocateMultiplePins(cspins, 3, PinOwner::UM_FourLineDisplay)) { type=NONE; return; } - PinManagerPinType pins[2] = { { spi_sclk, true }, { spi_mosi, true } }; - if (spi_sclk==-1 || spi_mosi==-1 || !pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_SPI)) { - pinManager.deallocateMultiplePins(cspins, 3, PinOwner::UM_FourLineDisplay); + if (spi_sclk<0 || spi_mosi<0 || ioPin[0]<0 || ioPin[1]<0 || ioPin[1]<0) { type = NONE; - return; + } else { + PinManagerPinType cspins[3] = { { ioPin[0], true }, { ioPin[1], true }, { ioPin[2], true } }; + if (!pinManager.allocateMultiplePins(cspins, 3, PinOwner::UM_FourLineDisplay)) { type = NONE; } } } else { - PinManagerPinType pins[2] = { {i2c_scl, true }, { i2c_sda, true } }; - if (i2c_scl==-1 || i2c_sda==-1 || !pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) { type=NONE; return; } + if (i2c_scl<0 || i2c_sda<0) { type=NONE; } } DEBUG_PRINTLN(F("Allocating display.")); @@ -563,20 +558,16 @@ void FourLineDisplayUsermod::setup() { case SSD1305_64: u8x8 = (U8X8 *) new U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C(); break; // U8X8 uses global SPI variable that is attached to VSPI bus on ESP32 case SSD1306_SPI: u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_4W_HW_SPI(ioPin[0], ioPin[1], ioPin[2]); break; // Pins are cs, dc, reset - case SSD1306_SPI64: u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_HW_SPI(ioPin[0], ioPin[1], ioPin[2]); break; // Pins are cs, dc, reset + case SSD1306_SPI64: u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_HW_SPI(ioPin[0], ioPin[1], ioPin[2]); break; // Pins are cs, dc, reset + case SSD1309_SPI64: u8x8 = (U8X8 *) new U8X8_SSD1309_128X64_NONAME0_4W_HW_SPI(ioPin[0], ioPin[1], ioPin[2]); break; // Pins are cs, dc, reset // catchall - default: u8x8 = (U8X8 *) new U8X8_NULL(); break; + default: u8x8 = (U8X8 *) new U8X8_NULL(); enabled = false; break; // catchall to create U8x8 instance } if (nullptr == u8x8) { DEBUG_PRINTLN(F("Display init failed.")); if (isSPI) { - int8_t pins[] = {spi_sclk, spi_mosi}; - pinManager.deallocateMultiplePins((const uint8_t*)pins, 2, PinOwner::HW_SPI); pinManager.deallocateMultiplePins((const uint8_t*)ioPin, 3, PinOwner::UM_FourLineDisplay); - } else { - int8_t pins[] = {i2c_scl, i2c_sda}; - pinManager.deallocateMultiplePins((const uint8_t*)pins, 2, PinOwner::HW_I2C); } type = NONE; return; @@ -1215,6 +1206,7 @@ void FourLineDisplayUsermod::appendConfigData() { 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("addInfo('4LineDisplay:type',1,'
Change may require reboot','');")); oappend(SET_F("addInfo('4LineDisplay:pin[]',0,'','SPI CS');")); oappend(SET_F("addInfo('4LineDisplay:pin[]',1,'','SPI DC');")); @@ -1306,38 +1298,30 @@ bool FourLineDisplayUsermod::readFromConfig(JsonObject& root) { bool pinsChanged = false; for (byte i=0; i<3; i++) if (ioPin[i] != oldPin[i]) { pinsChanged = true; break; } if (pinsChanged || type!=newType) { - bool isSPI = (type == SSD1306_SPI || type == SSD1306_SPI64); - bool newSPI = (newType == SSD1306_SPI || newType == SSD1306_SPI64); + bool isSPI = (type == SSD1306_SPI || type == SSD1306_SPI64 || type == SSD1309_SPI64); + bool newSPI = (newType == SSD1306_SPI || newType == SSD1306_SPI64 || newType == SSD1309_SPI64); if (isSPI) { if (pinsChanged || !newSPI) pinManager.deallocateMultiplePins((const uint8_t*)oldPin, 3, PinOwner::UM_FourLineDisplay); if (!newSPI) { // was SPI but is no longer SPI - int8_t oldPins[] = {spi_sclk, spi_mosi}; - pinManager.deallocateMultiplePins((const uint8_t*)oldPins, 2, PinOwner::HW_SPI); - PinManagerPinType pins[2] = { {i2c_scl, true }, { i2c_sda, true } }; - if (i2c_scl==-1 || i2c_sda==-1 || !pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) { newType=NONE; } + if (i2c_scl<0 || i2c_sda<0) { newType=NONE; } } else { // still SPI but pins changed PinManagerPinType cspins[3] = { { ioPin[0], true }, { ioPin[1], true }, { ioPin[2], true } }; - if (ioPin[0]==-1 || ioPin[1]==-1 || ioPin[1]==-1) { newType=NONE; } + if (ioPin[0]<0 || ioPin[1]<0 || ioPin[1]<0) { newType=NONE; } else if (!pinManager.allocateMultiplePins(cspins, 3, PinOwner::UM_FourLineDisplay)) { newType=NONE; } } } else if (newSPI) { // was I2C but is now SPI - int8_t oldPins[] = {i2c_scl, i2c_sda}; - pinManager.deallocateMultiplePins((const uint8_t*)oldPins, 2, PinOwner::HW_I2C); - PinManagerPinType pins[3] = { { ioPin[0], true }, { ioPin[1], true }, { ioPin[2], true } }; - if (ioPin[0]==-1 || ioPin[1]==-1 || ioPin[1]==-1) { newType=NONE; } - else if (!pinManager.allocateMultiplePins(pins, 3, PinOwner::UM_FourLineDisplay)) { newType=NONE; } - else { - PinManagerPinType pins[2] = { { spi_sclk, true }, { spi_mosi, true } }; - if (spi_sclk==-1 || spi_mosi==-1 || !pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_SPI)) { - pinManager.deallocateMultiplePins(pins, 3, PinOwner::UM_FourLineDisplay); - newType = NONE; - } + if (spi_sclk<0 || spi_mosi<0) { + newType=NONE; + } else { + PinManagerPinType pins[3] = { { ioPin[0], true }, { ioPin[1], true }, { ioPin[2], true } }; + if (ioPin[0]<0 || ioPin[1]<0 || ioPin[1]<0) { newType=NONE; } + else if (!pinManager.allocateMultiplePins(pins, 3, PinOwner::UM_FourLineDisplay)) { newType=NONE; } } } else { - // just I2C tye changed + // just I2C type changed } type = newType; switch (type) { @@ -1369,8 +1353,12 @@ bool FourLineDisplayUsermod::readFromConfig(JsonObject& root) { u8x8_Setup(u8x8->getU8x8(), u8x8_d_ssd1306_128x64_noname, u8x8_cad_001, u8x8_byte_arduino_hw_spi, u8x8_gpio_and_delay_arduino); u8x8_SetPin_4Wire_HW_SPI(u8x8->getU8x8(), ioPin[0], ioPin[1], ioPin[2]); // Pins are cs, dc, reset break; + case SSD1309_SPI64: + u8x8_Setup(u8x8->getU8x8(), u8x8_d_ssd1309_128x64_noname0, u8x8_cad_001, u8x8_byte_arduino_hw_spi, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_4Wire_HW_SPI(u8x8->getU8x8(), ioPin[0], ioPin[1], ioPin[2]); // Pins are cs, dc, reset default: u8x8_Setup(u8x8->getU8x8(), u8x8_d_null_cb, u8x8_cad_empty, u8x8_byte_empty, u8x8_dummy_cb); + enabled = false; break; } startDisplay(); diff --git a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h index e1fd5f655..75494dedb 100644 --- a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h +++ b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h @@ -474,7 +474,7 @@ void RotaryEncoderUIUsermod::setup() DEBUG_PRINTLN(F("Usermod Rotary Encoder init.")); if (usePcf8574) { - if ((i2c_sda == i2c_scl && i2c_sda == -1) || pinA<0 || pinB<0 || pinC<0) { + if (i2c_sda < 0 || i2c_scl < 0 || pinA < 0 || pinB < 0 || pinC < 0) { DEBUG_PRINTLN(F("I2C and/or PCF8574 pins unused, disabling.")); enabled = false; return; diff --git a/wled00/wled.h b/wled00/wled.h index 01d26caf2..1846e0eaa 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2306180 +#define VERSION 2306210 //uncomment this if you have a "my_config.h" file you'd like to use //#define WLED_USE_MY_CONFIG