[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
This commit is contained in:
Florian authored and GitHub committed 2023-05-02 10:31:58 -05:00
1 parent 9bb322daf8
commit 25991bfbb4
5 files changed
+74 -65

No files matched your search

+2 -1
View File
@@ -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}`
+12 -17
View File
@@ -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
/*
+47 -44
View File
@@ -33,54 +33,57 @@
extern "C" bool init_8209c_interface();
StaticJsonDocument<JSON_MSG_BUFFER> 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<JsonObject>();
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<JsonObject>();
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));
}
+10 -1
View File
@@ -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
+3 -2
View File
@@ -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 <ESP8266httpUpdate.h>