From 6f6c43a724839786aa42551bf1961e1310ac14f6 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 18 Apr 2023 17:16:29 +0200 Subject: [PATCH] Add command ``SetOption152 0/1`` Add command ``SetOption152 0/1`` to select two (default) or one pin bistable relay control (#18386) --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + tasmota/include/tasmota_types.h | 2 +- tasmota/tasmota.ino | 2 ++ tasmota/tasmota_support/support_command.ino | 1 + tasmota/tasmota_support/support_tasmota.ino | 33 +++++++++++++++++---- tools/decode-status.py | 5 ++-- 7 files changed, 37 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c71fbfaa..f095fdb9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. ## [12.5.0.1] ### Added - Matter sensors Humidity, Pressure, Illuminance; optimize memory (#18441) +- Command ``SetOption152 0/1`` to select two (default) or one pin bistable relay control (#18386) ### Breaking Changed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 9281f00d4..e7c1949ab 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -112,6 +112,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm ## Changelog v12.5.0.1 ### Added +- Command ``SetOption152 0/1`` to select two (default) or one pin bistable relay control [#18386](https://github.com/arendst/Tasmota/issues/18386) - Matter sensors Humidity, Pressure, Illuminance [#18441](https://github.com/arendst/Tasmota/issues/18441) ### Breaking Changed diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h index 7f947a51d..004b6602b 100644 --- a/tasmota/include/tasmota_types.h +++ b/tasmota/include/tasmota_types.h @@ -185,7 +185,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t dns_ipv6_priority : 1; // bit 3 (v12.2.0.6) - SetOption149 - (Wifi) prefer IPv6 DNS resolution to IPv4 address when available. Requires `#define USE_IPV6` uint32_t no_voltage_common : 1; // bit 4 (v12.3.1.5) - SetOption150 - (Energy) Force no voltage/frequency common uint32_t matter_enabled : 1; // bit 5 (v12.3.1.5) - SetOption151 - (Matter) Enable Matter protocol over Wifi - uint32_t spare06 : 1; // bit 6 + uint32_t bistable_single_pin : 1; // bit 6 (v12.5.0.1) - SetOption152 - (Power) Switch between two (0) or one (1) pin bistable relay control uint32_t spare07 : 1; // bit 7 uint32_t spare08 : 1; // bit 8 uint32_t spare09 : 1; // bit 9 diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 85c0f0d72..cdba8af55 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -254,6 +254,7 @@ struct TasmotaGlobal_t { void *log_buffer_mutex; // Control access to log buffer power_t power; // Current copy of Settings->power + power_t power_bistable; // Current state of single pin bistable power power_t rel_inverted; // Relay inverted flag (1 = (0 = On, 1 = Off)) power_t rel_bistable; // Relay bistable bitmap power_t last_power; // Last power set state @@ -430,6 +431,7 @@ void setup(void) { TasmotaGlobal.global_state.data = 0xF; // Init global state (wifi_down, mqtt_down) to solve possible network issues TasmotaGlobal.enable_logging = 1; TasmotaGlobal.seriallog_level = LOG_LEVEL_INFO; // Allow specific serial messages until config loaded + TasmotaGlobal.power_bistable = 0x80000000; RtcRebootLoad(); if (!RtcRebootValid()) { diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino index 4637cd09c..a5926b353 100644 --- a/tasmota/tasmota_support/support_command.ino +++ b/tasmota/tasmota_support/support_command.ino @@ -1472,6 +1472,7 @@ void CmndSetoptionBase(bool indexed) { bitWrite(Settings->flag6.data, pindex, XdrvMailbox.payload); switch (pindex) { case 5: // SetOption151 - Matter enabled + case 6: // SetOption152 - (Power) Use single pin bistable TasmotaGlobal.restart_flag = 2; break; } diff --git a/tasmota/tasmota_support/support_tasmota.ino b/tasmota/tasmota_support/support_tasmota.ino index 845f18766..432f7682e 100644 --- a/tasmota/tasmota_support/support_tasmota.ino +++ b/tasmota/tasmota_support/support_tasmota.ino @@ -309,6 +309,7 @@ void SetDevicePower(power_t rpower, uint32_t source) { else { uint32_t port = 0; uint32_t port_next; + power_t bistable = 0; ZeroCrossMomentStart(); @@ -316,12 +317,25 @@ void SetDevicePower(power_t rpower, uint32_t source) { power_t state = rpower &1; port_next = 1; // Select next relay + bool update = true; if (bitRead(TasmotaGlobal.rel_bistable, port)) { - if (!state) { port_next = 2; } // Skip highest relay - port += state; // Relay = Off, Relay = On + if (Settings->flag6.bistable_single_pin) { // SetOption152 - (Power) Use single pin bistable + if (0x80000000 == TasmotaGlobal.power_bistable) { + TasmotaGlobal.power_bistable = TasmotaGlobal.power; // Init last known state + } + update = (bitRead(TasmotaGlobal.power_bistable, port) != state); + if (update) { + bitWrite(TasmotaGlobal.power_bistable, port, state); + bitSet(bistable, port); + } + + } else { + if (!state) { port_next = 2; } // Skip highest relay + port += state; // Relay = Off, Relay = On + } state = 1; // Set pulse } - if (i < MAX_RELAYS) { + if (update && (i < MAX_RELAYS)) { DigitalWrite(GPIO_REL1, port, bitRead(TasmotaGlobal.rel_inverted, port) ? !state : state); } port += port_next; // Select next relay @@ -335,6 +349,11 @@ void SetDevicePower(power_t rpower, uint32_t source) { delay(Settings->param[P_BISTABLE_PULSE]); // SetOption45 - Keep energized for about 5 x operation time for (uint32_t i = 0; i < port; i++) { // Reset up to detected amount of ports if (bitRead(TasmotaGlobal.rel_bistable, i)) { + if (Settings->flag6.bistable_single_pin) { // SetOption152 - (Power) Use single pin bistable + if (!bitRead(bistable, i)) { + continue; + } + } DigitalWrite(GPIO_REL1, i, bitRead(TasmotaGlobal.rel_inverted, i) ? 1 : 0); } } @@ -2218,8 +2237,12 @@ void GpioInit(void) if (i &1) { TasmotaGlobal.devices_present--; } } #endif // ESP8266 - if (bitRead(TasmotaGlobal.rel_bistable, i)) { - if (bi_device &1) { TasmotaGlobal.devices_present--; } + if (!Settings->flag6.bistable_single_pin) { // SetOption152 - (Power) Use single pin bistable + if (bitRead(TasmotaGlobal.rel_bistable, i)) { + if (bi_device &1) { + TasmotaGlobal.devices_present--; + } + } bi_device++; } } diff --git a/tools/decode-status.py b/tools/decode-status.py index 490e8e79a..ebe18e460 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -207,7 +207,8 @@ a_setoption = [[ "(Wifi) prefer IPv6 DNS resolution to IPv4 address when available. Requires `#define USE_IPV6`", "(Energy) Force no voltage/frequency common", "(Matter) Enable Matter protocol over Wifi", - "","", + "(Power) Switch between two (0) or one (1) pin bistable relay control", + "", "","","","", "","","","", "","","","", @@ -324,7 +325,7 @@ else: obj = json.load(fp) def StartDecode(): - print ("\n*** decode-status.py v12.4.0.5 by Theo Arends and Jacek Ziolkowski ***") + print ("\n*** decode-status.py v12.5.0.1 by Theo Arends and Jacek Ziolkowski ***") # print("Decoding\n{}".format(obj))