New SPI display SSD1309 for 4LD.
Fixed global I2C usage (no pin allocation in usermods). Enabled option dor Multi relay.
This commit is contained in:
parent
c04c73bbd7
commit
cf48ad06ed
@ -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"));
|
||||
|
@ -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())
|
||||
{
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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())
|
||||
|
@ -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
|
||||
|
@ -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; i<MULTI_RELAY_MAX_RELAYS; i++) {
|
||||
@ -765,7 +768,7 @@ bool MultiRelay::readFromConfig(JsonObject &root) {
|
||||
usePcf8574 = top[FPSTR(_pcf8574)] | usePcf8574;
|
||||
addrPcf8574 = top[FPSTR(_pcfAddress)] | addrPcf8574;
|
||||
// if I2C is not globally initialised just ignore
|
||||
if (i2c_sda == i2c_scl && i2c_sda == -1) usePcf8574 = false;
|
||||
if (i2c_sda<0 || i2c_scl<0) usePcf8574 = false;
|
||||
periodicBroadcastSec = top[FPSTR(_broadcast)] | periodicBroadcastSec;
|
||||
periodicBroadcastSec = min(900,max(0,(int)periodicBroadcastSec));
|
||||
HAautodiscovery = top[FPSTR(_HAautodiscovery)] | HAautodiscovery;
|
||||
|
@ -16,7 +16,6 @@ class ShtUsermod : public Usermod
|
||||
private:
|
||||
bool enabled = false; // Is usermod enabled or not
|
||||
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
|
||||
bool haMqttDiscovery = false; // Is MQTT discovery enabled or not
|
||||
bool haMqttDiscoveryDone = false; // Remembers if we already published the HA discovery topics
|
||||
@ -94,7 +93,7 @@ void ShtUsermod::initShtTempHumiditySensor()
|
||||
case USERMOD_SHT_TYPE_SHT85: shtTempHumidSensor = (SHT *) new SHT85(); break;
|
||||
}
|
||||
|
||||
shtTempHumidSensor->begin(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();
|
||||
|
||||
|
@ -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,'<br><i class=\"warn\">Change may require reboot</i>','');"));
|
||||
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();
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user