diff --git a/code/espurna/config/general.h b/code/espurna/config/general.h index 725e733a..224d3e73 100644 --- a/code/espurna/config/general.h +++ b/code/espurna/config/general.h @@ -151,6 +151,10 @@ PROGMEM const char* const custom_reset_string[] = { #define RELAY_MODE_SAME 2 #define RELAY_MODE_TOOGLE 3 +#define RELAY_TYPE_NORMAL 0 +#define RELAY_TYPE_INVERSE 1 +#define RELAY_TYPE_LATCHED 2 + #define RELAY_SYNC_ANY 0 #define RELAY_SYNC_NONE_OR_ONE 1 #define RELAY_SYNC_ONE 2 @@ -183,6 +187,9 @@ PROGMEM const char* const custom_reset_string[] = { // Allowed actual relay changes inside requests flood protection window #define RELAY_FLOOD_CHANGES 5 +// Pulse with in milliseconds for a latched relay +#define RELAY_LATCHING_PULSE 50 + //------------------------------------------------------------------------------ // I18N //------------------------------------------------------------------------------ diff --git a/code/espurna/config/hardware.h b/code/espurna/config/hardware.h index f9ae9a42..fcb45e8f 100644 --- a/code/espurna/config/hardware.h +++ b/code/espurna/config/hardware.h @@ -36,7 +36,7 @@ // Relays #define RELAY1_PIN 12 - #define RELAY1_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL // LEDs #define LED1_PIN 2 @@ -53,7 +53,7 @@ // Relays #define RELAY1_PIN 5 - #define RELAY1_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL // LEDs #define LED1_PIN 2 @@ -77,7 +77,7 @@ // Relays #define RELAY1_PIN 12 - #define RELAY1_PIN_INVERSE 1 + #define RELAY1_TYPE RELAY_TYPE_INVERSE // LEDs #define LED1_PIN 5 @@ -106,7 +106,7 @@ // Relays #define RELAY1_PIN 12 - #define RELAY1_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL // LEDs #define LED1_PIN 13 @@ -125,7 +125,7 @@ // Relays #define RELAY1_PIN 12 - #define RELAY1_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL // LEDs #define LED1_PIN 13 @@ -144,7 +144,7 @@ // Relays #define RELAY1_PIN 12 - #define RELAY1_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL // LEDs #define LED1_PIN 13 @@ -163,7 +163,7 @@ // Relays #define RELAY1_PIN 12 - #define RELAY1_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL // LEDs #define LED1_PIN 13 @@ -182,7 +182,7 @@ // Relays #define RELAY1_PIN 12 - #define RELAY1_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL // LEDs #define LED1_PIN 13 @@ -201,7 +201,7 @@ // Relays #define RELAY1_PIN 12 - #define RELAY1_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL // LEDs #define LED1_PIN 13 @@ -220,7 +220,7 @@ // Relays #define RELAY1_PIN 12 - #define RELAY1_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL // LEDs #define LED1_PIN 13 @@ -240,7 +240,7 @@ // Relays #define RELAY1_PIN 12 - #define RELAY1_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL // LEDs #define LED1_PIN 15 @@ -298,10 +298,10 @@ #define RELAY3_PIN 4 #define RELAY4_PIN 15 - #define RELAY1_PIN_INVERSE 0 - #define RELAY2_PIN_INVERSE 0 - #define RELAY3_PIN_INVERSE 0 - #define RELAY4_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL + #define RELAY2_TYPE RELAY_TYPE_NORMAL + #define RELAY3_TYPE RELAY_TYPE_NORMAL + #define RELAY4_TYPE RELAY_TYPE_NORMAL // LEDs #define LED1_PIN 13 @@ -335,10 +335,10 @@ #define RELAY3_PIN 4 #define RELAY4_PIN 15 - #define RELAY1_PIN_INVERSE 0 - #define RELAY2_PIN_INVERSE 0 - #define RELAY3_PIN_INVERSE 0 - #define RELAY4_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL + #define RELAY2_TYPE RELAY_TYPE_NORMAL + #define RELAY3_TYPE RELAY_TYPE_NORMAL + #define RELAY4_TYPE RELAY_TYPE_NORMAL // LEDs #define LED1_PIN 13 @@ -366,7 +366,7 @@ // Relays #define RELAY1_PIN 12 - #define RELAY1_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL // LEDs #define LED1_PIN 13 @@ -385,7 +385,7 @@ // Relays #define RELAY1_PIN 12 - #define RELAY1_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL // LEDs #define LED1_PIN 13 @@ -472,7 +472,7 @@ // Relays #define RELAY1_PIN 5 - #define RELAY1_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL // LEDs #define LED1_PIN 13 @@ -498,8 +498,8 @@ #define RELAY1_PIN 12 #define RELAY2_PIN 4 - #define RELAY1_PIN_INVERSE 0 - #define RELAY2_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL + #define RELAY2_TYPE RELAY_TYPE_NORMAL // LEDs #define LED1_PIN 13 @@ -529,9 +529,9 @@ #define RELAY2_PIN 5 #define RELAY3_PIN 4 - #define RELAY1_PIN_INVERSE 0 - #define RELAY2_PIN_INVERSE 0 - #define RELAY3_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL + #define RELAY2_TYPE RELAY_TYPE_NORMAL + #define RELAY3_TYPE RELAY_TYPE_NORMAL // LEDs #define LED1_PIN 13 @@ -561,8 +561,8 @@ #define RELAY1_PIN 12 #define RELAY2_PIN 13 - #define RELAY1_PIN_INVERSE 0 - #define RELAY2_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL + #define RELAY2_TYPE RELAY_TYPE_NORMAL // LEDs #define LED1_PIN 16 @@ -585,7 +585,7 @@ // Relays #define RELAY1_PIN 15 - #define RELAY1_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL // LEDs #define LED1_PIN 2 @@ -690,8 +690,8 @@ #define RELAY1_PIN 2 #define RELAY2_PIN 14 - #define RELAY1_PIN_INVERSE 1 - #define RELAY2_PIN_INVERSE 1 + #define RELAY1_TYPE RELAY_TYPE_INVERSE + #define RELAY2_TYPE RELAY_TYPE_INVERSE #elif defined(JANGOE_WIFI_RELAY_NO) @@ -713,8 +713,8 @@ #define RELAY1_PIN 2 #define RELAY2_PIN 14 - #define RELAY1_PIN_INVERSE 0 - #define RELAY2_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL + #define RELAY2_TYPE RELAY_TYPE_NORMAL // ----------------------------------------------------------------------------- // Jorge García Wifi+Relays Board Kit @@ -732,8 +732,8 @@ #define RELAY1_PIN 0 #define RELAY2_PIN 2 - #define RELAY1_PIN_INVERSE 1 - #define RELAY2_PIN_INVERSE 1 + #define RELAY1_TYPE RELAY_TYPE_INVERSE + #define RELAY2_TYPE RELAY_TYPE_INVERSE // ----------------------------------------------------------------------------- // WiFi MQTT Relay / Thermostat @@ -752,7 +752,7 @@ // Relays #define RELAY1_PIN 12 - #define RELAY1_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL // LEDs #define LED1_PIN 16 @@ -779,7 +779,7 @@ // Relays #define RELAY1_PIN 15 - #define RELAY1_PIN_INVERSE 0 + #define RELAY1_TYPE RELAY_TYPE_NORMAL // LEDs #define LED1_PIN 2 @@ -875,6 +875,19 @@ #define BUTTON4_RELAY 0 #endif +#ifndef RELAY1_RESET_PIN +#define RELAY1_RESET_PIN 0 +#endif +#ifndef RELAY2_RESET_PIN +#define RELAY2_RESET_PIN 0 +#endif +#ifndef RELAY3_RESET_PIN +#define RELAY3_RESET_PIN 0 +#endif +#ifndef RELAY4_RESET_PIN +#define RELAY4_RESET_PIN 0 +#endif + #ifndef RELAY1_DELAY_ON #define RELAY1_DELAY_ON 0 #endif diff --git a/code/espurna/relay.ino b/code/espurna/relay.ino index 1357eb57..0b7c29ab 100644 --- a/code/espurna/relay.ino +++ b/code/espurna/relay.ino @@ -14,7 +14,8 @@ Copyright (C) 2016-2017 by Xose Pérez typedef struct { unsigned char pin; - bool reverse; + unsigned char type; + unsigned char reset_pin; unsigned char led; unsigned long delay_on; unsigned long delay_off; @@ -61,7 +62,21 @@ void relayProviderStatus(unsigned char id, bool status) { #endif #if RELAY_PROVIDER == RELAY_PROVIDER_RELAY - digitalWrite(_relays[id].pin, _relays[id].reverse ? !status : status); + if (_relays[id].type == RELAY_TYPE_NORMAL) { + digitalWrite(_relays[id].pin, status); + } else if (_relays[id].type == RELAY_TYPE_INVERSE) { + digitalWrite(_relays[id].pin, !status); + } else if (_relays[id].type == RELAY_TYPE_LATCHED) { + if (status) { + digitalWrite(_relays[id].pin, HIGH); + delay(RELAY_LATCHING_PULSE); + digitalWrite(_relays[id].pin, LOW); + } else { + digitalWrite(_relays[id].reset_pin, HIGH); + delay(RELAY_LATCHING_PULSE); + digitalWrite(_relays[id].reset_pin, LOW); + } + } #endif } @@ -83,8 +98,13 @@ bool relayProviderStatus(unsigned char id) { #endif #if RELAY_PROVIDER == RELAY_PROVIDER_RELAY - bool status = (digitalRead(_relays[id].pin) == HIGH); - return _relays[id].reverse ? !status : status; + if (_relays[id].type == RELAY_TYPE_NORMAL) { + return (digitalRead(_relays[id].pin) == HIGH); + } else if (_relays[id].type == RELAY_TYPE_INVERSE) { + return (digitalRead(_relays[id].pin) == LOW); + } else if (_relays[id].type == RELAY_TYPE_LATCHED) { + return _relays[id].scheduledStatus; + } #endif } @@ -428,23 +448,23 @@ void relaySetup() { #ifdef DUMMY_RELAY_COUNT for (unsigned char i=0; i < DUMMY_RELAY_COUNT; i++) { - _relays.push_back((relay_t) {0, 0}); + _relays.push_back((relay_t) {0, RELAY_TYPE_NORMAL}); _relays[i].scheduled = false; } #else #ifdef RELAY1_PIN - _relays.push_back((relay_t) { RELAY1_PIN, RELAY1_PIN_INVERSE, RELAY1_LED, RELAY1_DELAY_ON, RELAY1_DELAY_OFF }); + _relays.push_back((relay_t) { RELAY1_PIN, RELAY1_TYPE, RELAY1_RESET_PIN, RELAY1_LED, RELAY1_DELAY_ON, RELAY1_DELAY_OFF }); #endif #ifdef RELAY2_PIN - _relays.push_back((relay_t) { RELAY2_PIN, RELAY2_PIN_INVERSE, RELAY2_LED, RELAY2_DELAY_ON, RELAY2_DELAY_OFF }); + _relays.push_back((relay_t) { RELAY2_PIN, RELAY2_TYPE, RELAY2_RESET_PIN, RELAY2_LED, RELAY2_DELAY_ON, RELAY2_DELAY_OFF }); #endif #ifdef RELAY3_PIN - _relays.push_back((relay_t) { RELAY3_PIN, RELAY3_PIN_INVERSE, RELAY3_LED, RELAY3_DELAY_ON, RELAY3_DELAY_OFF }); + _relays.push_back((relay_t) { RELAY3_PIN, RELAY3_TYPE, RELAY3_RESET_PIN, RELAY3_LED, RELAY3_DELAY_ON, RELAY3_DELAY_OFF }); #endif #ifdef RELAY4_PIN - _relays.push_back((relay_t) { RELAY4_PIN, RELAY4_PIN_INVERSE, RELAY4_LED, RELAY4_DELAY_ON, RELAY4_DELAY_OFF }); + _relays.push_back((relay_t) { RELAY4_PIN, RELAY4_TYPE, RELAY4_RESET_PIN, RELAY4_LED, RELAY4_DELAY_ON, RELAY4_DELAY_OFF }); #endif #endif