diff --git a/include/Globals.h b/include/Globals.h index 8e5c1615..bd2470db 100644 --- a/include/Globals.h +++ b/include/Globals.h @@ -33,7 +33,7 @@ #define LDR_DIVIDER 4096 #endif #define SERIAL_SIZE_RX 2048 -#define CONFIG_NUM_PARAMS 20 +#define CONFIG_NUM_PARAMS 21 #define CONFIG_PREFIX_LENGTH 6 // This value must meet the one in Firefly Luciferin // We are transferring byte via Serial, the maximum decimal number that can be represented with 1 byte is 255. @@ -56,7 +56,7 @@ extern class Globals globals; extern byte config[CONFIG_NUM_PARAMS]; extern byte pre[CONFIG_PREFIX_LENGTH]; extern uint8_t prefix[], hi, lo, chk, loSecondPart, usbBrightness, gpio, baudRate, whiteTemp, fireflyEffect, - fireflyColorMode, fireflyColorOrder, ldrEn, ldrTo, ldrInt, ldrMn, ldrAction, relaySerialPin, sbSerialPin, ldrSerialPin, gpioClock; + fireflyColorMode, fireflyColorOrder, ldrEn, ldrTo, ldrInt, ldrMn, ldrAction, relaySerialPin, relayInvPin, sbSerialPin, ldrSerialPin, gpioClock; enum class Effect { GlowWormWifi, GlowWorm, solid, fire, twinkle, bpm, rainbow, chase_rainbow, solid_rainbow, slowRainbow, randomColors, @@ -96,6 +96,7 @@ const String BAUDRATE_FILENAME = "baudrate.json"; extern bool ldrReading; extern int ldrValue; extern bool ldrEnabled; +extern bool relInv; extern uint8_t ldrInterval; extern bool ldrTurnOff; extern uint8_t ldrMin; diff --git a/include/LedManager.h b/include/LedManager.h index aa086601..89ffa93e 100644 --- a/include/LedManager.h +++ b/include/LedManager.h @@ -61,6 +61,8 @@ class LedManager { const String MIN_LDR_PARAM = "minLdr"; const String MAX_LDR_PARAM = "maxLdr"; const String RELAY_PIN_PARAM = "relayPin"; + const String RELAY_INV_PARAM = "relayInv"; + const String RELAY_INV = "relayInv"; const String SB_PIN_PARAM = "sbPin"; const String LDR_PIN_PARAM = "ldrPin"; const String EFFECT_FILENAME = "effect.json"; @@ -130,7 +132,7 @@ class LedManager { void setLdr(int maxLdr); - void setPins(uint8_t relayPinParam, uint8_t sbPinParam, uint8_t ldrPinParam); + void setPins(uint8_t relayPinParam, uint8_t sbPinParam, uint8_t ldrPinParam, bool relInv); void flushSerial(); diff --git a/include/Version.h b/include/Version.h index a4d1f5d0..54e77b65 100644 --- a/include/Version.h +++ b/include/Version.h @@ -4,6 +4,6 @@ #define VERSION "5.21.3" #endif #ifndef BUILD_TIMESTAMP - #define BUILD_TIMESTAMP "2025-04-06 09:15:45.340060" + #define BUILD_TIMESTAMP "2025-08-09 14:31:39.066602" #endif \ No newline at end of file diff --git a/include/WebSettings.h b/include/WebSettings.h index 90d90704..3158a44a 100644 --- a/include/WebSettings.h +++ b/include/WebSettings.h @@ -27,6 +27,6 @@ const char setSettingsPage[] PROGMEM = R"=====(LUCIFERIN Web Interface

LUCIFERIN

