From 25991bfbb44df18563be817afe428db1e1fea3f6 Mon Sep 17 00:00:00 2001 From: Florian Date: Tue, 2 May 2023 10:31:58 -0500 Subject: [PATCH] [RN8209] Publish on change detect and heap usage optim (#1630) Publish the RN8209 depending on a threshold added to a frequency Also merge the 2 tasks into one to save heap --- docs/use/sensors.md | 3 +- main/ZactuatorONOFF.ino | 29 ++++++------- main/ZsensorRN8209.ino | 91 +++++++++++++++++++++-------------------- main/config_RN8209.h | 11 ++++- main/main.ino | 5 ++- 5 files changed, 74 insertions(+), 65 deletions(-) diff --git a/docs/use/sensors.md b/docs/use/sensors.md index 02813cd..ca0dac7 100644 --- a/docs/use/sensors.md +++ b/docs/use/sensors.md @@ -52,6 +52,7 @@ This notification pin can be inverted if driving directly or through a transisto `#define INVERT_LED_NOTIFY true` ### RN8209 -You will receive every TimeBetweenReadingRN8209 (set into config_RN8209.h) the RN8209 measurements (10s per default). +You will receive every `TimeBetweenPublishingRN8209` (set into config_RN8209.h) the RN8209 measurements (every 10s per default), or if the difference between the previous power reading and the new reading is more than 1W and more than 10% of the previous reading. +One reading is done every 0.5s. `home/OpenMQTTGateway/RN8209toMQTT {"volt":120.345,"current":7.9264,"power":954.6132}` diff --git a/main/ZactuatorONOFF.ino b/main/ZactuatorONOFF.ino index b60ffb2..2b889fd 100644 --- a/main/ZactuatorONOFF.ino +++ b/main/ZactuatorONOFF.ino @@ -94,9 +94,6 @@ void ONOFFConfig_load(){}; # endif void setupONOFF() { -# ifdef MAX_CURRENT_ACTUATOR - xTaskCreate(overLimitCurrent, "overLimitCurrent", 4000, NULL, 10, NULL); -# endif # ifdef MAX_TEMP_ACTUATOR xTaskCreate(overLimitTemp, "overLimitTemp", 4000, NULL, 10, NULL); # endif @@ -248,23 +245,21 @@ void overLimitTemp(void* pvParameters) { // 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 (;;) { - static float previousCurrent = 0; - 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 && previousCurrent > MAX_CURRENT_ACTUATOR) { - if (digitalRead(ACTUATOR_ONOFF_GPIO) == ACTUATOR_ON) { // This could be with the previous condition, but it is better to trigger the digitalRead only if the previous condition is met to avoid the digitalRead - Log.error(F("[ActuatorONOFF] OverCurrent detected ( %F > %F ) switching OFF Actuator" CR), current, MAX_CURRENT_ACTUATOR); - ActuatorTrigger(); - CriticalIndicatorON(); - } +void overLimitCurrent(float RN8209current) { + static float RN8209previousCurrent = 0; + Log.trace(F("RN8209 Current %F" CR), RN8209current); + // We switch OFF the actuator if the current of the RN8209 is more than MAX_CURRENT_ACTUATOR. + if (RN8209current > MAX_CURRENT_ACTUATOR && RN8209previousCurrent > MAX_CURRENT_ACTUATOR) { + if (digitalRead(ACTUATOR_ONOFF_GPIO) == ACTUATOR_ON) { // This could be with the previous condition, but it is better to trigger the digitalRead only if the previous condition is met to avoid the digitalRead + Log.error(F("[ActuatorONOFF] OverCurrent detected ( %F > %F ) switching OFF Actuator" CR), RN8209current, MAX_CURRENT_ACTUATOR); + ActuatorTrigger(); + CriticalIndicatorON(); } - previousCurrent = current; - vTaskDelay(TimeBetweenReadingCurrent); } + RN8209previousCurrent = RN8209current; } +# else +void overLimitCurrent(float RN8209current) {} # endif /* diff --git a/main/ZsensorRN8209.ino b/main/ZsensorRN8209.ino index 612f3ea..06a23af 100644 --- a/main/ZsensorRN8209.ino +++ b/main/ZsensorRN8209.ino @@ -33,54 +33,57 @@ extern "C" bool init_8209c_interface(); -StaticJsonDocument doc; +float voltage = 0; +float current = 0; +float power = 0; -// 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; -} +unsigned long PublishingTimerRN8209 = 0; void rn8209_loop(void* mode) { - uint32_t voltage; - int32_t current; - int32_t power; - while (1) { - if (!ProcessLock) { - uint8_t retv = rn8209c_read_voltage(&voltage); - uint8_t ret = rn8209c_read_emu_status(); - uint8_t retc = 1; - uint8_t retp = 1; - if (ret) { - uint32_t temp_current = 0; - uint32_t temp_power = 0; - retc = rn8209c_read_current(phase_A, &temp_current); - retp = rn8209c_read_power(phase_A, &temp_power); - if (ret == 1) { - current = temp_current; - power = temp_power; - } else { - current = (int32_t)temp_current * (-1); - power = (int32_t)temp_power * (-1); - } + uint32_t temp_voltage = 0; + uint8_t retv = rn8209c_read_voltage(&temp_voltage); + uint8_t ret = rn8209c_read_emu_status(); + uint8_t retc = 1; + uint8_t retp = 1; + float previousPower = 0; + if (ret) { + uint32_t temp_current = 0; + uint32_t temp_power = 0; + retc = rn8209c_read_current(phase_A, &temp_current); + retp = rn8209c_read_power(phase_A, &temp_power); + if (ret == 1) { + current = temp_current; + power = temp_power; + } else { + current = (int32_t)temp_current * (-1); + power = (int32_t)temp_power * (-1); } - - JsonObject data = doc.to(); - if (retv == 0) data["volt"] = (float)voltage / 1000.0; - if (retc == 0) data["current"] = (float)current / 10000.0; - if (retp == 0) data["power"] = (float)power / 10000.0; + if (retc == 0) { + current = current / 10000.0; + overLimitCurrent(current); + } + } + StaticJsonDocument<128> doc; + JsonObject data = doc.to(); + if (retc == 0) { + data["current"] = current; + } + if (retv == 0) { + voltage = (float)temp_voltage / 1000.0; + data["volt"] = voltage; + } + if (retp == 0) { + power = power / 10000.0; + data["power"] = power; + } + unsigned long now = millis(); + if ((now > (PublishingTimerRN8209 + TimeBetweenPublishingRN8209) || + !PublishingTimerRN8209 || + (abs(power - previousPower) > previousPower * PreviousPowerThreshold) && abs(power - previousPower) > MinPowerThreshold) && + !ProcessLock) { + PublishingTimerRN8209 = millis(); + previousPower = power; if (data) pub(subjectRN8209toMQTT, data); } delay(TimeBetweenReadingRN8209); @@ -94,7 +97,7 @@ void setupRN8209() { cal.EC = RN8209_EC; set_user_param(cal); init_8209c_interface(); - xTaskCreate(rn8209_loop, "rn8209_loop", RN8209_TASK_STACK_SIZE, NULL, RN8209_TASK_PRIO, NULL); + xTaskCreate(rn8209_loop, "rn8209_loop", RN8209_TASK_STACK_SIZE, NULL, 10, NULL); Log.trace(F("ZsensorRN8209 setup done " CR)); } diff --git a/main/config_RN8209.h b/main/config_RN8209.h index 92541fe..9c238bf 100644 --- a/main/config_RN8209.h +++ b/main/config_RN8209.h @@ -44,6 +44,15 @@ extern void RN8209toMQTT(); #endif #ifndef TimeBetweenReadingRN8209 -# define TimeBetweenReadingRN8209 10000 // time between 2 RN8209 readings in ms +# define TimeBetweenReadingRN8209 500 // time between 2 RN8209 readings in ms +#endif +#ifndef TimeBetweenPublishingRN8209 +# define TimeBetweenPublishingRN8209 10000 // time between 2 RN8209 publishing in ms +#endif +#ifndef PreviousPowerThreshold +# define PreviousPowerThreshold 0.1 // (percentage) threshold of the previous power that will trigger the publishing of the power value +#endif +#ifndef MinPowerThreshold +# define MinPowerThreshold 1 // (watt) Minimum power threshold that will trigger the publishing of the power value combined with PreviousPowerThreshold #endif #endif diff --git a/main/main.ino b/main/main.ino index f239c5c..48505a5 100644 --- a/main/main.ino +++ b/main/main.ino @@ -812,7 +812,7 @@ void setup() { /* 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 + Note that the ONOFF module need to start after the RN8209 so that the overCurrent function is launched after the setup of the sensor */ # ifdef ZsensorRN8209 setupRN8209(); @@ -2227,7 +2227,7 @@ String latestVersion; * Only available for ESP32 */ bool checkForUpdates() { - Log.notice(F("Update check")); + Log.notice(F("Update check, free heap: %d"), ESP.getFreeHeap()); HTTPClient http; http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); http.begin(OTA_JSON_URL, OTAserver_cert); @@ -2260,6 +2260,7 @@ bool checkForUpdates() { Log.trace(F("No update file found on server" CR)); return false; } + Log.notice(F("Update check done, free heap: %d"), ESP.getFreeHeap()); } # elif ESP8266 # include