Skip to content

Commit 1ca55e4

Browse files
authored
fix relay not turning on at boot (#5315)
These changes eliminate an elaborate race condition * add dedicated function to handle on/off and relay * add clarifying comment on output set order * add define for relay delay, honor forceOff in all cases
1 parent 2c4ed42 commit 1ca55e4

5 files changed

Lines changed: 21 additions & 14 deletions

File tree

usermods/deep_sleep/deep_sleep.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ class DeepSleepUsermod : public Usermod {
156156
delay(1000); // just in case: give user a short ~10s window to turn LEDs on in UI (delaycounter is 10 by default)
157157
return;
158158
}
159-
if (powerup == false && delaycounter) { // delay sleep in case a preset is being loaded and turnOnAtBoot is disabled (handleIO() does enable offMode temporarily in this case)
159+
if (powerup == false && delaycounter) { // delay sleep in case a preset is being loaded and turnOnAtBoot is disabled (beginStrip() / handleIO() does enable offMode temporarily in this case)
160160
delaycounter--;
161161
if (delaycounter == 1 && offMode) { // force turn on, no matter the settings (device is bricked if user set sleepDelay=0, no bootup preset and turnOnAtBoot=false)
162162
if (briS == 0) bri = 10; // turn on and set low brightness to avoid automatic turn off

wled00/button.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -367,24 +367,29 @@ void handleIO()
367367

368368
// if we want to control on-board LED (ESP8266) or relay we have to do it here as the final show() may not happen until
369369
// next loop() cycle
370-
if (strip.getBrightness()) {
370+
handleOnOff();
371+
}
372+
373+
void handleOnOff(bool forceOff)
374+
{
375+
if (strip.getBrightness() && !forceOff) {
371376
lastOnTime = millis();
372377
if (offMode) {
373378
BusManager::on();
374379
if (rlyPin>=0) {
375-
pinMode(rlyPin, rlyOpenDrain ? OUTPUT_OPEN_DRAIN : OUTPUT);
376-
digitalWrite(rlyPin, rlyMde);
377-
delay(50); // wait for relay to switch and power to stabilize
380+
// note: pinMode is set in first call to handleOnOff(true) in beginStrip()
381+
digitalWrite(rlyPin, rlyMde); // set to on state
382+
delay(RELAY_DELAY); // let power stabilize before sending LED data (#346 #812 #3581 #3955)
378383
}
379384
offMode = false;
380385
}
381-
} else if (millis() - lastOnTime > 600 && !strip.needsUpdate()) {
386+
} else if ((millis() - lastOnTime > 600 && !strip.needsUpdate()) || forceOff) {
382387
// for turning LED or relay off we need to wait until strip no longer needs updates (strip.trigger())
383388
if (!offMode) {
384389
BusManager::off();
385390
if (rlyPin>=0) {
391+
digitalWrite(rlyPin, !rlyMde); // set output before disabling high-z state to avoid output glitches
386392
pinMode(rlyPin, rlyOpenDrain ? OUTPUT_OPEN_DRAIN : OUTPUT);
387-
digitalWrite(rlyPin, !rlyMde);
388393
}
389394
offMode = true;
390395
}

wled00/const.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ static_assert(WLED_MAX_BUSSES <= 32, "WLED_MAX_BUSSES exceeds hard limit");
114114
#endif
115115
#endif
116116

117+
#define RELAY_DELAY 50 // delay in ms between switching on relay and sending data to LEDs
118+
117119
#if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32S2)
118120
#define WLED_MAX_COLOR_ORDER_MAPPINGS 5
119121
#else

wled00/fcn_declare.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ void longPressAction(uint8_t b=0);
2020
void doublePressAction(uint8_t b=0);
2121
bool isButtonPressed(uint8_t b=0);
2222
void handleButton();
23+
void handleOnOff(bool forceOff = false);
2324
void handleIO();
2425
void IRAM_ATTR touchButtonISR();
2526

wled00/wled.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,10 @@ void WLED::beginStrip()
591591
strip.setShowCallback(handleOverlayDraw);
592592
doInitBusses = false;
593593

594+
// init offMode and relay
595+
offMode = false; // init to on state to allow proper relay init
596+
handleOnOff(true); // init relay and force off
597+
594598
if (turnOnAtBoot) {
595599
if (briS > 0) bri = briS;
596600
else if (bri == 0) bri = 128;
@@ -606,20 +610,15 @@ void WLED::beginStrip()
606610
}
607611
briLast = briS; bri = 0;
608612
strip.fill(BLACK);
609-
strip.show();
613+
if (rlyPin < 0)
614+
strip.show(); // ensure LEDs are off if no relay is used
610615
}
611616
colorUpdated(CALL_MODE_INIT); // will not send notification but will initiate transition
612617
if (bootPreset > 0) {
613618
applyPreset(bootPreset, CALL_MODE_INIT);
614619
}
615620

616621
strip.setTransition(transitionDelayDefault); // restore transitions
617-
618-
// init relay pin
619-
if (rlyPin >= 0) {
620-
pinMode(rlyPin, rlyOpenDrain ? OUTPUT_OPEN_DRAIN : OUTPUT);
621-
digitalWrite(rlyPin, (rlyMde ? bri : !bri));
622-
}
623622
}
624623

625624
void WLED::initAP(bool resetAP)

0 commit comments

Comments
 (0)