Bias Lighting and Ambient Light firmware designed for Firefly Luciferin



















)====="; -const char setLdrPage[] PROGMEM = R"=====(LUCIFERIN Web Interface

LUCIFERIN











)====="; +const char setLdrPage[] PROGMEM = R"=====(LUCIFERIN Web Interface

LUCIFERIN



Invert relay








)====="; #endif //GLOW_WORM_LUCIFERIN_WEBSETTINGS_H diff --git a/platformio.ini b/platformio.ini index 58d0f843..b26e471d 100755 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,7 @@ platform_esp8266 = espressif8266@4.2.1 f_cpu_esp8266 = 160000000L monitor_filters_esp8266 = esp8266_exception_decoder -platform_esp32 = espressif32@6.10.0 +platform_esp32 = espressif32@6.11.0 monitor_filters_esp32 = esp32_exception_decoder framework = arduino @@ -24,8 +24,8 @@ extra_scripts = pre:platformio_version_increment/version_increment_pre.py post:platformio_version_increment/version_increment_post.py lib_deps = - makuna/NeoPixelBus@2.8.3 - bblanchon/ArduinoJson@7.3.1 + makuna/NeoPixelBus@2.8.4 + bblanchon/ArduinoJson@7.4.2 knolleary/PubSubClient@2.8.0 ;https://github.com/Makuna/NeoPixelBus.git#master lib_extra_dirs = arduino_bootstrapper diff --git a/platformio_version_increment b/platformio_version_increment index 781207e2..e436ee27 160000 --- a/platformio_version_increment +++ b/platformio_version_increment @@ -1 +1 @@ -Subproject commit 781207e2d24c4cfcc274a4f5aa8529741e129697 +Subproject commit e436ee2719945796e292ed5861a71a97ea4b645a diff --git a/src/Globals.cpp b/src/Globals.cpp index aa3d8924..c8f7735d 100755 --- a/src/Globals.cpp +++ b/src/Globals.cpp @@ -33,7 +33,7 @@ Globals globals; byte config[CONFIG_NUM_PARAMS]; byte pre[CONFIG_PREFIX_LENGTH]; uint8_t prefix[] = {'D', 'P', 's', 'o', 'f', 't'}, hi, lo, chk, loSecondPart, usbBrightness, gpio, baudRate, whiteTemp, - fireflyEffect, fireflyColorMode, fireflyColorOrder, ldrEn, ldrTo, ldrInt, ldrMn, ldrAction, relaySerialPin, sbSerialPin, ldrSerialPin, gpioClock; + fireflyEffect, fireflyColorMode, fireflyColorOrder, ldrEn, ldrTo, ldrInt, ldrMn, ldrAction, relaySerialPin, relayInvPin, sbSerialPin, ldrSerialPin, gpioClock; uint8_t whiteTempInUse = WHITE_TEMP_CORRECTION_DISABLE; uint8_t colorMode = 1; uint8_t colorOrder = 1; @@ -62,6 +62,7 @@ bool breakLoop = false; bool ldrReading = false; int ldrValue; bool ldrEnabled = false; +bool relInv = false; uint8_t ldrInterval = 30; bool ldrTurnOff = false; uint8_t ldrMin = 20; @@ -238,7 +239,7 @@ void Globals::setBaudRate(int bdRate) { void Globals::turnOnRelay() { if (!relayState) { relayState = true; - digitalWrite(relayPin, HIGH); + digitalWrite(relayPin, relInv ? LOW : HIGH); delay(10); } } @@ -250,7 +251,7 @@ void Globals::turnOffRelay() { if (relayState) { relayState = false; delay(10); - digitalWrite(relayPin, LOW); + digitalWrite(relayPin, relInv ? HIGH : LOW); } } @@ -301,6 +302,7 @@ void Globals::sendSerialInfo() { Serial.printf("ldr:%d\n", ((ldrValue * 100) / ldrDivider)); } Serial.printf("relayPin:%d\n", relayPin); + Serial.printf("relInv:%d\n", relInv); Serial.printf("sbPin:%d\n", sbPin); Serial.printf("ldrPin:%d\n", ldrPin); Serial.flush(); diff --git a/src/GlowWormLuciferin.cpp b/src/GlowWormLuciferin.cpp index f7b6d85f..1813ecc4 100755 --- a/src/GlowWormLuciferin.cpp +++ b/src/GlowWormLuciferin.cpp @@ -124,6 +124,7 @@ void setup() { String ldrMinFromStorage = bootstrapManager.readValueFromFile(ledManager.LDR_FILENAME, ledManager.MIN_LDR_PARAM); String ldrMaxFromStorage = bootstrapManager.readValueFromFile(ledManager.LDR_CAL_FILENAME, ledManager.MAX_LDR_PARAM); String relayPinFromStorage = bootstrapManager.readValueFromFile(ledManager.PIN_FILENAME, ledManager.RELAY_PIN_PARAM); + String relayInvStorage = bootstrapManager.readValueFromFile(ledManager.PIN_FILENAME, ledManager.RELAY_INV); String sbPinFromStorage = bootstrapManager.readValueFromFile(ledManager.PIN_FILENAME, ledManager.SB_PIN_PARAM); String ldrPinFromStorage = bootstrapManager.readValueFromFile(ledManager.PIN_FILENAME, ledManager.LDR_PIN_PARAM); if (!ldrFromStorage.isEmpty() && ldrFromStorage != ERROR) { @@ -141,6 +142,9 @@ void setup() { if (!relayPinFromStorage.isEmpty() && relayPinFromStorage != ERROR) { relayPin = relayPinFromStorage.toInt(); } + if (!relayInvStorage.isEmpty() && relayInvStorage != ERROR) { + relInv = relayInvStorage.toInt(); + } if (!sbPinFromStorage.isEmpty() && sbPinFromStorage != ERROR) { sbPin = sbPinFromStorage.toInt(); } @@ -314,6 +318,7 @@ void mainLoop() { fireflyColorMode = config[i++]; fireflyColorOrder = config[i++]; relaySerialPin = config[i++]; + relayInvPin = config[i++]; sbSerialPin = config[i++]; ldrSerialPin = config[i++]; gpioClock = config[i++]; @@ -321,7 +326,7 @@ void mainLoop() { if (!(!breakLoop && (chk != (hi ^ lo ^ loSecondPart ^ usbBrightness ^ gpio ^ baudRate ^ whiteTemp ^ fireflyEffect ^ ldrEn ^ ldrTo ^ ldrInt ^ ldrMn ^ ldrAction ^ fireflyColorMode ^ fireflyColorOrder - ^ relaySerialPin ^ sbSerialPin ^ ldrSerialPin ^ gpioClock ^ 0x55)))) { + ^ relaySerialPin ^ relayInvPin ^ sbSerialPin ^ ldrSerialPin ^ gpioClock ^ 0x55)))) { if (!breakLoop) { #ifdef TARGET_GLOWWORMLUCIFERINLIGHT if (!relayState) { @@ -359,11 +364,12 @@ void mainLoop() { relaySerialPin = relaySerialPin - 10; sbSerialPin = sbSerialPin - 10; ldrSerialPin = ldrSerialPin - 10; - if ((relayPin != relaySerialPin) || (sbPin != sbSerialPin) || (ldrPin != ldrSerialPin)) { + if ((relayPin != relaySerialPin) || (sbPin != sbSerialPin) || (ldrPin != ldrSerialPin) || (relayInvPin == 10 && relInv) || (relayInvPin == 11 && !relInv)) { relayPin = relaySerialPin; sbPin = sbSerialPin; ldrPin = ldrSerialPin; - ledManager.setPins(relayPin, sbPin, ldrPin); + relInv = relayInvPin == 11; + ledManager.setPins(relayPin, sbPin, ldrPin, relInv); } } uint16_t numLedFromLuciferin = lo + (loSecondPart * SERIAL_CHUNK_SIZE) + 1; diff --git a/src/LedManager.cpp b/src/LedManager.cpp index 0a2a56ed..8bf611b6 100644 --- a/src/LedManager.cpp +++ b/src/LedManager.cpp @@ -788,13 +788,15 @@ void LedManager::setLdr(int maxLdr) { * @param ldrTurnOffToSet Turn off LEDs before LDR readings * @param ldrIntervalToSet Interval between readings * @param minLdr min brightness when using LDR + * @param relInv relay iverted */ -void LedManager::setPins(uint8_t relayPinParam, uint8_t sbPinParam, uint8_t ldrPinParam) { +void LedManager::setPins(uint8_t relayPinParam, uint8_t sbPinParam, uint8_t ldrPinParam, bool relInv) { Serial.println(F("CHANGING PINs")); JsonDocument ldrDoc; ldrDoc[RELAY_PIN_PARAM] = relayPinParam; ldrDoc[SB_PIN_PARAM] = sbPinParam; ldrDoc[LDR_PIN_PARAM] = ldrPinParam; + ldrDoc[RELAY_INV] = relInv; BootstrapManager::writeToLittleFS(ldrDoc, PIN_FILENAME); delay(200); #if defined(ARDUINO_ARCH_ESP32) diff --git a/src/NetManager.cpp b/src/NetManager.cpp index bfdb0599..ae28a790 100644 --- a/src/NetManager.cpp +++ b/src/NetManager.cpp @@ -312,6 +312,8 @@ void NetManager::listenOnHttpGet() { prefsData += ldrMin; prefsData += F("\",\"relayPin\":\""); prefsData += relayPin; + prefsData += F("\",\"relInv\":\""); + prefsData += relInv; prefsData += F("\",\"sbPin\":\""); prefsData += sbPin; prefsData += F("\",\"ldrPin\":\""); @@ -776,7 +778,7 @@ bool NetManager::processFirmwareConfig() { int ldrPinParam = (int) bootstrapManager.jsonDoc[ledManager.LDR_PIN_PARAM]; if (ldrPin != ldrPinParam) { ldrPin = ldrPinParam; - ledManager.setPins(relayPin, sbPin, ldrPin); + ledManager.setPins(relayPin, sbPin, ldrPin, relInv); ledManager.reinitLEDTriggered = true; } } @@ -785,7 +787,16 @@ bool NetManager::processFirmwareConfig() { int relayPinParam = (int) bootstrapManager.jsonDoc[ledManager.RELAY_PIN_PARAM]; if (relayPin != relayPinParam) { relayPin = relayPinParam; - ledManager.setPins(relayPin, sbPin, ldrPin); + ledManager.setPins(relayPin, sbPin, ldrPin, relInv); + ledManager.reinitLEDTriggered = true; + } + } + // INVERTED RELAY + if (bootstrapManager.jsonDoc[ledManager.RELAY_INV_PARAM].is()) { + bool relayInvParam = bootstrapManager.jsonDoc[ledManager.RELAY_INV_PARAM]; + if (relInv != relayInvParam) { + relInv = relayInvParam; + ledManager.setPins(relayPin, sbPin, ldrPin, relInv); ledManager.reinitLEDTriggered = true; } } @@ -794,7 +805,7 @@ bool NetManager::processFirmwareConfig() { int sbrPinParam = (int) bootstrapManager.jsonDoc[ledManager.SB_PIN_PARAM]; if (sbPin != sbrPinParam) { sbPin = sbrPinParam; - ledManager.setPins(relayPin, sbPin, ldrPin); + ledManager.setPins(relayPin, sbPin, ldrPin, relInv); ledManager.reinitLEDTriggered = true; } } @@ -916,7 +927,8 @@ void NetManager::sendStatus() { if (effect == Effect::GlowWorm || effect == Effect::GlowWormWifi) { fpsData = F("{\"deviceName\":\""); fpsData += deviceName; - fpsData += F("\",\"state\":\""); + fpsData += "\",\"color\": { \"r\": 255, \"g\": 190, \"b\": 140 }"; // Default for bias light + fpsData += F(",\"state\":\""); fpsData += (ledManager.stateOn) ? ON_CMD : OFF_CMD; fpsData += F("\",\"brightness\":"); fpsData += brightness; @@ -951,8 +963,8 @@ void NetManager::sendStatus() { } else { bootstrapManager.jsonDoc.clear(); JsonObject root = bootstrapManager.jsonDoc.to(); - JsonObject color = root["color"].to(); root[F("state")] = (ledManager.stateOn) ? ON_CMD : OFF_CMD; + JsonObject color = root["color"].to(); color[F("r")] = ledManager.red; color[F("g")] = ledManager.green; color[F("b")] = ledManager.blue; @@ -972,6 +984,7 @@ void NetManager::sendStatus() { root[F("ldr")] = ((ldrValue * 100) / ldrDivider); } root[F("relayPin")] = relayPin; + root[F("relayInv")] = relInv; root[F("sbPin")] = sbPin; root[F("ldrPin")] = ldrPin; root[BAUDRATE_PARAM] = baudRateInUse; @@ -1127,8 +1140,10 @@ bool NetManager::processLDR() { String ldrMinMqtt = bootstrapManager.jsonDoc[F("ldrMin")]; String ldrActionMqtt = bootstrapManager.jsonDoc[F("ldrAction")]; String rPin = bootstrapManager.jsonDoc[F("relayPin")]; + String rInvStr = bootstrapManager.jsonDoc[F("relInv")]; String sPin = bootstrapManager.jsonDoc[F("sbPin")]; String lPin = bootstrapManager.jsonDoc[F("ldrPin")]; + relInv = rInvStr == "true"; ldrEnabled = ldrEnabledMqtt == "true"; ldrTurnOff = ldrTurnOffMqtt == "true"; ldrInterval = ldrIntervalMqtt.toInt(); @@ -1154,7 +1169,7 @@ bool NetManager::processLDR() { relayPin = rPin.toInt(); sbPin = sPin.toInt(); ldrPin = lPin.toInt(); - ledManager.setPins(relayPin, sbPin, ldrPin); + ledManager.setPins(relayPin, sbPin, ldrPin, relInv); } delay(DELAY_500); startUDP();