From 51357191dfdbfc71915c46a90e9a3bd1e86a1f85 Mon Sep 17 00:00:00 2001 From: Florian Date: Thu, 26 Jan 2023 19:51:12 -0600 Subject: [PATCH] [ONOFF] Add overcurrent protection (#1426) Add a function that switches OFF the actuator if the current measured is more than MAX_CURRENT_ACTUATOR --- main/ZactuatorONOFF.ino | 44 +++++++++++++++++++++++++++++++++++------ main/ZsensorRN8209.ino | 18 +++++++++++++++++ main/config_ONOFF.h | 9 ++++++++- main/main.ino | 24 +++++++++++----------- 4 files changed, 77 insertions(+), 18 deletions(-) diff --git a/main/ZactuatorONOFF.ino b/main/ZactuatorONOFF.ino index 7a03fbc..c897b58 100644 --- a/main/ZactuatorONOFF.ino +++ b/main/ZactuatorONOFF.ino @@ -29,13 +29,19 @@ #include "User_config.h" #ifdef ZactuatorONOFF -unsigned long timeinttemp = 0; void setupONOFF() { +# ifdef MAX_CURRENT_ACTUATOR + xTaskCreate(overLimitCurrent, "overLimitCurrent", 2500, NULL, 10, NULL); +# endif +# ifdef MAX_TEMP_ACTUATOR + xTaskCreate(overLimitTemp, "overLimitTemp", 2500, NULL, 10, NULL); +# endif pinMode(ACTUATOR_ONOFF_GPIO, OUTPUT); # ifdef ACTUATOR_ONOFF_DEFAULT digitalWrite(ACTUATOR_ONOFF_GPIO, ACTUATOR_ONOFF_DEFAULT); # endif + Log.trace(F("ZactuatorONOFF setup done" CR)); } # if jsonReceiving @@ -106,9 +112,9 @@ void MQTTtoONOFF(char* topicOri, char* datacallback) { //Check regularly temperature of the ESP32 board and switch OFF the relay if temperature is more than MAX_TEMP_ACTUATOR # ifdef MAX_TEMP_ACTUATOR -void OverHeatingRelayOFF() { +void overLimitTemp(void* pvParameters) { # if defined(ESP32) && !defined(NO_INT_TEMP_READING) - if (millis() > (timeinttemp + TimeBetweenReadingIntTemp)) { + for (;;) { static float previousInternalTempc = 0; float internalTempc = intTemperatureRead(); Log.trace(F("Internal temperature of the ESP32 %F" CR), internalTempc); @@ -116,14 +122,40 @@ void OverHeatingRelayOFF() { if (internalTempc > MAX_TEMP_ACTUATOR && previousInternalTempc > MAX_TEMP_ACTUATOR && digitalRead(ACTUATOR_ONOFF_GPIO) == ACTUATOR_ON) { Log.error(F("[ActuatorONOFF] OverTemperature detected ( %F > %F ) switching OFF Actuator" CR), internalTempc, MAX_TEMP_ACTUATOR); ActuatorTrigger(); + for (int i = 0; i < 30; i++) { + ErrorIndicatorON(); + vTaskDelay(200); + ErrorIndicatorOFF(); + vTaskDelay(200); + } } previousInternalTempc = internalTempc; - timeinttemp = millis(); + vTaskDelay(TimeBetweenReadingIntTemp); } # endif } -# else -void OverHeatingRelayOFF() {} +# endif + +// Check regularly current the relay and switch it OFF if the current is more than MAX_CURRENT_ACTUATOR +# ifdef MAX_CURRENT_ACTUATOR +void overLimitCurrent(void* pvParameters) { + for (;;) { + float current = getRN8209current(); + Log.trace(F("RN8209 Current %F" CR), current); + // We switch OFF the actuator if the current of the RN8209 is more than MAX_CURRENT_ACTUATOR. + if (current > MAX_CURRENT_ACTUATOR && digitalRead(ACTUATOR_ONOFF_GPIO) == ACTUATOR_ON) { + Log.error(F("[ActuatorONOFF] OverCurrent detected ( %F > %F ) switching OFF Actuator" CR), current, MAX_CURRENT_ACTUATOR); + ActuatorTrigger(); + for (int i = 0; i < 30; i++) { + ErrorIndicatorON(); + vTaskDelay(200); + ErrorIndicatorOFF(); + vTaskDelay(200); + } + } + vTaskDelay(TimeBetweenReadingCurrent); + } +} # endif /* diff --git a/main/ZsensorRN8209.ino b/main/ZsensorRN8209.ino index 4cb2113..b7c6f8f 100644 --- a/main/ZsensorRN8209.ino +++ b/main/ZsensorRN8209.ino @@ -35,6 +35,23 @@ extern "C" bool init_8209c_interface(); StaticJsonDocument doc; +// GetCurrent function for critical operation like overcurrent protection +float getRN8209current() { + uint8_t ret = rn8209c_read_emu_status(); + if (ret) { + int32_t current; + uint32_t temp_current = 0; + rn8209c_read_current(phase_A, &temp_current); + if (ret == 1) { + current = temp_current; + } else { + current = (int32_t)temp_current * (-1); + } + return current / 10000.0; + } + return 0; +} + void rn8209_loop(void* mode) { if (!ProcessLock) { uint32_t voltage; @@ -78,6 +95,7 @@ void setupRN8209() { set_user_param(cal); init_8209c_interface(); xTaskCreate(rn8209_loop, "rn8209_loop", RN8209_TASK_STACK_SIZE, NULL, RN8209_TASK_PRIO, NULL); + Log.trace(F("ZsensorRN8209 setup done " CR)); } #endif // ZsensorRN8209 \ No newline at end of file diff --git a/main/config_ONOFF.h b/main/config_ONOFF.h index 6e8cfe4..8e14f5b 100644 --- a/main/config_ONOFF.h +++ b/main/config_ONOFF.h @@ -47,11 +47,18 @@ extern void MQTTtoONOFF(char* topicOri, JsonObject& RFdata); //# define ACTUATOR_BUTTON_TRIGGER_LEVEL LOW // 0 or 1, set to the level which to detect a button press to change the actuator state. #endif #ifndef MAX_TEMP_ACTUATOR -//# define MAX_TEMP_ACTUATOR 70 // Temperature that will trigger the relay to go OFF +//# define MAX_TEMP_ACTUATOR 70.0 // Temperature that will trigger the relay to go OFF #endif +#ifndef MAX_CURRENT_ACTUATOR +//# define MAX_CURRENT_ACTUATOR 15.0 // Current that will trigger the relay to go OFF +#endif + #ifndef TimeBetweenReadingIntTemp # define TimeBetweenReadingIntTemp 5000 // Time interval between internal temp measurement to switch off the relay if MAX_TEMP_ACTUATOR is reached #endif +#ifndef TimeBetweenReadingCurrent +# define TimeBetweenReadingCurrent 1000 // Time interval between internal temp measurement to switch off the relay if MAX_TEMP_ACTUATOR is reached +#endif /*-------------------PIN DEFINITIONS----------------------*/ // default pin, if not set into the MQTT json #ifndef ACTUATOR_ONOFF_GPIO diff --git a/main/main.ino b/main/main.ino index 1bac830..22d8695 100644 --- a/main/main.ino +++ b/main/main.ino @@ -692,6 +692,19 @@ void setup() { Log.notice(F("OpenMQTTGateway Version: " OMG_VERSION CR)); # endif +/* + The 2 modules below are not connection dependent so start them before the connectivity functions + Note that the ONOFF module need to start after the RN8209 so that the overCurrent task is launched after the setup of the sensor +*/ +# ifdef ZsensorRN8209 + setupRN8209(); + modules.add(ZsensorRN8209); +# endif +# ifdef ZactuatorONOFF + setupONOFF(); + modules.add(ZactuatorONOFF); +# endif + String s = WiFi.macAddress(); # ifdef USE_MAC_AS_GATEWAY_NAME sprintf(gateway_name, "%.2s%.2s%.2s%.2s%.2s%.2s", @@ -757,10 +770,6 @@ void setup() { delay(1500); -#ifdef ZactuatorONOFF - setupONOFF(); - modules.add(ZactuatorONOFF); -#endif #ifdef ZsensorBME280 setupZsensorBME280(); modules.add(ZsensorBME280); @@ -898,10 +907,6 @@ void setup() { # endif # define ACTIVE_RECEIVER ACTIVE_RTL #endif -#ifdef ZsensorRN8209 - setupRN8209(); - modules.add(ZsensorRN8209); -#endif #if defined(ZgatewayRTL_433) || defined(ZgatewayRF) || defined(ZgatewayPilight) || defined(ZgatewayRF2) # ifdef DEFAULT_RECEIVER // Allow defining of default receiver as a compiler directive activeReceiver = DEFAULT_RECEIVER; @@ -1587,9 +1592,6 @@ void loop() { #ifdef ZactuatorFASTLED FASTLEDLoop(); #endif -#ifdef ZactuatorONOFF - OverHeatingRelayOFF(); -#endif #ifdef ZactuatorPWM PWMLoop(); #endif