diff --git a/code/espurna/config/general.h b/code/espurna/config/general.h index 8ca8ff3a..614b5d77 100644 --- a/code/espurna/config/general.h +++ b/code/espurna/config/general.h @@ -243,68 +243,69 @@ PROGMEM const char* const custom_reset_string[] = { // RELAY //------------------------------------------------------------------------------ -#define RELAY_BOOT_OFF 0 -#define RELAY_BOOT_ON 1 -#define RELAY_BOOT_SAME 2 -#define RELAY_BOOT_TOGGLE 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 -#define RELAY_SYNC_SAME 3 - -#define RELAY_PULSE_NONE 0 -#define RELAY_PULSE_OFF 1 -#define RELAY_PULSE_ON 2 - -#define RELAY_PROVIDER_RELAY 0 -#define RELAY_PROVIDER_DUAL 1 -#define RELAY_PROVIDER_LIGHT 2 -#define RELAY_PROVIDER_RFBRIDGE 3 -#define RELAY_PROVIDER_STM 4 +#define RELAY_BOOT_OFF 0 +#define RELAY_BOOT_ON 1 +#define RELAY_BOOT_SAME 2 +#define RELAY_BOOT_TOGGLE 3 + +#define RELAY_TYPE_NORMAL 0 +#define RELAY_TYPE_INVERSE 1 +#define RELAY_TYPE_LATCHED 2 +#define RELAY_TYPE_LATCHED_INVERSE 3 + +#define RELAY_SYNC_ANY 0 +#define RELAY_SYNC_NONE_OR_ONE 1 +#define RELAY_SYNC_ONE 2 +#define RELAY_SYNC_SAME 3 + +#define RELAY_PULSE_NONE 0 +#define RELAY_PULSE_OFF 1 +#define RELAY_PULSE_ON 2 + +#define RELAY_PROVIDER_RELAY 0 +#define RELAY_PROVIDER_DUAL 1 +#define RELAY_PROVIDER_LIGHT 2 +#define RELAY_PROVIDER_RFBRIDGE 3 +#define RELAY_PROVIDER_STM 4 // Default boot mode: 0 means OFF, 1 ON and 2 whatever was before -#define RELAY_BOOT_MODE RELAY_BOOT_OFF +#define RELAY_BOOT_MODE RELAY_BOOT_OFF // 0 means ANY, 1 zero or one and 2 one and only one -#define RELAY_SYNC RELAY_SYNC_ANY +#define RELAY_SYNC RELAY_SYNC_ANY // Default pulse mode: 0 means no pulses, 1 means normally off, 2 normally on -#define RELAY_PULSE_MODE RELAY_PULSE_NONE +#define RELAY_PULSE_MODE RELAY_PULSE_NONE // Default pulse time in seconds -#define RELAY_PULSE_TIME 1.0 +#define RELAY_PULSE_TIME 1.0 // Relay requests flood protection window - in seconds -#define RELAY_FLOOD_WINDOW 3 +#define RELAY_FLOOD_WINDOW 3 // Allowed actual relay changes inside requests flood protection window -#define RELAY_FLOOD_CHANGES 5 +#define RELAY_FLOOD_CHANGES 5 // Pulse with in milliseconds for a latched relay -#define RELAY_LATCHING_PULSE 10 +#define RELAY_LATCHING_PULSE 10 // Do not save relay state after these many milliseconds -#define RELAY_SAVE_DELAY 1000 +#define RELAY_SAVE_DELAY 1000 //------------------------------------------------------------------------------ // LED //------------------------------------------------------------------------------ -#define LED_MODE_MQTT 0 // LED will be managed from MQTT (OFF by default) -#define LED_MODE_WIFI 1 // LED will blink according to the WIFI status -#define LED_MODE_FOLLOW 2 // LED will follow state of linked relay (check RELAY#_LED) -#define LED_MODE_FOLLOW_INVERSE 3 // LED will follow the opposite state of linked relay (check RELAY#_LED) -#define LED_MODE_FINDME 4 // LED will be ON if all relays are OFF -#define LED_MODE_FINDME_WIFI 5 // A mixture between WIFI and FINDME -#define LED_MODE_ON 6 // LED always ON -#define LED_MODE_OFF 7 // LED always OFF -#define LED_MODE_RELAY 8 // If any relay is ON, LED will be ON, otherwise OFF -#define LED_MODE_RELAY_WIFI 9 // A mixture between WIFI and RELAY, the reverse of MIXED +#define LED_MODE_MQTT 0 // LED will be managed from MQTT (OFF by default) +#define LED_MODE_WIFI 1 // LED will blink according to the WIFI status +#define LED_MODE_FOLLOW 2 // LED will follow state of linked relay (check RELAY#_LED) +#define LED_MODE_FOLLOW_INVERSE 3 // LED will follow the opposite state of linked relay (check RELAY#_LED) +#define LED_MODE_FINDME 4 // LED will be ON if all relays are OFF +#define LED_MODE_FINDME_WIFI 5 // A mixture between WIFI and FINDME +#define LED_MODE_ON 6 // LED always ON +#define LED_MODE_OFF 7 // LED always OFF +#define LED_MODE_RELAY 8 // If any relay is ON, LED will be ON, otherwise OFF +#define LED_MODE_RELAY_WIFI 9 // A mixture between WIFI and RELAY, the reverse of MIXED // ----------------------------------------------------------------------------- // WIFI diff --git a/code/espurna/config/hardware.h b/code/espurna/config/hardware.h index 5c2f29c4..c7c4743a 100644 --- a/code/espurna/config/hardware.h +++ b/code/espurna/config/hardware.h @@ -12,7 +12,7 @@ // - BUTTON_DEFAULT_HIGH: there is a pull up in place // - BUTTON_SET_PULLUP: set pullup by software // RELAY#_PIN: GPIO for the n-th relay (1-based, up to 4 relays) -// RELAY#_TYPE: Relay can be RELAY_TYPE_NORMAL, RELAY_TYPE_INVERSE or RELAY_TYPE_LATCHED +// RELAY#_TYPE: Relay can be RELAY_TYPE_NORMAL, RELAY_TYPE_INVERSE, RELAY_TYPE_LATCHED or RELAY_TYPE_LATCHED_INVERSE // LED#_PIN: GPIO for the n-th LED (1-based, up to 4 LEDs) // LED#_PIN_INVERSE: LED has inversed logic (lit when pulled down) // LED#_MODE: Check hardware.h for LED_MODE_% diff --git a/code/espurna/relay.ino b/code/espurna/relay.ino index a8a5cd65..406f7670 100644 --- a/code/espurna/relay.ino +++ b/code/espurna/relay.ino @@ -17,7 +17,7 @@ typedef struct { // Configuration variables unsigned char pin; // GPIO pin for the relay - unsigned char type; // RELAY_TYPE_NORMAL, RELAY_TYPE_INVERSE or RELAY_TYPE_LATCHED + unsigned char type; // RELAY_TYPE_NORMAL, RELAY_TYPE_INVERSE, RELAY_TYPE_LATCHED or RELAY_TYPE_LATCHED_INVERSE unsigned char reset_pin; // GPIO to reset the relay if RELAY_TYPE_LATCHED unsigned long delay_on; // Delay to turn relay ON unsigned long delay_off; // Delay to turn relay OFF @@ -118,17 +118,18 @@ void _relayProviderStatus(unsigned char id, bool status) { 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) { - digitalWrite(_relays[id].pin, LOW); - digitalWrite(_relays[id].reset_pin, LOW); + } else if (_relays[id].type == RELAY_TYPE_LATCHED || _relays[id].type == RELAY_TYPE_LATCHED_INVERSE) { + bool pulse = RELAY_TYPE_LATCHED ? HIGH : LOW; + digitalWrite(_relays[id].pin, !pulse); + digitalWrite(_relays[id].reset_pin, !pulse); if (status) { - digitalWrite(_relays[id].pin, HIGH); + digitalWrite(_relays[id].pin, pulse); } else { - digitalWrite(_relays[id].reset_pin, HIGH); + digitalWrite(_relays[id].reset_pin, pulse); } delay(RELAY_LATCHING_PULSE); - digitalWrite(_relays[id].pin, LOW); - digitalWrite(_relays[id].reset_pin, LOW); + digitalWrite(_relays[id].pin, !pulse); + digitalWrite(_relays[id].reset_pin, !pulse); } #endif @@ -483,7 +484,9 @@ void _relayBoot() { void _relayConfigure() { for (unsigned int i=0; i<_relays.size(); i++) { pinMode(_relays[i].pin, OUTPUT); - if (_relays[i].type == RELAY_TYPE_LATCHED) pinMode(_relays[i].reset_pin, OUTPUT); + if (_relays[i].type == RELAY_TYPE_LATCHED || _relays[i].type == RELAY_TYPE_LATCHED_INVERSE) { + pinMode(_relays[i].reset_pin, OUTPUT); + } _relays[i].pulse = getSetting("relayPulse", i, RELAY_PULSE_MODE).toInt(); _relays[i].pulse_ms = 1000 * getSetting("relayTime", i, RELAY_PULSE_MODE).toFloat(); }