Pin manager enhancements (sharing I2C pins).
Effect helpers in UI.
This commit is contained in:
parent
65ac8d4b2b
commit
108fc4a0d8
@ -3,6 +3,14 @@
|
|||||||
#include "src/dependencies/time/DS1307RTC.h"
|
#include "src/dependencies/time/DS1307RTC.h"
|
||||||
#include "wled.h"
|
#include "wled.h"
|
||||||
|
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
#define HW_PIN_SCL 22
|
||||||
|
#define HW_PIN_SDA 21
|
||||||
|
#else
|
||||||
|
#define HW_PIN_SCL 5
|
||||||
|
#define HW_PIN_SDA 4
|
||||||
|
#endif
|
||||||
|
|
||||||
//Connect DS1307 to standard I2C pins (ESP32: GPIO 21 (SDA)/GPIO 22 (SCL))
|
//Connect DS1307 to standard I2C pins (ESP32: GPIO 21 (SDA)/GPIO 22 (SCL))
|
||||||
|
|
||||||
class RTCUsermod : public Usermod {
|
class RTCUsermod : public Usermod {
|
||||||
@ -12,6 +20,8 @@ class RTCUsermod : public Usermod {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
|
PinManagerPinType pins[2] = { { HW_PIN_SCL, true }, { HW_PIN_SDA, true } };
|
||||||
|
if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) { disabled = true; return; }
|
||||||
time_t rtcTime = RTC.get();
|
time_t rtcTime = RTC.get();
|
||||||
if (rtcTime) {
|
if (rtcTime) {
|
||||||
toki.setTime(rtcTime,TOKI_NO_MS_ACCURACY,TOKI_TS_RTC);
|
toki.setTime(rtcTime,TOKI_NO_MS_ACCURACY,TOKI_TS_RTC);
|
||||||
@ -28,6 +38,19 @@ class RTCUsermod : public Usermod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object.
|
||||||
|
* It will be called by WLED when settings are actually saved (for example, LED settings are saved)
|
||||||
|
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
||||||
|
*/
|
||||||
|
void addToConfig(JsonObject& root)
|
||||||
|
{
|
||||||
|
JsonObject top = root.createNestedObject("RTC");
|
||||||
|
JsonArray pins = top.createNestedArray("pin");
|
||||||
|
pins.add(HW_PIN_SCL);
|
||||||
|
pins.add(HW_PIN_SDA);
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t getId()
|
uint16_t getId()
|
||||||
{
|
{
|
||||||
return USERMOD_ID_RTC;
|
return USERMOD_ID_RTC;
|
||||||
|
@ -21,6 +21,14 @@
|
|||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
#include <VL53L0X.h>
|
#include <VL53L0X.h>
|
||||||
|
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
#define HW_PIN_SCL 22
|
||||||
|
#define HW_PIN_SDA 21
|
||||||
|
#else
|
||||||
|
#define HW_PIN_SCL 5
|
||||||
|
#define HW_PIN_SDA 4
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef VL53L0X_MAX_RANGE_MM
|
#ifndef VL53L0X_MAX_RANGE_MM
|
||||||
#define VL53L0X_MAX_RANGE_MM 230 // max height in millimiters to react for motions
|
#define VL53L0X_MAX_RANGE_MM 230 // max height in millimiters to react for motions
|
||||||
#endif
|
#endif
|
||||||
@ -42,6 +50,7 @@ class UsermodVL53L0XGestures : public Usermod {
|
|||||||
//Private class members. You can declare variables and functions only accessible to your usermod here
|
//Private class members. You can declare variables and functions only accessible to your usermod here
|
||||||
unsigned long lastTime = 0;
|
unsigned long lastTime = 0;
|
||||||
VL53L0X sensor;
|
VL53L0X sensor;
|
||||||
|
bool enabled = true;
|
||||||
|
|
||||||
bool wasMotionBefore = false;
|
bool wasMotionBefore = false;
|
||||||
bool isLongMotion = false;
|
bool isLongMotion = false;
|
||||||
@ -50,6 +59,8 @@ class UsermodVL53L0XGestures : public Usermod {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
|
PinManagerPinType pins[2] = { { HW_PIN_SCL, true }, { HW_PIN_SDA, true } };
|
||||||
|
if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) { enabled = false; return; }
|
||||||
Wire.begin();
|
Wire.begin();
|
||||||
|
|
||||||
sensor.setTimeout(150);
|
sensor.setTimeout(150);
|
||||||
@ -63,6 +74,7 @@ class UsermodVL53L0XGestures : public Usermod {
|
|||||||
|
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
if (!enabled) return;
|
||||||
if (millis() - lastTime > VL53L0X_DELAY_MS)
|
if (millis() - lastTime > VL53L0X_DELAY_MS)
|
||||||
{
|
{
|
||||||
lastTime = millis();
|
lastTime = millis();
|
||||||
@ -110,6 +122,19 @@ class UsermodVL53L0XGestures : public Usermod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object.
|
||||||
|
* It will be called by WLED when settings are actually saved (for example, LED settings are saved)
|
||||||
|
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
||||||
|
*/
|
||||||
|
void addToConfig(JsonObject& root)
|
||||||
|
{
|
||||||
|
JsonObject top = root.createNestedObject("VL53L0x");
|
||||||
|
JsonArray pins = top.createNestedArray("pin");
|
||||||
|
pins.add(HW_PIN_SCL);
|
||||||
|
pins.add(HW_PIN_SDA);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
|
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
|
||||||
* This could be used in the future for the system to determine whether your usermod is installed.
|
* This could be used in the future for the system to determine whether your usermod is installed.
|
||||||
|
@ -42,6 +42,14 @@
|
|||||||
#include "Wire.h"
|
#include "Wire.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
#define HW_PIN_SCL 22
|
||||||
|
#define HW_PIN_SDA 21
|
||||||
|
#else
|
||||||
|
#define HW_PIN_SCL 5
|
||||||
|
#define HW_PIN_SDA 4
|
||||||
|
#endif
|
||||||
|
|
||||||
// ================================================================
|
// ================================================================
|
||||||
// === INTERRUPT DETECTION ROUTINE ===
|
// === INTERRUPT DETECTION ROUTINE ===
|
||||||
// ================================================================
|
// ================================================================
|
||||||
@ -55,6 +63,7 @@ void IRAM_ATTR dmpDataReady() {
|
|||||||
class MPU6050Driver : public Usermod {
|
class MPU6050Driver : public Usermod {
|
||||||
private:
|
private:
|
||||||
MPU6050 mpu;
|
MPU6050 mpu;
|
||||||
|
bool enabled = true;
|
||||||
|
|
||||||
// MPU control/status vars
|
// MPU control/status vars
|
||||||
bool dmpReady = false; // set true if DMP init was successful
|
bool dmpReady = false; // set true if DMP init was successful
|
||||||
@ -84,6 +93,8 @@ class MPU6050Driver : public Usermod {
|
|||||||
* setup() is called once at boot. WiFi is not yet connected at this point.
|
* setup() is called once at boot. WiFi is not yet connected at this point.
|
||||||
*/
|
*/
|
||||||
void setup() {
|
void setup() {
|
||||||
|
PinManagerPinType pins[2] = { { HW_PIN_SCL, true }, { HW_PIN_SDA, true } };
|
||||||
|
if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) { enabled = false; return; }
|
||||||
// join I2C bus (I2Cdev library doesn't do this automatically)
|
// join I2C bus (I2Cdev library doesn't do this automatically)
|
||||||
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
|
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
|
||||||
Wire.begin();
|
Wire.begin();
|
||||||
@ -93,16 +104,16 @@ class MPU6050Driver : public Usermod {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// initialize device
|
// initialize device
|
||||||
Serial.println(F("Initializing I2C devices..."));
|
DEBUG_PRINTLN(F("Initializing I2C devices..."));
|
||||||
mpu.initialize();
|
mpu.initialize();
|
||||||
pinMode(INTERRUPT_PIN, INPUT);
|
pinMode(INTERRUPT_PIN, INPUT);
|
||||||
|
|
||||||
// verify connection
|
// verify connection
|
||||||
Serial.println(F("Testing device connections..."));
|
DEBUG_PRINTLN(F("Testing device connections..."));
|
||||||
Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
|
DEBUG_PRINTLN(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
|
||||||
|
|
||||||
// load and configure the DMP
|
// load and configure the DMP
|
||||||
Serial.println(F("Initializing DMP..."));
|
DEBUG_PRINTLN(F("Initializing DMP..."));
|
||||||
devStatus = mpu.dmpInitialize();
|
devStatus = mpu.dmpInitialize();
|
||||||
|
|
||||||
// supply your own gyro offsets here, scaled for min sensitivity
|
// supply your own gyro offsets here, scaled for min sensitivity
|
||||||
@ -114,16 +125,16 @@ class MPU6050Driver : public Usermod {
|
|||||||
// make sure it worked (returns 0 if so)
|
// make sure it worked (returns 0 if so)
|
||||||
if (devStatus == 0) {
|
if (devStatus == 0) {
|
||||||
// turn on the DMP, now that it's ready
|
// turn on the DMP, now that it's ready
|
||||||
Serial.println(F("Enabling DMP..."));
|
DEBUG_PRINTLN(F("Enabling DMP..."));
|
||||||
mpu.setDMPEnabled(true);
|
mpu.setDMPEnabled(true);
|
||||||
|
|
||||||
// enable Arduino interrupt detection
|
// enable Arduino interrupt detection
|
||||||
Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
|
DEBUG_PRINTLN(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
|
||||||
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
|
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
|
||||||
mpuIntStatus = mpu.getIntStatus();
|
mpuIntStatus = mpu.getIntStatus();
|
||||||
|
|
||||||
// set our DMP Ready flag so the main loop() function knows it's okay to use it
|
// set our DMP Ready flag so the main loop() function knows it's okay to use it
|
||||||
Serial.println(F("DMP ready! Waiting for first interrupt..."));
|
DEBUG_PRINTLN(F("DMP ready! Waiting for first interrupt..."));
|
||||||
dmpReady = true;
|
dmpReady = true;
|
||||||
|
|
||||||
// get expected DMP packet size for later comparison
|
// get expected DMP packet size for later comparison
|
||||||
@ -133,9 +144,9 @@ class MPU6050Driver : public Usermod {
|
|||||||
// 1 = initial memory load failed
|
// 1 = initial memory load failed
|
||||||
// 2 = DMP configuration updates failed
|
// 2 = DMP configuration updates failed
|
||||||
// (if it's going to break, usually the code will be 1)
|
// (if it's going to break, usually the code will be 1)
|
||||||
Serial.print(F("DMP Initialization failed (code "));
|
DEBUG_PRINT(F("DMP Initialization failed (code "));
|
||||||
Serial.print(devStatus);
|
DEBUG_PRINT(devStatus);
|
||||||
Serial.println(F(")"));
|
DEBUG_PRINTLN(F(")"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +155,7 @@ class MPU6050Driver : public Usermod {
|
|||||||
* Use it to initialize network interfaces
|
* Use it to initialize network interfaces
|
||||||
*/
|
*/
|
||||||
void connected() {
|
void connected() {
|
||||||
//Serial.println("Connected to WiFi!");
|
//DEBUG_PRINTLN("Connected to WiFi!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -153,7 +164,7 @@ class MPU6050Driver : public Usermod {
|
|||||||
*/
|
*/
|
||||||
void loop() {
|
void loop() {
|
||||||
// if programming failed, don't try to do anything
|
// if programming failed, don't try to do anything
|
||||||
if (!dmpReady) return;
|
if (!enabled || !dmpReady) return;
|
||||||
|
|
||||||
// wait for MPU interrupt or extra packet(s) available
|
// wait for MPU interrupt or extra packet(s) available
|
||||||
if (!mpuInterrupt && fifoCount < packetSize) return;
|
if (!mpuInterrupt && fifoCount < packetSize) return;
|
||||||
@ -169,7 +180,7 @@ class MPU6050Driver : public Usermod {
|
|||||||
if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
|
if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
|
||||||
// reset so we can continue cleanly
|
// reset so we can continue cleanly
|
||||||
mpu.resetFIFO();
|
mpu.resetFIFO();
|
||||||
Serial.println(F("FIFO overflow!"));
|
DEBUG_PRINTLN(F("FIFO overflow!"));
|
||||||
|
|
||||||
// otherwise, check for DMP data ready interrupt (this should happen frequently)
|
// otherwise, check for DMP data ready interrupt (this should happen frequently)
|
||||||
} else if (mpuIntStatus & 0x02) {
|
} else if (mpuIntStatus & 0x02) {
|
||||||
@ -259,10 +270,23 @@ class MPU6050Driver : public Usermod {
|
|||||||
*/
|
*/
|
||||||
void readFromJsonState(JsonObject& root)
|
void readFromJsonState(JsonObject& root)
|
||||||
{
|
{
|
||||||
//if (root["bri"] == 255) Serial.println(F("Don't burn down your garage!"));
|
//if (root["bri"] == 255) DEBUG_PRINTLN(F("Don't burn down your garage!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object.
|
||||||
|
* It will be called by WLED when settings are actually saved (for example, LED settings are saved)
|
||||||
|
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
||||||
|
*/
|
||||||
|
void addToConfig(JsonObject& root)
|
||||||
|
{
|
||||||
|
JsonObject top = root.createNestedObject("MPU6050_IMU");
|
||||||
|
JsonArray pins = top.createNestedArray("pin");
|
||||||
|
pins.add(HW_PIN_SCL);
|
||||||
|
pins.add(HW_PIN_SDA);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
|
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
|
||||||
*/
|
*/
|
||||||
|
@ -25,6 +25,10 @@
|
|||||||
|
|
||||||
//The SCL and SDA pins are defined here.
|
//The SCL and SDA pins are defined here.
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
#define HW_PIN_SCL 22
|
||||||
|
#define HW_PIN_SDA 21
|
||||||
|
#define HW_PIN_CLOCKSPI 18
|
||||||
|
#define HW_PIN_DATASPI 23
|
||||||
#ifndef FLD_PIN_SCL
|
#ifndef FLD_PIN_SCL
|
||||||
#define FLD_PIN_SCL 22
|
#define FLD_PIN_SCL 22
|
||||||
#endif
|
#endif
|
||||||
@ -47,6 +51,10 @@
|
|||||||
#define FLD_PIN_RESET 26
|
#define FLD_PIN_RESET 26
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
|
#define HW_PIN_SCL 5
|
||||||
|
#define HW_PIN_SDA 4
|
||||||
|
#define HW_PIN_CLOCKSPI 14
|
||||||
|
#define HW_PIN_DATASPI 13
|
||||||
#ifndef FLD_PIN_SCL
|
#ifndef FLD_PIN_SCL
|
||||||
#define FLD_PIN_SCL 5
|
#define FLD_PIN_SCL 5
|
||||||
#endif
|
#endif
|
||||||
@ -172,80 +180,64 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
// network here
|
// network here
|
||||||
void setup() {
|
void setup() {
|
||||||
if (type == NONE || !enabled) return;
|
if (type == NONE || !enabled) return;
|
||||||
|
|
||||||
|
bool isHW;
|
||||||
|
PinOwner po = PinOwner::UM_FourLineDisplay;
|
||||||
if (type == SSD1306_SPI || type == SSD1306_SPI64) {
|
if (type == SSD1306_SPI || type == SSD1306_SPI64) {
|
||||||
|
isHW = (ioPin[0]==HW_PIN_CLOCKSPI && ioPin[1]==HW_PIN_DATASPI);
|
||||||
PinManagerPinType pins[5] = { { ioPin[0], true }, { ioPin[1], true }, { ioPin[2], true }, { ioPin[3], true }, { ioPin[4], true }};
|
PinManagerPinType pins[5] = { { ioPin[0], true }, { ioPin[1], true }, { ioPin[2], true }, { ioPin[3], true }, { ioPin[4], true }};
|
||||||
if (!pinManager.allocateMultiplePins(pins, 5, PinOwner::UM_FourLineDisplay)) { type=NONE; return; }
|
if (!pinManager.allocateMultiplePins(pins, 5, po)) { type=NONE; return; }
|
||||||
} else {
|
} else {
|
||||||
|
isHW = (ioPin[0]==HW_PIN_SCL && ioPin[1]==HW_PIN_SDA);
|
||||||
PinManagerPinType pins[2] = { { ioPin[0], true }, { ioPin[1], true } };
|
PinManagerPinType pins[2] = { { ioPin[0], true }, { ioPin[1], true } };
|
||||||
if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::UM_FourLineDisplay)) { type=NONE; return; }
|
if (ioPin[0]==HW_PIN_SCL && ioPin[1]==HW_PIN_SDA) po = PinOwner::HW_I2C; // allow multiple allocations of HW I2C bus pins
|
||||||
|
if (!pinManager.allocateMultiplePins(pins, 2, po)) { type=NONE; return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_PRINTLN(F("Allocating display."));
|
DEBUG_PRINTLN(F("Allocating display."));
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SSD1306:
|
case SSD1306:
|
||||||
#ifdef ESP8266
|
if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
||||||
if (!(ioPin[0]==5 && ioPin[1]==4))
|
else u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
|
||||||
lineHeight = 1;
|
lineHeight = 1;
|
||||||
break;
|
break;
|
||||||
case SH1106:
|
case SH1106:
|
||||||
#ifdef ESP8266
|
if (!isHW) u8x8 = (U8X8 *) new U8X8_SH1106_128X64_WINSTAR_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
||||||
if (!(ioPin[0]==5 && ioPin[1]==4))
|
else u8x8 = (U8X8 *) new U8X8_SH1106_128X64_WINSTAR_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
||||||
u8x8 = (U8X8 *) new U8X8_SH1106_128X64_WINSTAR_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
u8x8 = (U8X8 *) new U8X8_SH1106_128X64_WINSTAR_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
|
||||||
lineHeight = 2;
|
lineHeight = 2;
|
||||||
break;
|
break;
|
||||||
case SSD1306_64:
|
case SSD1306_64:
|
||||||
#ifdef ESP8266
|
if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
||||||
if (!(ioPin[0]==5 && ioPin[1]==4))
|
else u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
|
||||||
lineHeight = 2;
|
lineHeight = 2;
|
||||||
break;
|
break;
|
||||||
case SSD1305:
|
case SSD1305:
|
||||||
#ifdef ESP8266
|
if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1305_128X32_NONAME_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
||||||
if (!(ioPin[0]==5 && ioPin[1]==4))
|
else u8x8 = (U8X8 *) new U8X8_SSD1305_128X32_ADAFRUIT_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1305_128X32_NONAME_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1305_128X32_ADAFRUIT_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
|
||||||
lineHeight = 1;
|
lineHeight = 1;
|
||||||
break;
|
break;
|
||||||
case SSD1305_64:
|
case SSD1305_64:
|
||||||
#ifdef ESP8266
|
if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1305_128X64_ADAFRUIT_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
||||||
if (!(ioPin[0]==5 && ioPin[1]==4))
|
else u8x8 = (U8X8 *) new U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1305_128X64_ADAFRUIT_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
|
||||||
lineHeight = 2;
|
lineHeight = 2;
|
||||||
break;
|
break;
|
||||||
case SSD1306_SPI:
|
case SSD1306_SPI:
|
||||||
if (!(ioPin[0]==FLD_PIN_CLOCKSPI && ioPin[1]==FLD_PIN_DATASPI)) // if not overridden these sould be HW accellerated
|
if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_4W_SW_SPI(ioPin[0], ioPin[1], ioPin[2], ioPin[3], ioPin[4]);
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_4W_SW_SPI(ioPin[0], ioPin[1], ioPin[2], ioPin[3], ioPin[4]);
|
else u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_4W_HW_SPI(ioPin[2], ioPin[3], ioPin[4]); // Pins are cs, dc, reset
|
||||||
else
|
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_4W_HW_SPI(ioPin[2], ioPin[3], ioPin[4]); // Pins are cs, dc, reset
|
|
||||||
lineHeight = 1;
|
lineHeight = 1;
|
||||||
break;
|
break;
|
||||||
case SSD1306_SPI64:
|
case SSD1306_SPI64:
|
||||||
if (!(ioPin[0]==FLD_PIN_CLOCKSPI && ioPin[1]==FLD_PIN_DATASPI)) // if not overridden these sould be HW accellerated
|
if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_SW_SPI(ioPin[0], ioPin[1], ioPin[2], ioPin[3], ioPin[4]);
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_SW_SPI(ioPin[0], ioPin[1], ioPin[2], ioPin[3], ioPin[4]);
|
else u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_HW_SPI(ioPin[2], ioPin[3], ioPin[4]); // Pins are cs, dc, reset
|
||||||
else
|
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_HW_SPI(ioPin[2], ioPin[3], ioPin[4]); // Pins are cs, dc, reset
|
|
||||||
lineHeight = 2;
|
lineHeight = 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
u8x8 = nullptr;
|
u8x8 = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nullptr == u8x8) {
|
if (nullptr == u8x8) {
|
||||||
DEBUG_PRINTLN(F("Display init failed."));
|
DEBUG_PRINTLN(F("Display init failed."));
|
||||||
for (byte i=0; i<5 && ioPin[i]>=0; i++) pinManager.deallocatePin(ioPin[i], PinOwner::UM_FourLineDisplay);
|
pinManager.deallocateMultiplePins((const uint8_t*)ioPin, (type == SSD1306_SPI || type == SSD1306_SPI64) ? 5 : 2, po);
|
||||||
type = NONE;
|
type = NONE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -714,10 +706,10 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
for (byte i=0; i<5; i++) if (ioPin[i] != newPin[i]) { pinsChanged = true; break; }
|
for (byte i=0; i<5; i++) if (ioPin[i] != newPin[i]) { pinsChanged = true; break; }
|
||||||
if (pinsChanged || type!=newType) {
|
if (pinsChanged || type!=newType) {
|
||||||
if (type != NONE) delete u8x8;
|
if (type != NONE) delete u8x8;
|
||||||
for (byte i=0; i<5; i++) {
|
PinOwner po = PinOwner::UM_FourLineDisplay;
|
||||||
if (ioPin[i]>=0) pinManager.deallocatePin(ioPin[i], PinOwner::UM_FourLineDisplay);
|
if (ioPin[0]==HW_PIN_SCL && ioPin[1]==HW_PIN_SDA) po = PinOwner::HW_I2C; // allow multiple allocations of HW I2C bus pins
|
||||||
ioPin[i] = newPin[i];
|
pinManager.deallocateMultiplePins((const uint8_t *)ioPin, (type == SSD1306_SPI || type == SSD1306_SPI64) ? 5 : 2, po);
|
||||||
}
|
for (byte i=0; i<5; i++) ioPin[i] = newPin[i];
|
||||||
if (ioPin[0]<0 || ioPin[1]<0) { // data & clock must be > -1
|
if (ioPin[0]<0 || ioPin[1]<0) { // data & clock must be > -1
|
||||||
type = NONE;
|
type = NONE;
|
||||||
return true;
|
return true;
|
||||||
|
50
wled00/FX.h
50
wled00/FX.h
@ -932,7 +932,7 @@ class WS2812FX {
|
|||||||
const char JSON_mode_names[] PROGMEM = R"=====([
|
const char JSON_mode_names[] PROGMEM = R"=====([
|
||||||
"Solid",
|
"Solid",
|
||||||
"Blink@;!;!",
|
"Blink@;!;!",
|
||||||
"Breathe@Speed;,!;!",
|
"Breathe@!,;,!;!",
|
||||||
"Wipe",
|
"Wipe",
|
||||||
"Wipe Random",
|
"Wipe Random",
|
||||||
"Random Colors",
|
"Random Colors",
|
||||||
@ -940,13 +940,12 @@ const char JSON_mode_names[] PROGMEM = R"=====([
|
|||||||
"Dynamic",
|
"Dynamic",
|
||||||
"Colorloop",
|
"Colorloop",
|
||||||
"Rainbow",
|
"Rainbow",
|
||||||
"Scan@!,# of dots;,!,?;!",
|
"Scan@!,# of dots;,!,;!",
|
||||||
"Scan Dual@!,# of dots;,!,?;!",
|
"Scan Dual@!,# of dots;,!,;!",
|
||||||
"Fade",
|
"Fade","Theater",
|
||||||
"Theater",
|
|
||||||
"Theater Rainbow",
|
"Theater Rainbow",
|
||||||
"Running",
|
"Running@!,Wave width;!,!,;!",
|
||||||
"Saw",
|
"Saw@!,Width;Fx,Bg,;!",
|
||||||
"Twinkle",
|
"Twinkle",
|
||||||
"Dissolve",
|
"Dissolve",
|
||||||
"Dissolve Rnd",
|
"Dissolve Rnd",
|
||||||
@ -967,24 +966,24 @@ const char JSON_mode_names[] PROGMEM = R"=====([
|
|||||||
"Colorful",
|
"Colorful",
|
||||||
"Traffic Light",
|
"Traffic Light",
|
||||||
"Sweep Random",
|
"Sweep Random",
|
||||||
"Running 2",
|
"Running 2@!,Width;;!",
|
||||||
"Aurora",
|
"Aurora",
|
||||||
"Stream",
|
"Stream",
|
||||||
"Scanner",
|
"Scanner",
|
||||||
"Lighthouse",
|
"Lighthouse",
|
||||||
"Fireworks",
|
"Fireworks",
|
||||||
"Rain",
|
"Rain",
|
||||||
"Tetrix@Speed,Width;Fx,BG,;!",
|
"Tetrix@!,Width;Fx,Bg,;!",
|
||||||
"Fire Flicker",
|
"Fire Flicker",
|
||||||
"Gradient",
|
"Gradient",
|
||||||
"Loading",
|
"Loading",
|
||||||
"Police",
|
"Police@!,Width;;",
|
||||||
"Police All",
|
"Police All@!,Width;;",
|
||||||
"Two Dots",
|
"Two Dots@!,Dot size;,,Bg;!",
|
||||||
"Two Areas",
|
"Two Areas@!,Size;,,Bg;!",
|
||||||
"Running Dual",
|
"Running Dual",
|
||||||
"Halloween",
|
"Halloween",
|
||||||
"Tri Chase",
|
"Tri Chase@!,Size;;",
|
||||||
"Tri Wipe",
|
"Tri Wipe",
|
||||||
"Tri Fade",
|
"Tri Fade",
|
||||||
"Lightning",
|
"Lightning",
|
||||||
@ -994,9 +993,9 @@ const char JSON_mode_names[] PROGMEM = R"=====([
|
|||||||
"Stream 2",
|
"Stream 2",
|
||||||
"Oscillate",
|
"Oscillate",
|
||||||
"Pride 2015",
|
"Pride 2015",
|
||||||
"Juggle",
|
"Juggle@!,Trail;Fx,Bg,;!",
|
||||||
"Palette",
|
"Palette@!,;;!",
|
||||||
"Fire 2012",
|
"Fire 2012@Spark rate,Decay;!;!",
|
||||||
"Colorwaves",
|
"Colorwaves",
|
||||||
"Bpm",
|
"Bpm",
|
||||||
"Fill Noise",
|
"Fill Noise",
|
||||||
@ -1013,15 +1012,15 @@ const char JSON_mode_names[] PROGMEM = R"=====([
|
|||||||
"Twinklefox",
|
"Twinklefox",
|
||||||
"Twinklecat",
|
"Twinklecat",
|
||||||
"Halloween Eyes",
|
"Halloween Eyes",
|
||||||
"Solid Pattern",
|
"Solid Pattern@Fg size,Bg size;Fg,Bg,;",
|
||||||
"Solid Pattern Tri",
|
"Solid Pattern Tri@,Size;;",
|
||||||
"Spots",
|
"Spots",
|
||||||
"Spots Fade",
|
"Spots Fade",
|
||||||
"Glitter",
|
"Glitter",
|
||||||
"Candle",
|
"Candle@Flicker rate,Flicker intensity;Fx,Bg,;",
|
||||||
"Fireworks Starburst",
|
"Fireworks Starburst",
|
||||||
"Fireworks 1D@Gravity,Firing side;;!",
|
"Fireworks 1D@Gravity,Firing side;;!",
|
||||||
"Bouncing Balls",
|
"Bouncing Balls@Gravity,# of balls;Fx,Bg,;!",
|
||||||
"Sinelon",
|
"Sinelon",
|
||||||
"Sinelon Dual",
|
"Sinelon Dual",
|
||||||
"Sinelon Rainbow",
|
"Sinelon Rainbow",
|
||||||
@ -1032,16 +1031,15 @@ const char JSON_mode_names[] PROGMEM = R"=====([
|
|||||||
"Ripple Rainbow",
|
"Ripple Rainbow",
|
||||||
"Heartbeat",
|
"Heartbeat",
|
||||||
"Pacifica",
|
"Pacifica",
|
||||||
"Candle Multi",
|
"Candle Multi@Flicker rate,Flicker intensity;Fx,Bg,;",
|
||||||
"Solid Glitter",
|
"Solid Glitter",
|
||||||
"Sunrise",
|
"Sunrise@Time [min],;!;",
|
||||||
"Phased",
|
"Phased","Twinkleup@Speed,Intensity;,!;!",
|
||||||
"Twinkleup@Speed,Intensity,Min;,!;!",
|
|
||||||
"Noise Pal",
|
"Noise Pal",
|
||||||
"Sine",
|
"Sine",
|
||||||
"Phased Noise",
|
"Phased Noise",
|
||||||
"Flow",
|
"Flow",
|
||||||
"Chunchun",
|
"Chunchun@!,Gap size;Fg,Bg,;!",
|
||||||
"Dancing Shadows",
|
"Dancing Shadows",
|
||||||
"Washing Machine",
|
"Washing Machine",
|
||||||
"Candy Cane",
|
"Candy Cane",
|
||||||
|
@ -134,7 +134,8 @@ bool deserializeState(JsonObject root, byte callMode = CALL_MODE_DIRECT_CHANGE,
|
|||||||
void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool forPreset = false, bool segmentBounds = true);
|
void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool forPreset = false, bool segmentBounds = true);
|
||||||
void serializeState(JsonObject root, bool forPreset = false, bool includeBri = true, bool segmentBounds = true);
|
void serializeState(JsonObject root, bool forPreset = false, bool includeBri = true, bool segmentBounds = true);
|
||||||
void serializeInfo(JsonObject root);
|
void serializeInfo(JsonObject root);
|
||||||
void serializeSRNames(JsonArray arr, const char *qstring);
|
void serializeModeNames(JsonArray arr, const char *qstring);
|
||||||
|
void serializeModeData(JsonObject root);
|
||||||
uint8_t extractModeName(uint8_t mode, const char *src, char *dest, uint8_t maxLen);
|
uint8_t extractModeName(uint8_t mode, const char *src, char *dest, uint8_t maxLen);
|
||||||
void serveJson(AsyncWebServerRequest* request);
|
void serveJson(AsyncWebServerRequest* request);
|
||||||
bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient = 0);
|
bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient = 0);
|
||||||
|
@ -813,15 +813,50 @@ void serializeNodes(JsonObject root)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// deserializes mode names string into JsonArray
|
void serializeModeData(JsonObject root)
|
||||||
// also removes WLED-SR extensions (@...) from deserialised names
|
{
|
||||||
void deserializeModeNames(JsonArray arr, const char *qstring) {
|
JsonArray fxdata = root.createNestedArray("fxdata");
|
||||||
String lineBuffer;
|
String lineBuffer;
|
||||||
bool insideQuotes = false;
|
bool insideQuotes = false;
|
||||||
char singleJsonSymbol;
|
char singleJsonSymbol;
|
||||||
|
size_t len = strlen_P(JSON_mode_names);
|
||||||
|
|
||||||
// Find the mode name in JSON
|
// Find the mode name in JSON
|
||||||
for (size_t i = 0; i < strlen_P(qstring); i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
singleJsonSymbol = pgm_read_byte_near(JSON_mode_names + i);
|
||||||
|
if (singleJsonSymbol == '\0') break;
|
||||||
|
switch (singleJsonSymbol) {
|
||||||
|
case '"':
|
||||||
|
insideQuotes = !insideQuotes;
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
break;
|
||||||
|
case ']':
|
||||||
|
case ',':
|
||||||
|
if (lineBuffer.length() > 0) {
|
||||||
|
uint8_t endPos = lineBuffer.indexOf('@');
|
||||||
|
if (endPos>0) fxdata.add(lineBuffer.substring(endPos));
|
||||||
|
else fxdata.add("");
|
||||||
|
lineBuffer.clear();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (!insideQuotes) break;
|
||||||
|
lineBuffer += singleJsonSymbol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// deserializes mode names string into JsonArray
|
||||||
|
// also removes WLED-SR extensions (@...) from deserialised names
|
||||||
|
void serializeModeNames(JsonArray arr, const char *qstring) {
|
||||||
|
String lineBuffer;
|
||||||
|
bool insideQuotes = false;
|
||||||
|
char singleJsonSymbol;
|
||||||
|
size_t len = strlen_P(qstring);
|
||||||
|
|
||||||
|
// Find the mode name in JSON
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
singleJsonSymbol = pgm_read_byte_near(qstring + i);
|
singleJsonSymbol = pgm_read_byte_near(qstring + i);
|
||||||
if (singleJsonSymbol == '\0') break;
|
if (singleJsonSymbol == '\0') break;
|
||||||
switch (singleJsonSymbol) {
|
switch (singleJsonSymbol) {
|
||||||
@ -854,9 +889,10 @@ uint8_t extractModeName(uint8_t mode, const char *src, char *dest, uint8_t maxLe
|
|||||||
bool insideQuotes = false;
|
bool insideQuotes = false;
|
||||||
uint8_t printedChars = 0;
|
uint8_t printedChars = 0;
|
||||||
char singleJsonSymbol;
|
char singleJsonSymbol;
|
||||||
|
size_t len = strlen_P(src);
|
||||||
|
|
||||||
// Find the mode name in JSON
|
// Find the mode name in JSON
|
||||||
for (size_t i = 0; i < strlen_P(src); i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
singleJsonSymbol = pgm_read_byte_near(src + i);
|
singleJsonSymbol = pgm_read_byte_near(src + i);
|
||||||
if (singleJsonSymbol == '\0') break;
|
if (singleJsonSymbol == '\0') break;
|
||||||
switch (singleJsonSymbol) {
|
switch (singleJsonSymbol) {
|
||||||
@ -889,6 +925,7 @@ void serveJson(AsyncWebServerRequest* request)
|
|||||||
else if (url.indexOf("si") > 0) subJson = 3;
|
else if (url.indexOf("si") > 0) subJson = 3;
|
||||||
else if (url.indexOf("nodes") > 0) subJson = 4;
|
else if (url.indexOf("nodes") > 0) subJson = 4;
|
||||||
else if (url.indexOf("palx") > 0) subJson = 5;
|
else if (url.indexOf("palx") > 0) subJson = 5;
|
||||||
|
else if (url.indexOf("fxda") > 0) subJson = 6;
|
||||||
else if (url.indexOf("live") > 0) {
|
else if (url.indexOf("live") > 0) {
|
||||||
serveLiveLeds(request);
|
serveLiveLeds(request);
|
||||||
return;
|
return;
|
||||||
@ -936,6 +973,8 @@ void serveJson(AsyncWebServerRequest* request)
|
|||||||
serializeNodes(lDoc); break;
|
serializeNodes(lDoc); break;
|
||||||
case 5: //palettes
|
case 5: //palettes
|
||||||
serializePalettes(lDoc, request); break;
|
serializePalettes(lDoc, request); break;
|
||||||
|
case 6: // FX helper data
|
||||||
|
serializeModeData(lDoc); break;
|
||||||
default: //all
|
default: //all
|
||||||
JsonObject state = lDoc.createNestedObject("state");
|
JsonObject state = lDoc.createNestedObject("state");
|
||||||
serializeState(state);
|
serializeState(state);
|
||||||
@ -945,7 +984,7 @@ void serveJson(AsyncWebServerRequest* request)
|
|||||||
{
|
{
|
||||||
//lDoc[F("effects")] = serialized((const __FlashStringHelper*)JSON_mode_names);
|
//lDoc[F("effects")] = serialized((const __FlashStringHelper*)JSON_mode_names);
|
||||||
JsonArray effects = lDoc.createNestedArray(F("effects"));
|
JsonArray effects = lDoc.createNestedArray(F("effects"));
|
||||||
deserializeModeNames(effects, JSON_mode_names); // remove WLED-SR extensions from effect names
|
serializeModeNames(effects, JSON_mode_names); // remove WLED-SR extensions from effect names
|
||||||
lDoc[F("palettes")] = serialized((const __FlashStringHelper*)JSON_palette_names);
|
lDoc[F("palettes")] = serialized((const __FlashStringHelper*)JSON_palette_names);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,48 @@ bool PinManagerClass::deallocatePin(byte gpio, PinOwner tag)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// support function for deallocating multiple pins
|
||||||
|
bool PinManagerClass::deallocateMultiplePins(const uint8_t *pinArray, byte arrayElementCount, PinOwner tag)
|
||||||
|
{
|
||||||
|
bool shouldFail = false;
|
||||||
|
DEBUG_PRINTLN(F("MULTIPIN DEALLOC"));
|
||||||
|
// first verify the pins are OK and allocated by selected owner
|
||||||
|
for (int i = 0; i < arrayElementCount; i++) {
|
||||||
|
byte gpio = pinArray[i];
|
||||||
|
if (gpio == 0xFF) {
|
||||||
|
// explicit support for io -1 as a no-op (no allocation of pin),
|
||||||
|
// as this can greatly simplify configuration arrays
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (isPinAllocated(gpio, tag)) {
|
||||||
|
// if the current pin is allocated by selected owner it is possible to release it
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#ifdef WLED_DEBUG
|
||||||
|
DEBUG_PRINT(F("PIN DEALLOC: IO "));
|
||||||
|
DEBUG_PRINT(gpio);
|
||||||
|
DEBUG_PRINT(F(" allocated by "));
|
||||||
|
DebugPrintOwnerTag(ownerTag[gpio]);
|
||||||
|
DEBUG_PRINT(F(", but attempted de-allocation by "));
|
||||||
|
DebugPrintOwnerTag(tag);
|
||||||
|
#endif
|
||||||
|
shouldFail = true;
|
||||||
|
}
|
||||||
|
if (shouldFail) {
|
||||||
|
return false; // no pins deallocated
|
||||||
|
}
|
||||||
|
if (tag==PinOwner::HW_I2C) {
|
||||||
|
if (i2cAllocCount && --i2cAllocCount>0) {
|
||||||
|
// no deallocation done until last owner releases pins
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < arrayElementCount; i++) {
|
||||||
|
deallocatePin(pinArray[i], tag);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool PinManagerClass::allocateMultiplePins(const managed_pin_type * mptArray, byte arrayElementCount, PinOwner tag)
|
bool PinManagerClass::allocateMultiplePins(const managed_pin_type * mptArray, byte arrayElementCount, PinOwner tag)
|
||||||
{
|
{
|
||||||
bool shouldFail = false;
|
bool shouldFail = false;
|
||||||
@ -58,7 +100,10 @@ bool PinManagerClass::allocateMultiplePins(const managed_pin_type * mptArray, by
|
|||||||
#endif
|
#endif
|
||||||
shouldFail = true;
|
shouldFail = true;
|
||||||
}
|
}
|
||||||
if (isPinAllocated(gpio)) {
|
if (tag==PinOwner::HW_I2C && isPinAllocated(gpio, tag)) {
|
||||||
|
// allow multiple "allocations" of HW I2C bus pins
|
||||||
|
continue;
|
||||||
|
} else if (isPinAllocated(gpio)) {
|
||||||
#ifdef WLED_DEBUG
|
#ifdef WLED_DEBUG
|
||||||
DEBUG_PRINT(F("PIN ALLOC: FAIL: IO "));
|
DEBUG_PRINT(F("PIN ALLOC: FAIL: IO "));
|
||||||
DEBUG_PRINT(gpio);
|
DEBUG_PRINT(gpio);
|
||||||
@ -73,6 +118,8 @@ bool PinManagerClass::allocateMultiplePins(const managed_pin_type * mptArray, by
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tag==PinOwner::HW_I2C) i2cAllocCount++;
|
||||||
|
|
||||||
// all pins are available .. track each one
|
// all pins are available .. track each one
|
||||||
for (int i = 0; i < arrayElementCount; i++) {
|
for (int i = 0; i < arrayElementCount; i++) {
|
||||||
byte gpio = mptArray[i].pin;
|
byte gpio = mptArray[i].pin;
|
||||||
@ -91,7 +138,8 @@ bool PinManagerClass::allocateMultiplePins(const managed_pin_type * mptArray, by
|
|||||||
|
|
||||||
bool PinManagerClass::allocatePin(byte gpio, bool output, PinOwner tag)
|
bool PinManagerClass::allocatePin(byte gpio, bool output, PinOwner tag)
|
||||||
{
|
{
|
||||||
if (!isPinOk(gpio, output)) return false;
|
// HW I2C pins have to be allocated using allocateMultiplePins variant since there is always SCL/SDA pair
|
||||||
|
if (!isPinOk(gpio, output) || tag==PinOwner::HW_I2C) return false;
|
||||||
if (isPinAllocated(gpio)) {
|
if (isPinAllocated(gpio)) {
|
||||||
#ifdef WLED_DEBUG
|
#ifdef WLED_DEBUG
|
||||||
DEBUG_PRINT(F("PIN ALLOC: Pin "));
|
DEBUG_PRINT(F("PIN ALLOC: Pin "));
|
||||||
|
@ -33,26 +33,27 @@ enum struct PinOwner : uint8_t {
|
|||||||
SPI_RAM = 0x88, // 'SpiR' == SPI RAM
|
SPI_RAM = 0x88, // 'SpiR' == SPI RAM
|
||||||
DebugOut = 0x89, // 'Dbg' == debug output always IO1
|
DebugOut = 0x89, // 'Dbg' == debug output always IO1
|
||||||
DMX = 0x8A, // 'DMX' == hard-coded to IO2
|
DMX = 0x8A, // 'DMX' == hard-coded to IO2
|
||||||
|
HW_I2C = 0x8B, // 'I2C' == hardware I2C pins (4&5 on ESP8266, 21&22 on ESP32)
|
||||||
// Use UserMod IDs from const.h here
|
// Use UserMod IDs from const.h here
|
||||||
UM_Unspecified = USERMOD_ID_UNSPECIFIED, // 0x01
|
UM_Unspecified = USERMOD_ID_UNSPECIFIED, // 0x01
|
||||||
UM_Example = USERMOD_ID_EXAMPLE, // 0x02 // Usermod "usermod_v2_example.h"
|
UM_Example = USERMOD_ID_EXAMPLE, // 0x02 // Usermod "usermod_v2_example.h"
|
||||||
UM_Temperature = USERMOD_ID_TEMPERATURE, // 0x03 // Usermod "usermod_temperature.h"
|
UM_Temperature = USERMOD_ID_TEMPERATURE, // 0x03 // Usermod "usermod_temperature.h"
|
||||||
// #define USERMOD_ID_FIXNETSERVICES // 0x04 // Usermod "usermod_Fix_unreachable_netservices.h" -- Does not allocate pins
|
// #define USERMOD_ID_FIXNETSERVICES // 0x04 // Usermod "usermod_Fix_unreachable_netservices.h" -- Does not allocate pins
|
||||||
UM_PIR = USERMOD_ID_PIRSWITCH, // 0x05 // Usermod "usermod_PIR_sensor_switch.h"
|
UM_PIR = USERMOD_ID_PIRSWITCH, // 0x05 // Usermod "usermod_PIR_sensor_switch.h"
|
||||||
// #define USERMOD_ID_IMU // 0x06 // Usermod "usermod_mpu6050_imu.h" -- Uses "standard" I2C pins ... TODO -- enable shared I2C bus use
|
// #define USERMOD_ID_IMU // 0x06 // Usermod "usermod_mpu6050_imu.h" -- Uses "standard" HW_I2C pins
|
||||||
UM_FourLineDisplay = USERMOD_ID_FOUR_LINE_DISP, // 0x07 // Usermod "usermod_v2_four_line_display.h
|
UM_FourLineDisplay = USERMOD_ID_FOUR_LINE_DISP, // 0x07 // Usermod "usermod_v2_four_line_display.h -- May use "standard" HW_I2C pins
|
||||||
UM_RotaryEncoderUI = USERMOD_ID_ROTARY_ENC_UI, // 0x08 // Usermod "usermod_v2_rotary_encoder_ui.h"
|
UM_RotaryEncoderUI = USERMOD_ID_ROTARY_ENC_UI, // 0x08 // Usermod "usermod_v2_rotary_encoder_ui.h"
|
||||||
// #define USERMOD_ID_AUTO_SAVE // 0x09 // Usermod "usermod_v2_auto_save.h" -- Does not allocate pins
|
// #define USERMOD_ID_AUTO_SAVE // 0x09 // Usermod "usermod_v2_auto_save.h" -- Does not allocate pins
|
||||||
// #define USERMOD_ID_DHT // 0x0A // Usermod "usermod_dht.h" -- Statically allocates pins, not compatible with pinManager?
|
// #define USERMOD_ID_DHT // 0x0A // Usermod "usermod_dht.h" -- Statically allocates pins, not compatible with pinManager?
|
||||||
// #define USERMOD_ID_MODE_SORT // 0x0B // Usermod "usermod_v2_mode_sort.h" -- Does not allocate pins
|
// #define USERMOD_ID_MODE_SORT // 0x0B // Usermod "usermod_v2_mode_sort.h" -- Does not allocate pins
|
||||||
// #define USERMOD_ID_VL53L0X // 0x0C // Usermod "usermod_vl53l0x_gestures.h" -- Uses "standard" I2C pins ... TODO -- enable shared I2C bus use
|
// #define USERMOD_ID_VL53L0X // 0x0C // Usermod "usermod_vl53l0x_gestures.h" -- Uses "standard" HW_I2C pins
|
||||||
UM_MultiRelay = USERMOD_ID_MULTI_RELAY, // 0x0D // Usermod "usermod_multi_relay.h"
|
UM_MultiRelay = USERMOD_ID_MULTI_RELAY, // 0x0D // Usermod "usermod_multi_relay.h"
|
||||||
UM_AnimatedStaircase = USERMOD_ID_ANIMATED_STAIRCASE, // 0x0E // Usermod "Animated_Staircase.h"
|
UM_AnimatedStaircase = USERMOD_ID_ANIMATED_STAIRCASE, // 0x0E // Usermod "Animated_Staircase.h"
|
||||||
// #define USERMOD_ID_RTC // 0x0F // Usermod "usermod_rtc.h" -- Uses "standard" I2C pins ... TODO -- enable shared I2C bus use
|
// #define USERMOD_ID_RTC // 0x0F // Usermod "usermod_rtc.h" -- Uses "standard" HW_I2C pins
|
||||||
// #define USERMOD_ID_ELEKSTUBE_IPS // 0x10 // Usermod "usermod_elekstube_ips.h" -- Uses quite a few pins ... see Hardware.h and User_Setup.h
|
// #define USERMOD_ID_ELEKSTUBE_IPS // 0x10 // Usermod "usermod_elekstube_ips.h" -- Uses quite a few pins ... see Hardware.h and User_Setup.h
|
||||||
// #define USERMOD_ID_SN_PHOTORESISTOR // 0x11 // Usermod "usermod_sn_photoresistor.h" -- Uses hard-coded pin (PHOTORESISTOR_PIN == A0), but could be easily updated to use pinManager
|
// #define USERMOD_ID_SN_PHOTORESISTOR // 0x11 // Usermod "usermod_sn_photoresistor.h" -- Uses hard-coded pin (PHOTORESISTOR_PIN == A0), but could be easily updated to use pinManager
|
||||||
UM_RGBRotaryEncoder = USERMOD_RGB_ROTARY_ENCODER, // 0x16 // Usermod "rgb-rotary-encoder.h"
|
UM_RGBRotaryEncoder = USERMOD_RGB_ROTARY_ENCODER, // 0x16 // Usermod "rgb-rotary-encoder.h"
|
||||||
UM_QuinLEDAnPenta = USERMOD_ID_QUINLED_AN_PENTA, // 0x17 // Usermod "quinled-an-penta.h"
|
UM_QuinLEDAnPenta = USERMOD_ID_QUINLED_AN_PENTA // 0x17 // Usermod "quinled-an-penta.h"
|
||||||
};
|
};
|
||||||
static_assert(0u == static_cast<uint8_t>(PinOwner::None), "PinOwner::None must be zero, so default array initialization works as expected");
|
static_assert(0u == static_cast<uint8_t>(PinOwner::None), "PinOwner::None must be zero, so default array initialization works as expected");
|
||||||
|
|
||||||
@ -66,10 +67,13 @@ class PinManagerClass {
|
|||||||
uint8_t ledcAlloc[2] = {0x00, 0x00}; //16 LEDC channels
|
uint8_t ledcAlloc[2] = {0x00, 0x00}; //16 LEDC channels
|
||||||
PinOwner ownerTag[40] = { PinOwner::None };
|
PinOwner ownerTag[40] = { PinOwner::None };
|
||||||
#endif
|
#endif
|
||||||
|
uint8_t i2cAllocCount = 0; // allow multiple allocation of I2C bus pins but keep track of allocations
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// De-allocates a single pin
|
// De-allocates a single pin
|
||||||
bool deallocatePin(byte gpio, PinOwner tag);
|
bool deallocatePin(byte gpio, PinOwner tag);
|
||||||
|
// De-allocates multiple pins but only if all can be deallocated (PinOwner has to be specified)
|
||||||
|
bool deallocateMultiplePins(const uint8_t *pinArray, byte arrayElementCount, PinOwner tag);
|
||||||
// Allocates a single pin, with an owner tag.
|
// Allocates a single pin, with an owner tag.
|
||||||
// De-allocation requires the same owner tag (or override)
|
// De-allocation requires the same owner tag (or override)
|
||||||
bool allocatePin(byte gpio, bool output, PinOwner tag);
|
bool allocatePin(byte gpio, bool output, PinOwner tag);
|
||||||
@ -84,7 +88,7 @@ class PinManagerClass {
|
|||||||
#endif
|
#endif
|
||||||
inline bool allocatePin(byte gpio, bool output = true) { return allocatePin(gpio, output, PinOwner::None); }
|
inline bool allocatePin(byte gpio, bool output = true) { return allocatePin(gpio, output, PinOwner::None); }
|
||||||
#if !defined(ESP8266) // ESP8266 compiler doesn't understand deprecated attribute
|
#if !defined(ESP8266) // ESP8266 compiler doesn't understand deprecated attribute
|
||||||
[[deprecated("Replaced by three-parameter deallocatePin(gpio, output, ownerTag), for improved debugging")]]
|
[[deprecated("Replaced by two-parameter deallocatePin(gpio, ownerTag), for improved debugging")]]
|
||||||
#endif
|
#endif
|
||||||
inline void deallocatePin(byte gpio) { deallocatePin(gpio, PinOwner::None); }
|
inline void deallocatePin(byte gpio) { deallocatePin(gpio, PinOwner::None); }
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// version code in format yymmddb (b = daily build)
|
// version code in format yymmddb (b = daily build)
|
||||||
#define VERSION 2111171
|
#define VERSION 2111191
|
||||||
|
|
||||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||||
//#define WLED_USE_MY_CONFIG
|
//#define WLED_USE_MY_CONFIG
|
||||||
|
Loading…
Reference in New Issue
Block a user