From 4aa94015b0f47f757024dd01819d09d12c7696af Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sat, 23 Sep 2023 22:01:37 +0200 Subject: [PATCH 01/12] [P026][Sysvars] Add Internal temperature sensor value for ESP32 --- src/_P026_Sysinfo.ino | 97 ++++++++++++++---------- src/src/CustomBuild/define_plugin_sets.h | 8 ++ src/src/Helpers/Hardware.cpp | 42 ++++++++++ src/src/Helpers/Hardware.h | 4 + src/src/Helpers/StringProvider.cpp | 6 ++ src/src/Helpers/StringProvider.h | 3 + src/src/Helpers/SystemVariables.cpp | 6 ++ src/src/Helpers/SystemVariables.h | 31 ++++---- src/src/PluginStructs/P026_data_struct.h | 19 +++++ src/src/WebServer/SysVarPage.cpp | 3 + 10 files changed, 166 insertions(+), 53 deletions(-) create mode 100644 src/src/PluginStructs/P026_data_struct.h diff --git a/src/_P026_Sysinfo.ino b/src/_P026_Sysinfo.ino index 9139efece0..521f21d505 100644 --- a/src/_P026_Sysinfo.ino +++ b/src/_P026_Sysinfo.ino @@ -5,6 +5,13 @@ // #################################### Plugin 026: System Info ########################################## // ####################################################################################################### +/** Changelog: + * 2023-09-23 tonhuisman: Add Internal temperature option for ESP32 + * Format source using Uncrustify + * Move #if check to P026_data_struct.h as Arduino compiler doesn't support that :( + * Move other defines to P026_data_struct.h + * 2023-09-23 tonhuisman: Start changelog + */ # include "src/DataStructs/ESPEasy_packed_raw_data.h" # include "src/ESPEasyCore/ESPEasyNetwork.h" @@ -17,32 +24,31 @@ # define PLUGIN_ID_026 26 # define PLUGIN_NAME_026 "Generic - System Info" -// place sensor type selector right after the output value settings -# define P026_QUERY1_CONFIG_POS 0 -# define P026_SENSOR_TYPE_INDEX (P026_QUERY1_CONFIG_POS + VARS_PER_TASK) -# define P026_NR_OUTPUT_VALUES getValueCountFromSensorType(static_cast(PCONFIG(P026_SENSOR_TYPE_INDEX))) - -# define P026_NR_OUTPUT_OPTIONS 14 +# include "src/PluginStructs/P026_data_struct.h" // Arduino doesn't do #if in .ino sources :( const __FlashStringHelper* Plugin_026_valuename(uint8_t value_nr, bool displayString) { - const __FlashStringHelper* strings[] { - F("Uptime") , F("uptime"), - F("Free RAM") , F("freeheap"), - F("Wifi RSSI") , F("rssi"), - F("Input VCC") , F("vcc"), - F("System load") , F("load"), - F("IP 1.Octet") , F("ip1"), - F("IP 2.Octet") , F("ip2"), - F("IP 3.Octet") , F("ip3"), - F("IP 4.Octet") , F("ip4"), - F("Web activity") , F("web"), - F("Free Stack") , F("freestack"), - F("None") , F(""), - F("WiFi TX pwr") , F("txpwr"), - F("Free 2nd Heap"), F("free2ndheap") + const __FlashStringHelper *strings[] { + F("Uptime"), F("uptime"), + F("Free RAM"), F("freeheap"), + F("Wifi RSSI"), F("rssi"), + F("Input VCC"), F("vcc"), + F("System load"), F("load"), + F("IP 1.Octet"), F("ip1"), + F("IP 2.Octet"), F("ip2"), + F("IP 3.Octet"), F("ip3"), + F("IP 4.Octet"), F("ip4"), + F("Web activity"), F("web"), + F("Free Stack"), F("freestack"), + F("None"), F(""), + F("WiFi TX pwr"), F("txpwr"), + F("Free 2nd Heap"), F("free2ndheap"), + # if FEATURE_INTERNAL_TEMPERATURE + F("Internal temperature (ESP32)"), F("internaltemp"), + # endif // if FEATURE_INTERNAL_TEMPERATURE }; - const size_t index = (2* value_nr) + (displayString ? 0 : 1); + const size_t index = (2 * value_nr) + (displayString ? 0 : 1); constexpr size_t nrStrings = NR_ELEMENTS(strings); + if (index < nrStrings) { return strings[index]; } @@ -77,6 +83,7 @@ boolean Plugin_026(uint8_t function, struct EventStruct *event, String& string) case PLUGIN_GET_DEVICEVALUENAMES: { const int valueCount = P026_NR_OUTPUT_VALUES; + for (uint8_t i = 0; i < VARS_PER_TASK; ++i) { if (i < valueCount) { const uint8_t pconfigIndex = i + P026_QUERY1_CONFIG_POS; @@ -134,8 +141,9 @@ boolean Plugin_026(uint8_t function, struct EventStruct *event, String& string) // Work around to get the "none" at the end. options[index] = Plugin_026_valuename(11, true); indices[index] = 11; - + const int valueCount = P026_NR_OUTPUT_VALUES; + for (uint8_t i = 0; i < valueCount; ++i) { const uint8_t pconfigIndex = i + P026_QUERY1_CONFIG_POS; sensorTypeHelper_loadOutputSelector(event, pconfigIndex, i, P026_NR_OUTPUT_OPTIONS, options, indices); @@ -153,6 +161,7 @@ boolean Plugin_026(uint8_t function, struct EventStruct *event, String& string) { // Save output selector parameters. const int valueCount = P026_NR_OUTPUT_VALUES; + for (uint8_t i = 0; i < valueCount; ++i) { const uint8_t pconfigIndex = i + P026_QUERY1_CONFIG_POS; const uint8_t choice = PCONFIG(pconfigIndex); @@ -171,10 +180,12 @@ boolean Plugin_026(uint8_t function, struct EventStruct *event, String& string) case PLUGIN_READ: { const int valueCount = P026_NR_OUTPUT_VALUES; + for (int i = 0; i < valueCount; ++i) { UserVar[event->BaseVarIndex + i] = P026_get_value(PCONFIG(i)); } - #ifndef LIMIT_BUILD_SIZE + # ifndef LIMIT_BUILD_SIZE + if (loglevelActiveFor(LOG_LEVEL_INFO)) { String log; @@ -191,7 +202,7 @@ boolean Plugin_026(uint8_t function, struct EventStruct *event, String& string) addLogMove(LOG_LEVEL_INFO, log); } } - #endif + # endif // ifndef LIMIT_BUILD_SIZE success = true; break; } @@ -202,19 +213,23 @@ boolean Plugin_026(uint8_t function, struct EventStruct *event, String& string) // return decode(bytes, // [header, uint24, uint24, int8, vcc, pct_8, uint8, uint8, uint8, uint8, uint24, uint16], // ['header', 'uptime', 'freeheap', 'rssi', 'vcc', 'load', 'ip1', 'ip2', 'ip3', 'ip4', 'web', 'freestack']); + // on ESP32 you can add 'internaltemperature' of type int16 (1e2) to the list uint8_t index = 0; - string += LoRa_addInt(P026_get_value(index++), PackedData_uint24); // uptime - string += LoRa_addInt(P026_get_value(index++), PackedData_uint24); // freeheap - string += LoRa_addFloat(P026_get_value(index++), PackedData_int8); // rssi - string += LoRa_addFloat(P026_get_value(index++), PackedData_vcc); // vcc - string += LoRa_addFloat(P026_get_value(index++), PackedData_pct_8); // load - string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip1 - string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip2 - string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip3 - string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip4 - string += LoRa_addInt(P026_get_value(index++), PackedData_uint24); // web - string += LoRa_addInt(P026_get_value(index++), PackedData_uint16); // freestack - event->Par1 = index; // valuecount + string += LoRa_addInt(P026_get_value(index++), PackedData_uint24); // uptime + string += LoRa_addInt(P026_get_value(index++), PackedData_uint24); // freeheap + string += LoRa_addFloat(P026_get_value(index++), PackedData_int8); // rssi + string += LoRa_addFloat(P026_get_value(index++), PackedData_vcc); // vcc + string += LoRa_addFloat(P026_get_value(index++), PackedData_pct_8); // load + string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip1 + string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip2 + string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip3 + string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip4 + string += LoRa_addInt(P026_get_value(index++), PackedData_uint24); // web + string += LoRa_addInt(P026_get_value(index++), PackedData_uint16); // freestack + # if FEATURE_INTERNAL_TEMPERATURE + string += LoRa_addInt(P026_get_value(index++) * 100.0f, PackedData_int16_1e2); // internal temperature in 0.01 degrees + # endif // if FEATURE_INTERNAL_TEMPERATURE + event->Par1 = index; // valuecount success = true; break; } @@ -226,6 +241,7 @@ boolean Plugin_026(uint8_t function, struct EventStruct *event, String& string) float P026_get_value(uint8_t type) { float res{}; + switch (type) { case 0: res = getUptimeMinutes(); break; @@ -243,7 +259,7 @@ float P026_get_value(uint8_t type) case 6: case 7: case 8: - res = NetworkLocalIP()[type - 5]; break; + res = NetworkLocalIP()[type - 5]; break; case 9: res = timePassedSince(lastWeb) / 1000.0f; break; // respond in seconds case 10: res = getCurrentFreeStack(); break; case 12: res = WiFiEventData.wifi_TX_pwr; break; @@ -252,6 +268,11 @@ float P026_get_value(uint8_t type) res = FreeMem2ndHeap(); # endif // ifdef USE_SECOND_HEAP break; + case 14: + # if FEATURE_INTERNAL_TEMPERATURE + res = getInternalTemperature(); + # endif // if FEATURE_INTERNAL_TEMPERATURE + break; } return res; } diff --git a/src/src/CustomBuild/define_plugin_sets.h b/src/src/CustomBuild/define_plugin_sets.h index b5d110ab30..8f25e5f2b1 100644 --- a/src/src/CustomBuild/define_plugin_sets.h +++ b/src/src/CustomBuild/define_plugin_sets.h @@ -2975,6 +2975,14 @@ To create/register a plugin, you have to : #define FEATURE_PLUGIN_PRIORITY 0 // Disable by default #endif +#ifndef FEATURE_INTERNAL_TEMPERATURE + #if defined(ESP32) // Feature is only available on (most?) ESP32 chips + #define FEATURE_INTERNAL_TEMPERATURE 1 + #else + #define FEATURE_INTERNAL_TEMPERATURE 0 // Not evailable on ESP8266 + #endif +#endif + #ifndef FEATURE_I2C_DEVICE_CHECK #ifdef ESP8266_1M #define FEATURE_I2C_DEVICE_CHECK 0 // Disabled by default for 1M units diff --git a/src/src/Helpers/Hardware.cpp b/src/src/Helpers/Hardware.cpp index 2ad3039b2e..faaf6e1f7d 100644 --- a/src/src/Helpers/Hardware.cpp +++ b/src/src/Helpers/Hardware.cpp @@ -604,6 +604,48 @@ int espeasy_analogRead(int pin, bool readAsTouch) { #endif // ifdef ESP32 +#if FEATURE_INTERNAL_TEMPERATURE + +/** + * Code based on: https://github.com/esphome/esphome/blob/518ecb4cc4489c8a76b899bfda7576b05d84c226/esphome/components/internal_temperature/internal_temperature.cpp#L40 + */ + +#ifdef ESP32 +#if defined(ESP32_CLASSIC) +// there is no official API available on the original ESP32 +extern "C" { +uint8_t temprature_sens_read(); +} +#elif defined(ESP32C3) || defined(ESP32S2) || defined(ESP32S3) +#include "driver/temp_sensor.h" +#endif // ESP32_CLASSIC +#endif // ESP32 + +float getInternalTemperature() { + float temperature = -273.15f; // Inprobable value + bool success; + #ifdef ESP32 + #if defined(ESP32_CLASSIC) + uint8_t raw = temprature_sens_read(); + #ifndef BUILD_NO_DEBUG + addLog(LOG_LEVEL_DEBUG, concat(F("ESP32: Raw temperature value: "), raw)); + #endif + success = (raw != 128); + temperature = (raw - 32) / 1.8f; + #elif defined(ESP32C3) || defined(ESP32S2) || defined(ESP32S3) + temp_sensor_config_t tsens = TSENS_CONFIG_DEFAULT(); + temp_sensor_set_config(tsens); + temp_sensor_start(); + esp_err_t result = temp_sensor_read_celsius(&temperature); + temp_sensor_stop(); + if (result = ESP_OK) { + temperature = -273.15f; + } + #endif // ESP32_CLASSIC + #endif // USE_ESP32 + return temperature; +} +#endif // if FEATURE_INTERNAL_TEMPERATURE /********************************************************************************************\ Hardware information diff --git a/src/src/Helpers/Hardware.h b/src/src/Helpers/Hardware.h index d443780e22..c0704bae1d 100644 --- a/src/src/Helpers/Hardware.h +++ b/src/src/Helpers/Hardware.h @@ -70,6 +70,10 @@ int espeasy_analogRead(int pin, extern esp_adc_cal_characteristics_t adc_chars[ADC_ATTEN_MAX]; #endif // ifdef ESP32 +#if FEATURE_INTERNAL_TEMPERATURE +float getInternalTemperature(); +#endif // if FEATURE_INTERNAL_TEMPERATURE + /********************************************************************************************\ Hardware information diff --git a/src/src/Helpers/StringProvider.cpp b/src/src/Helpers/StringProvider.cpp index b63bfbe38f..7b974c457a 100644 --- a/src/src/Helpers/StringProvider.cpp +++ b/src/src/Helpers/StringProvider.cpp @@ -237,6 +237,9 @@ const __FlashStringHelper * getLabel(LabelType::Enum label) { case LabelType::MAX_OTA_SKETCH_SIZE: return F("Max. OTA Sketch Size"); case LabelType::OTA_2STEP: return F("OTA 2-step Needed"); case LabelType::OTA_POSSIBLE: return F("OTA possible"); + #if FEATURE_INTERNAL_TEMPERATURE + case LabelType::INTERNAL_TEMPERATURE: return F("Internal temperature (ESP32)"); + #endif // if FEATURE_INTERNAL_TEMPERATURE #if FEATURE_ETHERNET case LabelType::ETH_IP_ADDRESS: return F("Eth IP Address"); case LabelType::ETH_IP_SUBNET: return F("Eth IP Subnet"); @@ -413,6 +416,9 @@ String getValue(LabelType::Enum label) { case LabelType::IP_ADDRESS_SUBNET: return getValue(LabelType::IP_ADDRESS) + F(" / ") + getValue(LabelType::IP_SUBNET); case LabelType::GATEWAY: return formatIP(NetworkGatewayIP()); case LabelType::CLIENT_IP: return formatIP(web_server.client().remoteIP()); + #if FEATURE_INTERNAL_TEMPERATURE + case LabelType::INTERNAL_TEMPERATURE: return toString(getInternalTemperature()); + #endif // if FEATURE_INTERNAL_TEMPERATURE #if FEATURE_MDNS case LabelType::M_DNS: return NetworkGetHostname() + F(".local"); diff --git a/src/src/Helpers/StringProvider.h b/src/src/Helpers/StringProvider.h index 8e9e2d7333..9ac08a48b8 100644 --- a/src/src/Helpers/StringProvider.h +++ b/src/src/Helpers/StringProvider.h @@ -183,6 +183,9 @@ struct LabelType { MAX_OTA_SKETCH_SIZE, OTA_2STEP, OTA_POSSIBLE, + #if FEATURE_INTERNAL_TEMPERATURE + INTERNAL_TEMPERATURE, + #endif // if FEATURE_INTERNAL_TEMPERATURE #if FEATURE_ETHERNET ETH_IP_ADDRESS, ETH_IP_SUBNET, diff --git a/src/src/Helpers/SystemVariables.cpp b/src/src/Helpers/SystemVariables.cpp index 79fcaf59c8..7b9f2c1364 100644 --- a/src/src/Helpers/SystemVariables.cpp +++ b/src/src/Helpers/SystemVariables.cpp @@ -89,6 +89,9 @@ LabelType::Enum SystemVariables2LabelType(SystemVariables::Enum enumval) { case SystemVariables::DNS_2: label = LabelType::DNS_2; break; case SystemVariables::GATEWAY: label = LabelType::GATEWAY; break; case SystemVariables::CLIENTIP: label = LabelType::CLIENT_IP; break; + #if FEATURE_INTERNAL_TEMPERATURE + case SystemVariables::INTERNAL_TEMPERATURE: label = LabelType::INTERNAL_TEMPERATURE; break; + #endif // if FEATURE_INTERNAL_TEMPERATURE #if FEATURE_ETHERNET @@ -359,6 +362,9 @@ const __FlashStringHelper * SystemVariables::toFlashString(SystemVariables::Enum case Enum::ISMQTTIMP: return F("ismqttimp"); case Enum::ISNTP: return F("isntp"); case Enum::ISWIFI: return F("iswifi"); + #if FEATURE_INTERNAL_TEMPERATURE + case Enum::INTERNAL_TEMPERATURE: return F("internaltemperature"); + #endif // if FEATURE_INTERNAL_TEMPERATURE #if FEATURE_ETHERNET case Enum::ETHWIFIMODE: return F("ethwifimode"); case Enum::ETHCONNECTED: return F("ethconnected"); diff --git a/src/src/Helpers/SystemVariables.h b/src/src/Helpers/SystemVariables.h index d1965a78ab..e4cb077f57 100644 --- a/src/src/Helpers/SystemVariables.h +++ b/src/src/Helpers/SystemVariables.h @@ -4,7 +4,6 @@ #include "../../ESPEasy_common.h" class SystemVariables { - public: enum Enum : uint8_t { @@ -13,13 +12,16 @@ class SystemVariables { BSSID, CR, IP, - IP4, // 4th IP octet + IP4, // 4th IP octet SUBNET, GATEWAY, DNS, DNS_1, DNS_2, CLIENTIP, + #if FEATURE_INTERNAL_TEMPERATURE + INTERNAL_TEMPERATURE, + #endif // if FEATURE_INTERNAL_TEMPERATURE ISMQTT, ISMQTTIMP, ISNTP, @@ -85,7 +87,7 @@ class SystemVariables { SYS_MONTH_0, S_CR, S_LF, - UNIT_sysvar, // We already use UNIT as define. + UNIT_sysvar, // We already use UNIT as define. #if FEATURE_ZEROFILLED_UNITNUMBER UNIT_0_sysvar, #endif // FEATURE_ZEROFILLED_UNITNUMBER @@ -96,12 +98,12 @@ class SystemVariables { UPTIME_MS, VCC, WI_CH, - FLASH_FREQ, // Frequency of the flash chip - FLASH_SIZE, // Real size of the flash chip + FLASH_FREQ, // Frequency of the flash chip + FLASH_SIZE, // Real size of the flash chip FLASH_CHIP_VENDOR, FLASH_CHIP_MODEL, - FS_SIZE, // Size of the file system - FS_FREE, // Free space (in bytes) on the file system + FS_SIZE, // Size of the file system + FS_FREE, // Free space (in bytes) on the file system ESP_CHIP_ID, ESP_CHIP_FREQ, @@ -117,18 +119,17 @@ class SystemVariables { // Find the next thing to replace. // Return UNKNOWN when nothing needs to be replaced. - static SystemVariables::Enum nextReplacementEnum(const String& str, SystemVariables::Enum last_tested); - - static String toString(SystemVariables::Enum enumval); - static const __FlashStringHelper * toFlashString(SystemVariables::Enum enumval); + static SystemVariables::Enum nextReplacementEnum(const String & str, + SystemVariables::Enum last_tested); - static String getSystemVariable(SystemVariables::Enum enumval); + static String toString(SystemVariables::Enum enumval); + static const __FlashStringHelper* toFlashString(SystemVariables::Enum enumval); - static void parseSystemVariables(String& s, boolean useURLencode); + static String getSystemVariable(SystemVariables::Enum enumval); + static void parseSystemVariables(String& s, + boolean useURLencode); }; - - #endif // HELPERS_SYSTEMVARIABLES_H diff --git a/src/src/PluginStructs/P026_data_struct.h b/src/src/PluginStructs/P026_data_struct.h new file mode 100644 index 0000000000..728e5d355c --- /dev/null +++ b/src/src/PluginStructs/P026_data_struct.h @@ -0,0 +1,19 @@ +#ifndef PLUGINSTRUCTS_P026_DATA_STRUCT_H +#define PLUGINSTRUCTS_P026_DATA_STRUCT_H + +#include "../../_Plugin_Helper.h" +#ifdef USES_P026 + +// place sensor type selector right after the output value settings +# define P026_QUERY1_CONFIG_POS 0 +# define P026_SENSOR_TYPE_INDEX (P026_QUERY1_CONFIG_POS + VARS_PER_TASK) +# define P026_NR_OUTPUT_VALUES getValueCountFromSensorType(static_cast(PCONFIG(P026_SENSOR_TYPE_INDEX))) + +# if FEATURE_INTERNAL_TEMPERATURE +# define P026_NR_OUTPUT_OPTIONS 15 +# else // if FEATURE_INTERNAL_TEMPERATURE +# define P026_NR_OUTPUT_OPTIONS 14 +# endif // if FEATURE_INTERNAL_TEMPERATURE + +#endif // ifdef USES_P026 +#endif // ifndef PLUGINSTRUCTS_P026_DATA_STRUCT_H diff --git a/src/src/WebServer/SysVarPage.cpp b/src/src/WebServer/SysVarPage.cpp index 1a356b417b..370eb24c74 100644 --- a/src/src/WebServer/SysVarPage.cpp +++ b/src/src/WebServer/SysVarPage.cpp @@ -91,6 +91,9 @@ void handle_sysvars() { #if FEATURE_ADC_VCC addSysVar_enum_html(SystemVariables::VCC); #endif // if FEATURE_ADC_VCC + #if FEATURE_INTERNAL_TEMPERATURE + addSysVar_enum_html(SystemVariables::INTERNAL_TEMPERATURE); + #endif // if FEATURE_INTERNAL_TEMPERATURE addTableSeparator(F("Services Status"), 3, 3); From 4e0ac295aa92103be40e5bc4e3cfd4cd83743367 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sat, 23 Sep 2023 23:15:17 +0200 Subject: [PATCH 02/12] [P026][Sysvars] Feedback and fixes --- src/_P026_Sysinfo.ino | 32 ++++++++++++++--------------- src/src/Helpers/Hardware.cpp | 8 ++++---- src/src/Helpers/SystemVariables.cpp | 2 +- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/_P026_Sysinfo.ino b/src/_P026_Sysinfo.ino index 521f21d505..f77449d73e 100644 --- a/src/_P026_Sysinfo.ino +++ b/src/_P026_Sysinfo.ino @@ -213,23 +213,23 @@ boolean Plugin_026(uint8_t function, struct EventStruct *event, String& string) // return decode(bytes, // [header, uint24, uint24, int8, vcc, pct_8, uint8, uint8, uint8, uint8, uint24, uint16], // ['header', 'uptime', 'freeheap', 'rssi', 'vcc', 'load', 'ip1', 'ip2', 'ip3', 'ip4', 'web', 'freestack']); - // on ESP32 you can add 'internaltemperature' of type int16 (1e2) to the list + // on ESP32 you can add 'internaltemperature' of type int16 (1e2) to the list (disabled for now, so not available) uint8_t index = 0; - string += LoRa_addInt(P026_get_value(index++), PackedData_uint24); // uptime - string += LoRa_addInt(P026_get_value(index++), PackedData_uint24); // freeheap - string += LoRa_addFloat(P026_get_value(index++), PackedData_int8); // rssi - string += LoRa_addFloat(P026_get_value(index++), PackedData_vcc); // vcc - string += LoRa_addFloat(P026_get_value(index++), PackedData_pct_8); // load - string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip1 - string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip2 - string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip3 - string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip4 - string += LoRa_addInt(P026_get_value(index++), PackedData_uint24); // web - string += LoRa_addInt(P026_get_value(index++), PackedData_uint16); // freestack - # if FEATURE_INTERNAL_TEMPERATURE - string += LoRa_addInt(P026_get_value(index++) * 100.0f, PackedData_int16_1e2); // internal temperature in 0.01 degrees - # endif // if FEATURE_INTERNAL_TEMPERATURE - event->Par1 = index; // valuecount + string += LoRa_addInt(P026_get_value(index++), PackedData_uint24); // uptime + string += LoRa_addInt(P026_get_value(index++), PackedData_uint24); // freeheap + string += LoRa_addFloat(P026_get_value(index++), PackedData_int8); // rssi + string += LoRa_addFloat(P026_get_value(index++), PackedData_vcc); // vcc + string += LoRa_addFloat(P026_get_value(index++), PackedData_pct_8); // load + string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip1 + string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip2 + string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip3 + string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip4 + string += LoRa_addInt(P026_get_value(index++), PackedData_uint24); // web + string += LoRa_addInt(P026_get_value(index++), PackedData_uint16); // freestack + // # if FEATURE_INTERNAL_TEMPERATURE + // string += LoRa_addInt(P026_get_value(index++) * 100.0f, PackedData_int16_1e2); // internal temperature in 0.01 degrees + // # endif // if FEATURE_INTERNAL_TEMPERATURE + event->Par1 = index; // valuecount success = true; break; } diff --git a/src/src/Helpers/Hardware.cpp b/src/src/Helpers/Hardware.cpp index faaf6e1f7d..204af9864c 100644 --- a/src/src/Helpers/Hardware.cpp +++ b/src/src/Helpers/Hardware.cpp @@ -623,22 +623,22 @@ uint8_t temprature_sens_read(); float getInternalTemperature() { float temperature = -273.15f; // Inprobable value - bool success; #ifdef ESP32 #if defined(ESP32_CLASSIC) uint8_t raw = temprature_sens_read(); #ifndef BUILD_NO_DEBUG addLog(LOG_LEVEL_DEBUG, concat(F("ESP32: Raw temperature value: "), raw)); #endif - success = (raw != 128); - temperature = (raw - 32) / 1.8f; + if (raw != 128) { + temperature = (raw - 32) / 1.8f; + } #elif defined(ESP32C3) || defined(ESP32S2) || defined(ESP32S3) temp_sensor_config_t tsens = TSENS_CONFIG_DEFAULT(); temp_sensor_set_config(tsens); temp_sensor_start(); esp_err_t result = temp_sensor_read_celsius(&temperature); temp_sensor_stop(); - if (result = ESP_OK) { + if (result != ESP_OK) { temperature = -273.15f; } #endif // ESP32_CLASSIC diff --git a/src/src/Helpers/SystemVariables.cpp b/src/src/Helpers/SystemVariables.cpp index 7b9f2c1364..c5590e0d12 100644 --- a/src/src/Helpers/SystemVariables.cpp +++ b/src/src/Helpers/SystemVariables.cpp @@ -363,7 +363,7 @@ const __FlashStringHelper * SystemVariables::toFlashString(SystemVariables::Enum case Enum::ISNTP: return F("isntp"); case Enum::ISWIFI: return F("iswifi"); #if FEATURE_INTERNAL_TEMPERATURE - case Enum::INTERNAL_TEMPERATURE: return F("internaltemperature"); + case Enum::INTERNAL_TEMPERATURE: return F("inttemp"); #endif // if FEATURE_INTERNAL_TEMPERATURE #if FEATURE_ETHERNET case Enum::ETHWIFIMODE: return F("ethwifimode"); From 8ad3b5bdfb5b9e0b0b40a8e6db426e203bdc696b Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sun, 24 Sep 2023 13:57:49 +0200 Subject: [PATCH 03/12] [P026][Sysvars] Fix typo in comment --- src/src/Helpers/Hardware.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/src/Helpers/Hardware.cpp b/src/src/Helpers/Hardware.cpp index 204af9864c..702b21f86f 100644 --- a/src/src/Helpers/Hardware.cpp +++ b/src/src/Helpers/Hardware.cpp @@ -622,7 +622,7 @@ uint8_t temprature_sens_read(); #endif // ESP32 float getInternalTemperature() { - float temperature = -273.15f; // Inprobable value + float temperature = -273.15f; // Improbable value #ifdef ESP32 #if defined(ESP32_CLASSIC) uint8_t raw = temprature_sens_read(); From 31653e8b41970ab6a03e90f1b4d6319d28cf60bf Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sun, 24 Sep 2023 19:49:24 +0200 Subject: [PATCH 04/12] [P026] Add Get Config feature for all values --- src/_P026_Sysinfo.ino | 25 +++++++++++++++++------- src/src/PluginStructs/P026_data_struct.h | 7 +++++++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/_P026_Sysinfo.ino b/src/_P026_Sysinfo.ino index f77449d73e..2a7b0eb679 100644 --- a/src/_P026_Sysinfo.ino +++ b/src/_P026_Sysinfo.ino @@ -6,6 +6,9 @@ // ####################################################################################################### /** Changelog: + * 2023-09-24 tonhuisman: Add support for getting all values via Get Config option [#] where is the default + * name as set for an output value. None is ignored. Not available in MINIMAL_OTA builds. + * Move all includes to P026_data_struct.h * 2023-09-23 tonhuisman: Add Internal temperature option for ESP32 * Format source using Uncrustify * Move #if check to P026_data_struct.h as Arduino compiler doesn't support that :( @@ -13,13 +16,6 @@ * 2023-09-23 tonhuisman: Start changelog */ -# include "src/DataStructs/ESPEasy_packed_raw_data.h" -# include "src/ESPEasyCore/ESPEasyNetwork.h" -# include "src/Globals/ESPEasyWiFiEvent.h" -# include "src/Helpers/Memory.h" - -# include "ESPEasy-Globals.h" - # define PLUGIN_026 # define PLUGIN_ID_026 26 # define PLUGIN_NAME_026 "Generic - System Info" @@ -206,6 +202,21 @@ boolean Plugin_026(uint8_t function, struct EventStruct *event, String& string) success = true; break; } + # ifndef PLUGIN_BUILD_MINIMAL_OTA + case PLUGIN_GET_CONFIG_VALUE: + { + const String cmd = parseString(string, 1); + + for (uint8_t option = 0; option < P026_NR_OUTPUT_OPTIONS; ++option) { + if ((option != 11) && equals(cmd, Plugin_026_valuename(option, false))) { // Use default valuename + string = floatToString(P026_get_value(option), 2, true); // Trim trailing zeroes + success = true; + break; + } + } + break; + } + # endif // ifndef PLUGIN_BUILD_MINIMAL_OTA # if FEATURE_PACKED_RAW_DATA case PLUGIN_GET_PACKED_RAW_DATA: { diff --git a/src/src/PluginStructs/P026_data_struct.h b/src/src/PluginStructs/P026_data_struct.h index 728e5d355c..17b091b7e2 100644 --- a/src/src/PluginStructs/P026_data_struct.h +++ b/src/src/PluginStructs/P026_data_struct.h @@ -4,6 +4,13 @@ #include "../../_Plugin_Helper.h" #ifdef USES_P026 +# include "src/DataStructs/ESPEasy_packed_raw_data.h" +# include "src/ESPEasyCore/ESPEasyNetwork.h" +# include "src/Globals/ESPEasyWiFiEvent.h" +# include "src/Helpers/Memory.h" + +# include "ESPEasy-Globals.h" + // place sensor type selector right after the output value settings # define P026_QUERY1_CONFIG_POS 0 # define P026_SENSOR_TYPE_INDEX (P026_QUERY1_CONFIG_POS + VARS_PER_TASK) From 384ab4df8bed968e67c69aa13898b9fbf985fc7b Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sun, 24 Sep 2023 19:57:31 +0200 Subject: [PATCH 05/12] [P026] Add documentation --- docs/source/Plugin/P026.rst | 60 ++++++++++++++++-- .../Plugin/P026_DeviceConfiguration.png | Bin 0 -> 49504 bytes .../Plugin/P026_NumberOutputOptions.png | Bin 0 -> 14527 bytes docs/source/Plugin/P026_ValuesOptions.png | Bin 0 -> 45035 bytes docs/source/Plugin/P026_config_values.repl | 59 +++++++++++++++++ 5 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 docs/source/Plugin/P026_DeviceConfiguration.png create mode 100644 docs/source/Plugin/P026_NumberOutputOptions.png create mode 100644 docs/source/Plugin/P026_ValuesOptions.png create mode 100644 docs/source/Plugin/P026_config_values.repl diff --git a/docs/source/Plugin/P026.rst b/docs/source/Plugin/P026.rst index 01080d1a37..dcb0964d17 100644 --- a/docs/source/Plugin/P026.rst +++ b/docs/source/Plugin/P026.rst @@ -1,4 +1,4 @@ -.. include:: ../Plugin/_plugin_substitutions_p02x.repl +.. include:: ../Plugin/_plugin_substitutions_p02x.repl .. _P026_page: |P026_typename| @@ -21,10 +21,48 @@ Maintainer: |P026_maintainer| Used libraries: |P026_usedlibraries| -Supported hardware ------------------- +.. Supported hardware +.. ------------------ -|P026_usedby| +.. .. |P026_usedby| + +Introduction +------------ + +To monitor some internal values of an ESPEasy equiped device, the SysInfo plugin is available. This device can show up to 4 values showing user-selected system data. + +Configuration +------------- + +.. image:: P026_DeviceConfiguration.png + +* **Name** A unique name should be entered here. + +* **Enabled** The device can be disabled or enabled. When not enabled the device should not use any resources. + +Output configuration +^^^^^^^^^^^^^^^^^^^^ + +* **Number Output Values**: Select from 1 to 4 output values, default is 4 (Quad). If more values are to be used, multiple tasks can be configured using this plugin. + +.. image:: P026_NumberOutputOptions.png + +* **Value 1..4**: Depending on the **Number Output Values** selection, 1 to 4 selections for output values are available. These can be chosen as desired. + +.. image:: P026_ValuesOptions.png + +* *Uptime*: The uptime of the unit in minutes. +* *Free RAM*: The amount of free memory in bytes. +* *Wifi RSSI*: The RSSI (Received signal strength indicator) value. This is a negative value. +* *Input VCC*: The voltage applied to the 3.3V VCC input of the ESP. This value is **only** available on ESP8266 builds with VCC enabled (included in the build name), else 0 will be shown. +* *System load*: The load as displayed on the Main and Info pages, a percentage in range 0 .. 100. +* *IP 1.Octet* .. *IP 4.Octet*: The separate parts of the active IP address of the unit, the octets are counted from left to right. +* *Web activity*: The time passed since the last web activity at the unit. Measured in seconds. +* *Free Stack*: The available stack space in bytes. +* *WiFi TX pwr*: The current setting for transmit power via WiFi. This is determined dynamically, depending on the corresponding settings in the Tools/Advanced page, RSSI and other factors. +* *Free 2nd Heap*: The available memory on the 2nd heap, **only** available in some specific ESP8266 builds, else it shows 0. +* *Internal temperature (ESP32)*: The internal temperature of the ESP. **Only** available on ESP32 units. For ESP32-S2/S3/C2/C3/C6 MCUs there is official support for the internal temperature sensor via the Espressif libraries, that has compensation applied so it shows a realistic value. For ESP32 Classic this is determined empirically, based on the deviation of the 150 kHz internal clock generator, that is rather temperature dependent, compared to the (stable) crystal frequency. This should not be seen as an absolute temperature, but *can* be used as a relative measurement f.e. when comparing heavy load vs. light load situations. +* *None*: No value. .. Commands available .. ^^^^^^^^^^^^^^^^^^ @@ -36,6 +74,20 @@ Supported hardware .. .. include:: P026_events.repl +Data Acquisition +^^^^^^^^^^^^^^^^ + +This group of settings, **Single event with all values** and **Send to Controller** settings are standard available configuration items. Send to Controller is only visible when one or more Controllers are configured. + +* **Interval** By default, Interval will be set to 60 sec. The data will be collected, and event(s) generated, using this interval. + +Get Config values +~~~~~~~~~~~~~~~~~ + +These values are not available in *Minimal OTA* builds. + +.. include:: P026_config_values.repl + Change log ---------- diff --git a/docs/source/Plugin/P026_DeviceConfiguration.png b/docs/source/Plugin/P026_DeviceConfiguration.png new file mode 100644 index 0000000000000000000000000000000000000000..befceacc7dff0140ba6218955efc6782b8ad3ea3 GIT binary patch literal 49504 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%0An3{OBX5ns(ASF^~ei9$>94Ss}Ap}Htk%I4* z&MEPrgkG2PoWVa>6K$UE4v!;7wmY^j420syP-RH066Cx%*IE^<4!#9ZJ;I+p206}& z6vhQ-R<;FZ296kUF-S8Yp+(2z;|skQO7hF30y4vX@CicQ~(qCt6sL?;T=PW81Z}unf!yUfMPE!w_u6{8sInG@pu82uI zmm&ilryUV8^KU03Y6wAZBDK>9zz{uYwN1GtG&cO%%u=SRIUTks#SdQCMrr*&Yfks- zH7rnysu6m{a=FQ4NpCB-e$`QP1g|}6*c{n1e(gsM%?yz)TYX0 z3}2Ez*HqCj53Pu5Y;KWVLkr>?wsfuM4C4f>K*vHlsreY)Wnfot5cUM}V}kxC~0~_;-n~soI?d zi}kz2n>_rv`{n5{xHU(CMUx$IvZ>)d`h4n>#Nt%AlJfb?VmPw2#hqJ4R-c4UTr+`lI%{-ASQUnTQz9cT>IH%#Y28!8`WQYno#%)#daeV zlQwcx`|FDtQXg_BV8#;a3?Gh3+iC1+IJ=dOK`w7|-zKoM(sx3${w5c_ebOXbH!bJb z^!}K59&_wZt{jbUp$TyGbKg@a52AioR^Hr;PuyT=kXLQ#tbR4l|veIXI?PG#)?I3NIz3;58-ADx60t>G~*cxsd zCcmw->nHA!Kd3%#s4eLD5Rs?cmp8IU<6GSE;eU>c&v22OXw5*)iuL`Zv(J2K-ppQa z<|RCXUr*HZ;n{Nti+UP}aI(wwGG?=7PtK!(gP=<*bphZ@3a`aWC(kX#zMM{Q19CGZ zhYxRC=FkCDq`yb~F*O}zrg(qM@Zqo!-|&{;N!A%#yY6*5$Is~qPWN-*_u)z6R4PS| wEd%KF9&QFmgXD=1veYT>Cu$=yBCC-@u=#J{Pk77oFqHt^fc4 literal 0 HcmV?d00001 diff --git a/docs/source/Plugin/P026_NumberOutputOptions.png b/docs/source/Plugin/P026_NumberOutputOptions.png new file mode 100644 index 0000000000000000000000000000000000000000..2087f40e43197ed9bf5e54fb31ce801112594495 GIT binary patch literal 14527 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 JD-~^m{~vT;F^2#E literal 0 HcmV?d00001 diff --git a/docs/source/Plugin/P026_config_values.repl b/docs/source/Plugin/P026_config_values.repl new file mode 100644 index 0000000000..a8ebdaa5e2 --- /dev/null +++ b/docs/source/Plugin/P026_config_values.repl @@ -0,0 +1,59 @@ +.. csv-table:: + :header: "Config value", "Information" + :widths: 20, 30 + + " + | ``[#uptime]`` + "," + | Returns the uptime of the unit in minutes. + " + " + | ``[#freeheap]`` + "," + | Returns the amount of free memory in bytes. + " + " + | ``[#rssi]`` + "," + | Returns the RSSI (Received signal strength indicator) value. This is a negative value. + " + " + | ``[#vcc]`` + "," + | Returns the voltage applied to the 3.3V VCC input of the ESP. This value is **only** available on ESP8266 builds with VCC enabled (included in the build name), else 0 will be shown. + " + " + | ``[#load]`` + "," + | Returns the load as displayed on the Main and Info pages, a percentage in range 0 .. 100. + " + " + | ``[#ip1]`` .. ``[#ip4]`` + "," + | Returns the separate parts of the active IPv4 address of the unit, the parts 1..4 are counted from left to right. + " + " + | ``[#web]`` + "," + | Returns the time passed since the last web activity at the unit. Measured in seconds. + " + " + | ``[#freestack]`` + "," + | Returns the available stack space in bytes. + " + " + | ``[#txpwr]`` + "," + | Returns the current setting for transmit power via WiFi. This is determined dynamically, depending on the corresponding settings in the Tools/Advanced page, RSSI and other factors. + " + " + | ``[#free2ndheap]`` + "," + | Returns the available memory on the 2nd heap, **only** available in some specific ESP8266 builds, else it shows 0. + " + " + | ``[#internaltemp]`` + "," + | Returns the internal temperature of the ESP. **Only** available on ESP32 units. For ESP32-S2/S3/C2/C3/C6 MCUs there is official support for the internal temperature sensor via the Espressif libraries, that has compensation applied so it shows a realistic value. For ESP32 Classic this is determined empirically, based on the deviation of the 150 kHz internal clock generator, that is rather temperature dependent, compared to the (stable) crystal frequency. This should not be seen as an absolute temperature, but *can* be used as a relative measurement f.e. when comparing heavy load vs. light load situations. + " From 210d19239d77fa7cc53697511c60aa44a21a37d6 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Mon, 25 Sep 2023 23:08:44 +0200 Subject: [PATCH 06/12] [P026][Sysvars] Avoid temperature reading errors on ESP32 classic (2 tries only) --- src/src/Helpers/Hardware.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/src/Helpers/Hardware.cpp b/src/src/Helpers/Hardware.cpp index 702b21f86f..97223a2079 100644 --- a/src/src/Helpers/Hardware.cpp +++ b/src/src/Helpers/Hardware.cpp @@ -622,10 +622,15 @@ uint8_t temprature_sens_read(); #endif // ESP32 float getInternalTemperature() { - float temperature = -273.15f; // Improbable value + static float temperature = -273.15f; // Improbable value + int8_t retries = 2; #ifdef ESP32 #if defined(ESP32_CLASSIC) - uint8_t raw = temprature_sens_read(); + uint8_t raw = 128u; + while ((128u == raw) && (0 != retries)) { + raw = temprature_sens_read(); // Each reading takes about 112 microseconds + --retries; + } #ifndef BUILD_NO_DEBUG addLog(LOG_LEVEL_DEBUG, concat(F("ESP32: Raw temperature value: "), raw)); #endif @@ -635,11 +640,12 @@ float getInternalTemperature() { #elif defined(ESP32C3) || defined(ESP32S2) || defined(ESP32S3) temp_sensor_config_t tsens = TSENS_CONFIG_DEFAULT(); temp_sensor_set_config(tsens); + float tmpTemp = 0.0f; temp_sensor_start(); - esp_err_t result = temp_sensor_read_celsius(&temperature); + esp_err_t result = temp_sensor_read_celsius(&tmpTemp); temp_sensor_stop(); - if (result != ESP_OK) { - temperature = -273.15f; + if (result == ESP_OK) { + temperature = tmpTemp; } #endif // ESP32_CLASSIC #endif // USE_ESP32 From 36ca64e6f461a6483dbe6a6d702ad1dbaa24f9ae Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Mon, 25 Sep 2023 23:09:24 +0200 Subject: [PATCH 07/12] [P026][Sysvars] Read temperature every second on ESP32 classic for better results --- src/src/Helpers/PeriodicalActions.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/src/Helpers/PeriodicalActions.cpp b/src/src/Helpers/PeriodicalActions.cpp index 391bbdbec9..c6ad41ec0a 100644 --- a/src/src/Helpers/PeriodicalActions.cpp +++ b/src/src/Helpers/PeriodicalActions.cpp @@ -185,6 +185,9 @@ void runOncePerSecond() #endif #endif // if FEATURE_MDNS + #if FEATURE_INTERNAL_TEMPERATURE && defined(ESP32_CLASSIC) + getInternalTemperature(); // Just read the value every second to hopefully get a valid next reading on original ESP32 + #endif // if FEATURE_INTERNAL_TEMPERATURE && defined(ESP32_CLASSIC) checkResetFactoryPin(); STOP_TIMER(PLUGIN_CALL_1PS); From e672b51d25fe836656151e466543c9e4049e9cf1 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Mon, 25 Sep 2023 23:11:58 +0200 Subject: [PATCH 08/12] [Build] Try to use real branch name on GH Actions builds --- tools/pio/generate-compiletime-defines.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/pio/generate-compiletime-defines.py b/tools/pio/generate-compiletime-defines.py index 9a5a710d29..367430683f 100644 --- a/tools/pio/generate-compiletime-defines.py +++ b/tools/pio/generate-compiletime-defines.py @@ -72,7 +72,9 @@ def get_git_description(): from pygit2 import Repository try: repo = Repository('.') - return "{0}_{1}".format(repo.head.shorthand, repo.revparse_single('HEAD').short_id) + return "{0}_{1}".format(repo.head.name + .replace("refs/heads/","",1) + .replace("refs/tags/","",1), repo.revparse_single('HEAD').short_id) except: return 'No_.git_dir' except ImportError: From 43527d5a9a1d7305f41f5548ce21558725c29232 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Mon, 25 Sep 2023 23:13:18 +0200 Subject: [PATCH 09/12] [Build] Ignore Docs commits to trigger an Actions run --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 61770de129..580eb5e132 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,6 +8,7 @@ on: tags-ignore: '**' paths-ignore: - 'dist/Release_notes.txt' + - 'docs/**' pull_request: branches: [mega] From e96bfb2e90fd88ae18ed97371a3dd4dae39d9fde Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Mon, 25 Sep 2023 23:26:01 +0200 Subject: [PATCH 10/12] [P026][Sysvars] Explicitly disable FEATURE_INTERNAL_TEMPERATURE for ESP8266 --- src/src/CustomBuild/define_plugin_sets.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/src/CustomBuild/define_plugin_sets.h b/src/src/CustomBuild/define_plugin_sets.h index 8f25e5f2b1..98897d01d9 100644 --- a/src/src/CustomBuild/define_plugin_sets.h +++ b/src/src/CustomBuild/define_plugin_sets.h @@ -2982,6 +2982,10 @@ To create/register a plugin, you have to : #define FEATURE_INTERNAL_TEMPERATURE 0 // Not evailable on ESP8266 #endif #endif +#if defined(FEATURE_INTERNAL_TEMPERATURE) && defined(ESP8266) + #undef FEATURE_INTERNAL_TEMPERATURE + #define FEATURE_INTERNAL_TEMPERATURE 0 // Not evailable on ESP8266 +#endif #ifndef FEATURE_I2C_DEVICE_CHECK #ifdef ESP8266_1M From 1eb7a0d35aad24eafdc0ac4a2b5b47da0f5c607b Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Mon, 25 Sep 2023 23:31:39 +0200 Subject: [PATCH 11/12] [P026][Sysvars] Add delay() call --- src/src/Helpers/Hardware.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/src/Helpers/Hardware.cpp b/src/src/Helpers/Hardware.cpp index 97223a2079..7321c9c062 100644 --- a/src/src/Helpers/Hardware.cpp +++ b/src/src/Helpers/Hardware.cpp @@ -628,6 +628,7 @@ float getInternalTemperature() { #if defined(ESP32_CLASSIC) uint8_t raw = 128u; while ((128u == raw) && (0 != retries)) { + delay(0); raw = temprature_sens_read(); // Each reading takes about 112 microseconds --retries; } From 01c673ea13881cba06a7caf44e71a90cd53696f0 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Tue, 26 Sep 2023 19:44:59 +0200 Subject: [PATCH 12/12] [Build][P026] Update documentation (without Actions run...) --- docs/source/Plugin/P026.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/Plugin/P026.rst b/docs/source/Plugin/P026.rst index dcb0964d17..ec0e8b0117 100644 --- a/docs/source/Plugin/P026.rst +++ b/docs/source/Plugin/P026.rst @@ -94,6 +94,8 @@ Change log .. versionchanged:: 2.0 ... + |added| 2023-09-25 ESP32 Internal temperature sensor option, Get Config values + |added| Major overhaul for 2.0 release.