From 571a2afce50f3bff82361f2117ccb87a13daf3cb Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 16 Jul 2022 12:35:22 +0200 Subject: [PATCH] Fix bistable relay interlock - Fix bistable relay interlock - Reset bistable relay more consistent and faster (40ms instead of max 200ms) --- tasmota/tasmota_support/support_tasmota.ino | 30 ++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tasmota/tasmota_support/support_tasmota.ino b/tasmota/tasmota_support/support_tasmota.ino index 0e735a11f..42b4e1733 100644 --- a/tasmota/tasmota_support/support_tasmota.ino +++ b/tasmota/tasmota_support/support_tasmota.ino @@ -239,14 +239,6 @@ void SetLatchingRelay(power_t lpower, uint32_t state) { } } -void ResetBistableRelays(void) { - for (uint32_t i = 0; i < MAX_RELAYS; i++) { - if (bitRead(TasmotaGlobal.rel_bistable, i)) { - DigitalWrite(GPIO_REL1, i, bitRead(TasmotaGlobal.rel_inverted, i) ? 1 : 0); - } - } -} - void SetDevicePower(power_t rpower, uint32_t source) { ShowSource(source); TasmotaGlobal.last_source = source; @@ -300,19 +292,18 @@ void SetDevicePower(power_t rpower, uint32_t source) { SetLatchingRelay(rpower, 1); } #endif // ESP8266 - else - { - ZeroCrossMomentStart(); - + else { uint32_t port = 0; uint32_t port_next; + + ZeroCrossMomentStart(); + for (uint32_t i = 0; i < TasmotaGlobal.devices_present; i++) { power_t state = rpower &1; port_next = 1; // Select next relay if (bitRead(TasmotaGlobal.rel_bistable, port)) { if (!state) { port_next = 2; } // Skip highest relay - TasmotaGlobal.latching_relay_pulse = 2; // max 200mS (initiated by stateloop()) port += state; // Relay = Off, Relay = On state = 1; // Set pulse } @@ -320,10 +311,20 @@ void SetDevicePower(power_t rpower, uint32_t source) { DigitalWrite(GPIO_REL1, port, bitRead(TasmotaGlobal.rel_inverted, port) ? !state : state); } port += port_next; // Select next relay - rpower >>= 1; + rpower >>= 1; // Select next power } ZeroCrossMomentEnd(); + + // Reset bistable relay here to fix non-interlock situations due to fast switching + if (TasmotaGlobal.rel_bistable) { // If bistable relays in the mix reset them after 40ms + delay(40); // About 5 x operation time + for (uint32_t i = 0; i < MAX_RELAYS; i++) { + if (bitRead(TasmotaGlobal.rel_bistable, i)) { + DigitalWrite(GPIO_REL1, i, bitRead(TasmotaGlobal.rel_inverted, i) ? 1 : 0); + } + } + } } } @@ -1155,7 +1156,6 @@ void Every100mSeconds(void) SetLatchingRelay(0, 0); } #endif // ESP8266 - ResetBistableRelays(); } }