From fd5298b6915f86425140fec8d1f6c2c09ff0d7b1 Mon Sep 17 00:00:00 2001 From: RnD1 Date: Thu, 16 Apr 2026 06:17:22 +0900 Subject: [PATCH] OPtimization on cores, netc, setup --- .gitignore | Bin 438 -> 197 bytes HermitCrab.h | 1 + HCesp.ino => HermitCrab.ino | 4 +- NTC_10K.cpp | 89 +++++++++++++++------------ NTC_10K.h | 2 + OTA.cpp | 20 +++--- Setup.cpp | 51 ++-------------- Task0.ino | 118 ++++++++++++++++-------------------- 8 files changed, 123 insertions(+), 162 deletions(-) rename HCesp.ino => HermitCrab.ino (99%) diff --git a/.gitignore b/.gitignore index 35bfb1a08db022ffb9143e1c00540b150857ff99..1aab51ba75dff187c3affe508d26f916d577374e 100644 GIT binary patch literal 197 zcmZXOF%H5o3`KXJB2pKq)Z`3^GBB`!#GW*UT10haCk1X#D#66^zGUhB@5byT7Mj=` z`vZhRDLP0L#0#N1XzhrvN=&!PKodY?uB62$bIBzVn>|MayXa8UfgMRR%X?MVOZQ}X u=LvxjQ&xLa%k8wM9{C_*pBLfbaoTXFlHm literal 438 zcma)2%MOA-5bN2*e<1OqCcrls@!-LWCf<3hN+e=fK>c~OGb{ve9@uO<-L}l*UcEZTHZR1?5j~+4I7Ku+YYFuhrt(t Cw?Z)h diff --git a/HermitCrab.h b/HermitCrab.h index 691e510..28c10e7 100644 --- a/HermitCrab.h +++ b/HermitCrab.h @@ -20,6 +20,7 @@ #ifndef DEBUG #define DEBUG 1 // Set to 0 to disable debug output #endif +#undef DEBUG //#define BLE_DEBUG diff --git a/HCesp.ino b/HermitCrab.ino similarity index 99% rename from HCesp.ino rename to HermitCrab.ino index a9f9d6a..2ee9b75 100644 --- a/HCesp.ino +++ b/HermitCrab.ino @@ -53,10 +53,10 @@ MY_IRAM_ATTR void loop() { // Un-Conditional Loop { //ESP_LOGI(TAG_MAIN,"Checking WiFi2"); - checkWiFi(tickMillis); + //checkWiFi(tickMillis); //ESP_LOGI(TAG_MAIN,"Host Loop"); - host.Loop(tickMillis); + //host.Loop(tickMillis); // UI Button Check ui.loopButton(tickMillis); diff --git a/NTC_10K.cpp b/NTC_10K.cpp index 85e14d7..a4b6fdd 100644 --- a/NTC_10K.cpp +++ b/NTC_10K.cpp @@ -61,67 +61,76 @@ const int16_t temp_C[] = { 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150 }; - + NTC_10K ntc; void NTC_10K::setup(bool bNegativePolarity) { m_bNegativePolarity = bNegativePolarity; _vRef = 3.3f; _RESO = 4095; - for (int i = 0; i < 16; i++) temps[i] = 0; - temp_idx = 0; - temp_sum = 0; + m_nTemp = -9999; + m_fTemp = -9999.0; + m_fLastTemp = 0.0f; pinMode(PIN_NTC, INPUT); // Set PIN_NTC as input analogReadResolution(12); // Set ADC resolution to 12 bits (0-4095) analogSetAttenuation(ADC_11db); // Set attenuation for full-scale 3.3V } +/** + * @brief Reads NTC sensor, calculates temperature via interpolation, + * and applies an Exponential Moving Average (EMA) filter. + * * History: + * - 2026-04-16: Refactored from Simple Moving Average (SMA) to EMA with float buffer. + * - 2026-04-16: Optimized interpolation to reduce CPU cycles. + * - 2026-04-16: Implemented aggressive alpha (0.01) to mitigate 5°C PWM noise. + * - 2026-04-16: Upgraded lastTemp to float (m_fLastTemp) for total precision. + */ void NTC_10K::readSensor() { float Vin; - int16_t temp; - static int16_t lastTemp = 0; + float currentInstantTemp; // High-precision intermediate - int adcValue = analogRead(PIN_NTC); // Read ADC value from PIN_NTC + // 1. Hardware Acquisition + int adcValue = constrain(analogRead(PIN_NTC), 1, 4094); - // Calculate the input voltage from the ADC reading + // 2. Voltage and Resistance Calculation Vin = (float)adcValue * _vRef / _RESO; + + float r; + if (m_bNegativePolarity) { + r = (Vin / (_vRef - Vin)) * rRef; + } else { + r = ((_vRef - Vin) / Vin) * rRef; + } - // Calculate the resistance of the thermistor - // Calculate the resistance of the thermistor (adjusted for inverted ADC behavior) - - float r; - if (m_bNegativePolarity) { - // NTC is connected to Negative - r = (Vin / (_vRef - Vin)) * rRef; - } else { - // NTC is connected to Positive - r = ((_vRef - Vin) / Vin) * rRef; - } - - // Find the index of the resistance in the table where r is between resistance[i-1] and resistance[i] + // 3. Table Lookup int i = 0; - while (i < sizeof(resistance) / sizeof(resistance[0]) - 1 && resistance[i] > r) { + int tableSize = sizeof(resistance) / sizeof(resistance[0]); + while (i < tableSize - 1 && resistance[i] > r) { i++; } - // If r is out of range, return the closest extreme temperature - if (i == 0 || i == sizeof(resistance) / sizeof(resistance[0]) - 1) { - if (lastTemp != 0) temp = lastTemp; - else temp = 0; + // 4. Interpolation Logic (Precise Float Math) + if (i == 0 || i == tableSize - 1) { + // Use last known good float value if out of bounds + currentInstantTemp = (m_fLastTemp != 0.0f) ? m_fLastTemp : 0.0f; + } + else { + // Faster Slope Calculation: y = y0 + m * (r - r0) + float m = (temp_C[i] - temp_C[i - 1]) / (resistance[i] - resistance[i - 1]); + currentInstantTemp = temp_C[i - 1] + m * (r - resistance[i - 1]); } - else { - // Interpolate between resistance[i-1] and resistance[i] - float m = (temp_C[i] - temp_C[i - 1]) / (resistance[i] - resistance[i - 1]); // Slope - float b = temp_C[i - 1] - (m * resistance[i - 1]); // Intercept - temp = (int16_t) roundf((m * r + b) * 10.0f); - } - // Return the temperature as an integer scaled by 10 (e.g., 25.3°C => 253) - temp_sum -= temps[temp_idx]; - temps[temp_idx++] = temp; - temp_idx &= NTC_MASK; - temp_sum += temp; - lastTemp = temp; - m_nTemp = temp_sum / NTC_COUNT; -} + // 5. Exponential Moving Average (EMA) Filtering + if (m_fTemp < -5000.0f) { + m_fTemp = currentInstantTemp; + } else { + // 0.01f Alpha: The 5°C PWM noise now only moves the buffer by 0.05°C per hit. + const float alpha = 0.05f; + m_fTemp = (currentInstantTemp * alpha) + (m_fTemp * (1.0f - alpha)); + } + + // 6. Update Outputs + m_fLastTemp = currentInstantTemp; // Store precise float for next loop + m_nTemp = (int16_t)roundf(m_fTemp * 10.0f); // Final integer output (e.g., 25.34 -> 253) +} \ No newline at end of file diff --git a/NTC_10K.h b/NTC_10K.h index 2aefd5b..0ac3404 100644 --- a/NTC_10K.h +++ b/NTC_10K.h @@ -21,6 +21,8 @@ private: int _RESO; bool m_bNegativePolarity; int16_t m_nTemp; + float m_fTemp; + float m_fLastTemp; public: void setup(bool bNegativePolarity); diff --git a/OTA.cpp b/OTA.cpp index 4ad6ff4..646ec6d 100644 --- a/OTA.cpp +++ b/OTA.cpp @@ -17,10 +17,10 @@ // OTA // // ============================================================== -const char *HC__VERSION = "20260413001"; +const char *HC__VERSION = "20250415001"; #define UPDATE_PORT ((uint16_t) 443) -String url = "visionsoft.kr"; -String uri = "/hc/hc_firmware_update.php"; +const char *url = "visionsoft.kr"; +const char *uri = "/sc/pages/firmware_download.php"; const char *HTTPUPDATE_USERAGRENT = "ESP32-http-Update"; const char *COMPANY_NAME = "VisionSoft"; const char *SERVICE_NAME = "HermitCrab"; @@ -78,13 +78,13 @@ bool checkOTA(bool bForceUpdate) // result: POSITIVE (HTTP/Status), NEGATIVE (Network Error) int result = ESPUpdate.update( client, - "visionsoft.kr", // Server Host - 443, // Server Port HTTPS, - "/sc/pages/firmware_download.php", // phpUri, - HC__VERSION, // Current Version string - "HCesp", // Project Tag - bForceUpdate, // bForceUpdate - true // bRebootAfterInstall + url, // Server Host + 443, // Server Port HTTPS, + uri, // phpUri, + HC__VERSION, // Current Version string + SERVICE_NAME, // Project Tag + bForceUpdate, // bForceUpdate + true // bRebootAfterInstall ); // ====================================================================== diff --git a/Setup.cpp b/Setup.cpp index ea4f8c4..ecd8e26 100644 --- a/Setup.cpp +++ b/Setup.cpp @@ -56,24 +56,15 @@ void setup() { g_nSecond = 0; bShowSensor = false; - - DPRINTLN("1"); + setupConfig(); - DPRINTLN("2"); setupStatus(); - DPRINTLN("3"); setupPins(); - DPRINTLN("4"); scanI2C(); - DPRINTLN("5"); setupSensor(); - DPRINTLN("6"); ui.setup(); - DPRINTLN("7"); ui.message(0, (char *) "WiFi..."); - DPRINTLN("8"); setupWiFi(); - DPRINTLN("9"); if (aht25.sensor() || aht10_0x39.sensor()) { ui.message(4, (char *) "Sensor... OK!"); @@ -97,7 +88,7 @@ void setup() { xTaskCreatePinnedToCore( core0Task, // Function to run as a task "Task0", // Task name - 10240, // Stack size in words + 20480, // Stack size in words NULL, // Task input parameter 1, // Priority of the task &TaskHandle_0, // Task handle @@ -126,7 +117,7 @@ void setupWiFi() { // Connect WiFi for OTA if (config.ssid[0] && config.pw[0]) { #if defined(ESP32) - esp_wifi_set_max_tx_power(84); + esp_wifi_set_max_tx_power(74); #elif defined(ESP8266) WiFi.setOutputPower(20.5f); pinMode(16,OUTPUT); @@ -198,8 +189,6 @@ void setupPostWiFi(bool bBoot = false) { } } -#include "driver/ledc.h" - void setupPins() { // --- Basic Digital Pin Initialization --- pinMode(PIN_HEATER1, OUTPUT); @@ -219,39 +208,11 @@ void setupPins() { ledcAttachChannel(PIN_LED_HEATER2, PWM_1KHZ_FREQ, PWM_RESOLUTION, PWM_HEATER2_CHANNEL); // --- 3. Low Speed Group: Mist & WiFi LED (1.19Hz) --- - // Initialized at 32Hz to bypass the slow divider calculation/WDT panic. + // Initialized at 1Hz to bypass the slow divider calculation/WDT panic. + // Must be ESP32 coer version 3.0.2 in ordre to set 1Hz ledcAttachChannel(PIN_MIST, PWM_1HZ_FREQ, PWM_RESOLUTION, PWM_MIST_CHANNEL); ledcAttachChannel(PIN_LED_WIFI, PWM_1HZ_FREQ, PWM_RESOLUTION, PWM_WIFI_LED_CHANNEL); - // MANUALLY RECONFIGURE TIMER FOR 1.19Hz - // Source: LEDC_REF_TICK (1MHz) - // Divider: 819 (Integer part) - // Result: 1,000,000 / (819 * 1024) ≈ 1.192 Hz - // Note: On Core 2.0.17, LEDC_USE_REF_TICK is the correct constant. - /* - ledc_timer_set( - LEDC_LOW_SPEED_MODE, - LEDC_TIMER_0, - (uint32_t)(819 << 8), // 18.8 bit register: 819 integer, 0 fractional - (uint32_t)PWM_RESOLUTION, - LEDC_REF_TICK - ); - */ - /* - ledc_timer_config_t mist_timer_conf = { - .speed_mode = LEDC_LOW_SPEED_MODE, - .duty_resolution = LEDC_TIMER_8_BIT, - .timer_num = LEDC_TIMER_0, - .freq_hz = 2, // The driver will target 1Hz - .clk_cfg = LEDC_USE_REF_TICK, // Forces the 1MHz source - .deconfigure = false - }; - esp_err_t err = ledc_timer_config(&mist_timer_conf); - if (err == ESP_OK) { - // Apply the change and reset the counter - ledc_timer_rst(LEDC_LOW_SPEED_MODE, LEDC_TIMER_0); - } - */ // --- Initial State Writes --- ledcWrite(PIN_MOTOR, PWM_OFF); ledcWrite(PIN_FAN, PWM_OFF); @@ -320,7 +281,7 @@ void setupSensor() { if (aht25.setup()) { delay(82); aht25.readSensor(millis()); - DPRINTF("AHTx0 initialized successfully at 0x38. Temp: %.2f, Humid: %.2f%%\n", + DPRINTF("AHT25 initialized successfully at 0x38. Temp: %.2f, Humid: %.2f%%\n", aht25.getTemperature() / 100.0f, aht25.getHumidity() / 100.0f); } diff --git a/Task0.ino b/Task0.ino index ea97810..49b7903 100644 --- a/Task0.ino +++ b/Task0.ino @@ -27,97 +27,85 @@ MY_IRAM_ATTR void core0Task(void *pvParameters) { wl_status_t lastWiFiStatus = WL_DISCONNECTED; unsigned long tickMillis = millis(); unsigned long tickSecond; - unsigned long lastTick = tickMillis / 1000; - unsigned long lastTickMillis = tickMillis; - unsigned long lastSensorUpdate1 = tickMillis; - unsigned long lastSensorUpdate2 = tickMillis + 2500; - uint16_t tick1000, lastTick1000 = tickMillis % 1000;; - uint16_t tick250, lastTick250 = tickMillis % 250; uint8_t slot; - uint8_t lastSlot = tickMillis / 50; + uint8_t lastSlot = 255; esp_task_wdt_add(NULL); // NULL for the current task ui.start(); - ble.setupScan(); while (true) { esp_task_wdt_reset(); tickMillis = millis(); - tick250 = tickMillis % 250; - tick1000 = tickMillis % 1000; tickSecond = tickMillis / 1000; - slot = tick1000 / 50; + slot = (tickMillis % 1000) / 50; //=============================================================================== - // Loop top - // Once in a second loop - if (tick1000 != lastTick1000) { - if (slot != lastSlot) { - switch (slot) { - case 1: - case 6: - case 11: - case 16: // UI Display - ui.updateDisplayTop(tickSecond); - break; - case 2: - case 7: - case 12: - case 17: // NTC Temp Sensor - ntc.readSensor(); - break; + // Loop top: Once in a second loop + if (slot != lastSlot) { + lastSlot = slot; + + switch (slot) { + case 1: + case 6: + case 11: + case 16: // UI Display + ui.updateDisplayTop(tickSecond); + break; + case 2: + case 4: + case 7: + case 9: + case 12: + case 14: + case 17: // NTC Temp Sensor + case 19: + ble.loop(tickMillis); + break; + case 3: // NTP - Time - if (isWiFiConnected()) { - if (timeManager.getTime(tickMillis)) { - ESP_LOGI(TAG_TASK0,"NTP time loaded: %s", printTime()); - } + if (isWiFiConnected()) { + if (timeManager.getTime(tickMillis)) { + ESP_LOGI(TAG_TASK0,"NTP time loaded: %s", printTime()); } - break; - case 4: - case 9: - case 14: - case 19: - ntc.readSensor(); - break; + } + break; + case 5: // Heartbeat - if (isWiFiConnected()) { - host.SendHeartBeat(tickMillis); - } - break; + if (isWiFiConnected()) { + host.SendHeartBeat(tickMillis); + } + break; - case 8: // BLE - ble.loop(tickMillis); - break; - - case 13: // ATH2x - 0x38 - aht25.readSensor(tickMillis); - break; + case 8: // NTC + ntc.readSensor(); + break; + + case 13: // ATH2x - 0x38 + aht25.readSensor(tickMillis); + break; - case 15: // ATH0x - 0x39 - aht10_0x39.readSensor(tickMillis); - break; + case 15: // ATH0x - 0x39 + aht10_0x39.readSensor(tickMillis); + break; - case 18: // UI Bottom - ui.updateDisplayBottom(tickSecond); - break; - default: // 0 10 - break; - } - lastSlot = slot; + case 18: // UI Bottom + ui.updateDisplayBottom(tickSecond); + break; + default: // 0 10 + break; } - - lastTick1000 = tick1000; - lastTick250 = tick250; - } // end of - if (tick1000 != lastTick1000) + } // ===================================================== // Unconditional Loop + checkWiFi(tickMillis); + host.Loop(tickMillis); host.MonitorUDP(); // Loop end //========================================================================== - lastTickMillis = tickMillis; + esp_task_wdt_reset(); } // end of - While(True)