diff --git a/docs/use/sensors.md b/docs/use/sensors.md index 6830ebbba6..abee7a524a 100644 --- a/docs/use/sensors.md +++ b/docs/use/sensors.md @@ -52,10 +52,10 @@ This notification pin can be inverted if driving directly or through a transisto `#define INVERT_LED_NOTIFY true` ### RN8209 -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. +You will receive every `TimeBetweenPublishingRN8209` (set into config_RN8209.h) the RN8209 measurements (every 60s per default), or if the difference between the previous current reading and the new reading is more than 0.1A. One reading is done every 0.5s. -`home/OpenMQTTGateway/RN8209toMQTT {"volt":120.345,"current":7.9264,"power":954.6132}` +`home/OpenMQTTGateway/RN8209toMQTT {"volt":120.34,"current":7.92,"power":954.61}` ### Touch This sensor is only for ESP32, using the touch sensing peripheral. Up to 10 touch buttons can be defined, linked to 10 ESP32 pins that support touch sensing (GPIOs 0, 2, 4, 12, 13, 14, 15, 27, 32, 33) by defining TOUCH_GPIO, or TOUCH_GPIO_0 through TOUCH_GPIO_9. For example: diff --git a/main/ZsensorRN8209.ino b/main/ZsensorRN8209.ino index 770be5f215..1a7356e6b9 100644 --- a/main/ZsensorRN8209.ino +++ b/main/ZsensorRN8209.ino @@ -26,6 +26,8 @@ */ #ifdef ZsensorRN8209 +# include + # include "ArduinoJson.h" # include "driver/uart.h" # include "rn8209_flash.h" @@ -37,7 +39,10 @@ float voltage = 0; float current = 0; float power = 0; +TaskHandle_t rn8209TaskHandle = nullptr; + unsigned long PublishingTimerRN8209 = 0; +StaticJsonDocument doc; void rn8209_loop(void* mode) { while (1) { @@ -46,46 +51,51 @@ void rn8209_loop(void* mode) { uint8_t ret = rn8209c_read_emu_status(); uint8_t retc = 1; uint8_t retp = 1; - static float previousPower = 0; + static float previousCurrent = 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); } 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) && + (abs(current - previousCurrent) > MinCurrentThreshold)) && !ProcessLock) { + JsonObject data = doc.to(); + if (retc == 0) { + data["current"] = round2(current); + } + uint32_t temp_power = 0; + retp = rn8209c_read_power(phase_A, &temp_power); + if (retv == 0) { + voltage = (float)temp_voltage / 1000.0; + data["volt"] = round2(voltage); + } + if (ret == 1) { + power = temp_power; + } else { + power = (int32_t)temp_power * (-1); + } + if (retp == 0) { + power = power / 10000.0; + data["power"] = round2(power); + } PublishingTimerRN8209 = now; - previousPower = power; - if (data) pub(subjectRN8209toMQTT, data); + previousCurrent = current; + if (data) { + pub(subjectRN8209toMQTT, data); + } } + esp_task_wdt_reset(); delay(TimeBetweenReadingRN8209); } } @@ -97,7 +107,9 @@ void setupRN8209() { cal.EC = RN8209_EC; set_user_param(cal); init_8209c_interface(); - xTaskCreate(rn8209_loop, "rn8209_loop", RN8209_TASK_STACK_SIZE, NULL, 10, NULL); + esp_task_wdt_init(TimeOutWDTRN8209, true); + xTaskCreate(rn8209_loop, "rn8209_loop", 5000, NULL, 10, &rn8209TaskHandle); + esp_task_wdt_add(rn8209TaskHandle); Log.trace(F("ZsensorRN8209 setup done " CR)); } diff --git a/main/config_RN8209.h b/main/config_RN8209.h index 9c238bff82..c8cd17ff96 100644 --- a/main/config_RN8209.h +++ b/main/config_RN8209.h @@ -46,13 +46,14 @@ extern void RN8209toMQTT(); #ifndef TimeBetweenReadingRN8209 # define TimeBetweenReadingRN8209 500 // time between 2 RN8209 readings in ms #endif -#ifndef TimeBetweenPublishingRN8209 -# define TimeBetweenPublishingRN8209 10000 // time between 2 RN8209 publishing in ms + +#ifndef TimeOutWDTRN8209 +# define TimeOutWDTRN8209 60 // time out if RN8209 task is stuck in seconds (should be more than TimeBetweenReadingRN8209/1000), the WDT will reset the ESP #endif -#ifndef PreviousPowerThreshold -# define PreviousPowerThreshold 0.1 // (percentage) threshold of the previous power that will trigger the publishing of the power value +#ifndef TimeBetweenPublishingRN8209 +# define TimeBetweenPublishingRN8209 60000 // time between 2 RN8209 publishing in ms #endif -#ifndef MinPowerThreshold -# define MinPowerThreshold 1 // (watt) Minimum power threshold that will trigger the publishing of the power value combined with PreviousPowerThreshold +#ifndef MinCurrentThreshold +# define MinCurrentThreshold 0.1 // (A) Minimum current change that will trigger the publishing of the RN8209 measurements #endif #endif diff --git a/main/main.ino b/main/main.ino index 0b8056db96..f51b5c8f77 100644 --- a/main/main.ino +++ b/main/main.ino @@ -338,6 +338,14 @@ long value_from_hex_data(const char* service_data, int offset, int data_length, return value; } +/* + rounds a number to 2 decimal places + example: round(3.14159) -> 3.14 +*/ +double round2(double value) { + return (int)(value * 100 + 0.5) / 100.0; +} + /* From an hexa char array ("A220EE...") to a byte array (half the size) */