From 1ae48056c6675a26b54548227fb4c414905df556 Mon Sep 17 00:00:00 2001 From: Vid Tadel Date: Fri, 21 Nov 2025 18:13:31 +0100 Subject: [PATCH 01/15] Squash merge Sofronio_temperatureDrift_fix into develop --- include/parameter.h | 27 +++- src/hds.ino | 355 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 379 insertions(+), 3 deletions(-) diff --git a/include/parameter.h b/include/parameter.h index ec0f9d3..b0a72e0 100644 --- a/include/parameter.h +++ b/include/parameter.h @@ -91,7 +91,32 @@ bool b_autoSleep = true; //电子秤参数和计时点 -bool b_weight_in_serial = false; +// Enhanced tracking system global variables +static float f_tracking_offset = 0.0; // Current tracking offset +static float f_tracking_target = 0.0; // Current tracking target weight +static unsigned long t_last_tracking_update = 0; // Last tracking update time +static const unsigned long TRACKING_UPDATE_INTERVAL = 5000; // Tracking update interval 5 seconds +static const float TRACKING_THRESHOLD = 0.1; // Tracking stability threshold +static const int i_STABLE_COUNT_THRESHOLD = 5; // Stable count threshold +static const float MAX_TRACKING_ADJUSTMENT = 0.5; // Maximum single adjustment + +static unsigned long t_last_status_display = 0; +static const unsigned long STATUS_DISPLAY_INTERVAL = 5000; +static bool b_weight_in_serial = true; + +static int i_stable_count = 0; // Stable state counter +static bool b_tracking_enabled = true; // Tracking enable flag +static bool b_tracking_active = false; // Whether tracking is currently active + +// Stable output system global variables +static float f_previous_stable_value = 0.0; // Previous stable output value +static float f_current_raw_value = 0.0; // Current raw input value +static float STABLE_OUTPUT_THRESHOLD = 0.1; // Minimum change to update output +static bool b_stable_output_enabled = true; // Stable output enable flag +static unsigned long t_last_stable_change = 0; // Time of last stable change + + + bool b_negativeWeight = false; bool b_weight_quick_zero = false; //Tare后快速显示为0优化 diff --git a/src/hds.ino b/src/hds.ino index 7eb5b0b..bba344e 100644 --- a/src/hds.ino +++ b/src/hds.ino @@ -493,7 +493,7 @@ void setup() { //adc init unsigned long stabilizingtime = 500; //taring duration. longer for better reading. - boolean _tare = true; //电子秤初始化去皮,如果不想去皮则设为false + bool _tare = true; //电子秤初始化去皮,如果不想去皮则设为false //whether the scale will tare on start. scale.begin(); scale.setSamplesInUse(4); //设置灵敏度 @@ -699,6 +699,356 @@ void setup() { b_bootTare = true; } +/** + * Enhanced adaptive tracking system + * Tracks both zero and stable weights to prevent oscillation + */ +void updateAdaptiveTracking(float current_weight) { + unsigned long current_time = millis(); + + if (!b_tracking_enabled) { + return; + } + + // Calculate weight difference from current tracking target + float weight_diff = current_weight - f_tracking_target; + + // Check if weight is stable (within tracking threshold) + if (fabs(weight_diff) <= TRACKING_THRESHOLD) { + i_stable_count++; + + // Update tracking target to slowly follow stable weights + if (i_stable_count >= 3) { // Start adjusting target after 3 stable readings + float adjustment = weight_diff * 0.1; // Slow adaptation + + // Limit maximum adjustment to prevent large jumps + if (fabs(adjustment) > MAX_TRACKING_ADJUSTMENT) { + adjustment = (adjustment > 0) ? MAX_TRACKING_ADJUSTMENT : -MAX_TRACKING_ADJUSTMENT; + } + + f_tracking_target += adjustment; + } + + } else { + // Weight changed significantly - likely a real weight change + i_stable_count = 0; + b_tracking_active = false; + + // If weight change is large and persistent, update tracking target + if (fabs(weight_diff) > TRACKING_THRESHOLD * 2) { + // Consider this as a new stable weight after verification + if (verifyWeightStability(current_weight)) { + f_tracking_target = current_weight; + b_tracking_active = true; + if (b_weight_in_serial) { + Serial.print("New weight target set: "); + Serial.println(f_tracking_target, 4); + } + } + } + } + + // Perform tracking adjustment when conditions are met + if (i_stable_count >= i_STABLE_COUNT_THRESHOLD) { + if (current_time - t_last_tracking_update >= TRACKING_UPDATE_INTERVAL) { + performTrackingAdjustment(current_weight); + } + } +} + +/** + * Perform the actual tracking adjustment + */ +void performTrackingAdjustment(float current_weight) { + float old_offset = f_tracking_offset; + + // Calculate new offset based on current weight and target + float calculated_offset = current_weight - f_tracking_target; + + // Apply slow adaptation to prevent sudden changes + f_tracking_offset = f_tracking_offset * 0.8 + calculated_offset * 0.2; + + // Activate tracking if not already active + if (!b_tracking_active) { + b_tracking_active = true; + } + + // Debug output + if (b_weight_in_serial) { + Serial.print("Tracking adjustment: Offset "); + Serial.print(old_offset, 4); + Serial.print("g -> "); + Serial.print(f_tracking_offset, 4); + Serial.print("g | Target: "); + Serial.print(f_tracking_target, 4); + Serial.print("g | Raw: "); + Serial.print(current_weight, 4); + Serial.println("g"); + } + + // Reset counters + i_stable_count = i_STABLE_COUNT_THRESHOLD - 2; // Keep near threshold for continuous tracking + t_last_tracking_update = millis(); +} + +/** + * Verify if a weight is stable enough to be considered a new target + */ +bool verifyWeightStability(float current_weight) { + static float last_verified_weight = 0.0; + static int verification_count = 0; + + if (fabs(current_weight - last_verified_weight) <= TRACKING_THRESHOLD) { + verification_count++; + } else { + verification_count = 0; + } + + last_verified_weight = current_weight; + + // Require 3 consecutive stable readings to verify new weight + return (verification_count >= 3); +} + +/** + * Apply tracking compensation to raw weight + */ +float applyTrackingCompensation(float raw_weight) { + if (b_tracking_active && b_tracking_enabled) { + return raw_weight - f_tracking_offset; + } + return raw_weight; +} + +/** + * Apply stable output filtering + * Returns the same value if change is below threshold + */ +float applyStableOutput(float current_value) { + if (!b_stable_output_enabled) { + return current_value; // Bypass stable filtering if disabled + } + + float change = fabs(current_value - f_previous_stable_value); + + // If change is significant, update the stable value + if (change >= STABLE_OUTPUT_THRESHOLD) { + f_previous_stable_value = current_value; + t_last_stable_change = millis(); + + // Debug output for significant changes + if (b_weight_in_serial) { + Serial.print("Output updated: "); + Serial.print(current_value, 4); + Serial.print("g (Change: "); + Serial.print(change, 4); + Serial.println("g)"); + } + } + + // Always return the stable value (may be same as previous) + return f_previous_stable_value; +} + +/** + * Enhanced pureScale function with all features + */ +void pureScale() { + static bool b_newDataReady = 0; + + if (scale.update()) b_newDataReady = true; + + if (b_newDataReady) { + float raw_weight = scale.getData(); + f_current_raw_value = raw_weight; // Store for status display + + // Apply adaptive tracking compensation + float compensated_weight = applyTrackingCompensation(raw_weight); + + // Apply stable output filtering + float stable_weight = applyStableOutput(compensated_weight); + + // Dead zone processing (apply to stable weight) + if (stable_weight >= -0.14 && stable_weight <= 0.14) { + f_displayedValue = 0.0; + } else { + f_displayedValue = stable_weight; + } + + f_weight_before_input = f_displayedValue; + + // Update adaptive tracking (use compensated weight, not stable weight) + updateAdaptiveTracking(compensated_weight); + + // Convert and display + dtostrf(f_displayedValue, 7, i_decimal_precision, c_weight); + if (b_weight_in_serial == true) { + //Serial.println(trim(c_weight)); + + // Display status periodically + unsigned long current_time = millis(); + if (current_time - t_last_status_display >= STATUS_DISPLAY_INTERVAL) { + displayEnhancedStatus(raw_weight, compensated_weight, stable_weight); + t_last_status_display = current_time; + } + } + b_newDataReady = false; + } + + // Handle tare operation + if (scale.getTareStatus()) { + t_tareStatus = millis(); + b_weight_quick_zero = false; + resetTracking(); + resetStableOutput(); // Also reset stable output + } + + // Quick zero handling + if (b_weight_quick_zero || b_bootTare) { + f_displayedValue = 0.0; + resetTracking(); + resetStableOutput(); // Also reset stable output + } +} + +/** + * Reset tracking system (for tare/zero operations) + */ +void resetTracking() { + f_tracking_offset = 0.0; + f_tracking_target = 0.0; + i_stable_count = 0; + b_tracking_active = false; + t_last_tracking_update = millis(); + if (b_weight_in_serial) { + Serial.println("Tracking system reset"); + } +} + +/** + * Reset stable output system + */ +void resetStableOutput() { + f_previous_stable_value = 0.0; + t_last_stable_change = millis(); + if (b_weight_in_serial) { + Serial.println("Stable output reset"); + } +} + +/** + * Enable/disable stable output + */ +void setStableOutputEnabled(bool enabled) { + b_stable_output_enabled = enabled; + if (!enabled) { + resetStableOutput(); + } + Serial.print("Stable output "); + Serial.println(enabled ? "enabled" : "disabled"); +} + +/** + * Set stable output threshold + */ +void setStableOutputThreshold(float threshold) { + STABLE_OUTPUT_THRESHOLD = threshold; + Serial.print("Stable threshold set to: "); + Serial.println(threshold, 4); +} + +/** + * Enable/disable tracking system + */ +void setTrackingEnabled(bool enabled) { + b_tracking_enabled = enabled; + if (!enabled) { + resetTracking(); + } + Serial.print("Tracking system "); + Serial.println(enabled ? "enabled" : "disabled"); +} + +/** + * Enhanced status display with all system info + */ +void displayEnhancedStatus(float raw_weight, float compensated_weight, float stable_weight) { + Serial.println("=== Enhanced Scale Status ==="); + Serial.print("Raw Input: "); + Serial.print(raw_weight, 4); + Serial.print("g | Compensated: "); + Serial.print(compensated_weight, 4); + Serial.print("g | Stable Output: "); + Serial.print(stable_weight, 4); + Serial.println("g"); + + Serial.print("Stable Output: "); + Serial.print(b_stable_output_enabled ? "ON" : "OFF"); + Serial.print(" | Threshold: ±"); + Serial.print(STABLE_OUTPUT_THRESHOLD, 4); + Serial.println("g"); + + Serial.print("Last Stable Change: "); + Serial.print((millis() - t_last_stable_change) / 1000); + Serial.println("s ago"); + + // Tracking status + Serial.print("Tracking System: "); + Serial.print(b_tracking_enabled ? "ON" : "OFF"); + Serial.print(" | Active: "); + Serial.println(b_tracking_active ? "YES" : "NO"); + + Serial.print("Tracking Offset: "); + Serial.print(f_tracking_offset, 4); + Serial.print("g | Target: "); + Serial.print(f_tracking_target, 4); + Serial.println("g"); + + Serial.print("Stable Count: "); + Serial.print(i_stable_count); + Serial.print("/"); + Serial.println(i_STABLE_COUNT_THRESHOLD); + + Serial.println("============================="); +} + +/** + * Get current tracking offset + */ +float getTrackingOffset() { + return f_tracking_offset; +} + +/** + * Get current stable output value + */ +float getStableOutputValue() { + return f_previous_stable_value; +} + +// Optional: Manual control functions +/** + * Manual override - set specific tracking offset + */ +void setManualTrackingOffset(float offset) { + f_tracking_offset = offset; + b_tracking_active = true; + Serial.print("Manual tracking offset set: "); + Serial.println(offset, 4); +} + +/** + * Manual override - set specific stable value + */ +void setManualStableValue(float value) { + f_previous_stable_value = value; + t_last_stable_change = millis(); + Serial.print("Manual stable value set: "); + Serial.println(value, 4); +} + + +/* void pureScale() { static boolean newDataReady = 0; static boolean scaleStable = 0; @@ -764,6 +1114,7 @@ void pureScale() { ratio_temp = 0.0; dtostrf(ratio_temp, 7, i_decimal_precision, c_brew_ratio); } +*/ void serialCommand() { if (Serial.available()) { @@ -1417,4 +1768,4 @@ void drawTare() { // u8g2.drawStr(AC((char *)"TARE"), 60, (char *)"TARE"); u8g2.drawBox(30, 62, 128 - 30 * 2, 2); } -} \ No newline at end of file +} From ed3281cbe62d83295fd3086bb8556793f0bd909f Mon Sep 17 00:00:00 2001 From: Vid Tadel Date: Fri, 21 Nov 2025 09:13:24 +0100 Subject: [PATCH 02/15] wip --- src/hds.ino | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/hds.ino b/src/hds.ino index bba344e..aa56e8c 100644 --- a/src/hds.ino +++ b/src/hds.ino @@ -306,7 +306,7 @@ void button_init() { config1.setLongPressDelay(LONGCLICK); } -void wifi_init() { +void _wifi_init(void *args) { if (!readBoolEEPROMWithValidation(i_addr_enableWifiOnBoot, false)) { return; } @@ -342,8 +342,11 @@ void wifi_init() { } } }); + vTaskDelete(NULL); +} +void wifi_init() { + xTaskCreate(_wifi_init, "Wifi Init Task", configMINIMAL_STACK_SIZE + 2048, NULL, 0, NULL); } - void setup() { Serial.begin(115200); From 68a26856b0e36206f06f2be625c294b5dc034d3e Mon Sep 17 00:00:00 2001 From: Vid Tadel Date: Fri, 21 Nov 2025 18:35:19 +0100 Subject: [PATCH 03/15] init wifi if ble also enabled --- src/hds.ino | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hds.ino b/src/hds.ino index aa56e8c..21fd917 100644 --- a/src/hds.ino +++ b/src/hds.ino @@ -599,7 +599,9 @@ void setup() { //calibration value is not valid, go to calibration procedure. } #endif - wifi_init(); + if (b_ble_enabled) { + wifi_init(); + } // //wifiota // #ifdef WIFI if (digitalRead(BUTTON_CIRCLE) == LOW && digitalRead(BUTTON_SQUARE) == LOW) { From b352a13bfd888dc9969ae2d3fa2299e651ae9c9e Mon Sep 17 00:00:00 2001 From: Vid Tadel Date: Sat, 22 Nov 2025 22:09:30 +0100 Subject: [PATCH 04/15] include date and commit hash in about --- git_rev_macro.py | 9 +++++++++ include/config.h | 6 +++--- include/menu.h | 14 ++++++-------- platformio.ini | 1 + src/hds.ino | 6 ++++-- 5 files changed, 23 insertions(+), 13 deletions(-) create mode 100644 git_rev_macro.py diff --git a/git_rev_macro.py b/git_rev_macro.py new file mode 100644 index 0000000..d357f82 --- /dev/null +++ b/git_rev_macro.py @@ -0,0 +1,9 @@ +import subprocess + +revision = ( + subprocess.check_output(["git", "rev-parse", "HEAD"]) + .strip() + .decode("utf-8") + +) +print("'-DGIT_REV=\"%s\"'" % revision[:6]) diff --git a/include/config.h b/include/config.h index 8fb3ce0..a1bd453 100644 --- a/include/config.h +++ b/include/config.h @@ -26,9 +26,9 @@ //#define CHECKBATTERY //SCALE CONFIG -#define LINE1 (char*)"FW: 3.0.1" -#define LINE2 (char*)"Built-date(YYYYMMDD): 20251009" -#define LINE3 (char*)"S/N: HDS001" //Serial number +#define LINE1 (char*)"FW: 3.0.2" +#define LINE2 (char*)"Built-date " +#define LINE3 __DATE__ //Serial number #define VERSION /*version*/ LINE1, /*compile date*/ LINE2, /*sn*/ LINE3 //About info #define FIRMWARE_VER LINE1 diff --git a/include/menu.h b/include/menu.h index b6a6c42..1827cdf 100644 --- a/include/menu.h +++ b/include/menu.h @@ -908,17 +908,15 @@ void wifiUpdate() { void showAbout() { actionMessage = FIRMWARE_VER; - // actionMessage2 = PCB_VER; + actionMessage2 = LINE3; b_showAbout = true; - u8g2.setFont(FONT_M); + u8g2.setFont(FONT_S); u8g2.firstPage(); do { - if (AC(actionMessage.c_str()) < 0) - u8g2.setFont(FONT_S); - // u8g2.drawStr(AC(actionMessage.c_str()), AM() - 12, - // actionMessage.c_str()); u8g2.drawStr(AC(actionMessage2.c_str()), AM() + - // 12, actionMessage2.c_str()); - u8g2.drawStr(AC(actionMessage.c_str()), AM(), actionMessage.c_str()); + u8g2.setFont(FONT_S); + u8g2.drawStr(AC(actionMessage.c_str()), AM() - 24, actionMessage.c_str()); + u8g2.drawStr(AC(actionMessage2.c_str()), AM(), actionMessage2.c_str()); + u8g2.drawStr(AC(GIT_REV), AM()+ 24, GIT_REV); } while (u8g2.nextPage()); #ifdef BUZZER buzzer.off(); diff --git a/platformio.ini b/platformio.ini index ae85f39..1765c24 100644 --- a/platformio.ini +++ b/platformio.ini @@ -27,6 +27,7 @@ build_flags = ; -DESP32 -D CONFIG_ASYNC_TCP_RUNNING_CORE=1 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 + !python3 git_rev_macro.py # -D DEBUG # diff --git a/src/hds.ino b/src/hds.ino index 21fd917..efde5b1 100644 --- a/src/hds.ino +++ b/src/hds.ino @@ -637,8 +637,10 @@ void setup() { Serial.print(LINE1); Serial.print("\t"); Serial.print(LINE2); - // Serial.print("\t"); - // Serial.println(LINE3); + Serial.print("\t"); + Serial.print(LINE3); + Serial.print("\t"); + Serial.println(GIT_REV); Serial.print("\tCal_Val: "); Serial.print(f_calibration_value); Serial.print("\tHB_DET: "); From 0045435c722cbe297e0c06f34668203c4fd96674 Mon Sep 17 00:00:00 2001 From: Vid Tadel Date: Sat, 22 Nov 2025 22:09:49 +0100 Subject: [PATCH 05/15] use buffer for calibration value --- include/menu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/menu.h b/include/menu.h index 1827cdf..86736d7 100644 --- a/include/menu.h +++ b/include/menu.h @@ -401,7 +401,7 @@ void calibrate() { void calibration(int input) { if (b_calibration == true) { bool newDataReady = false; - char *c_calval = (char *)""; + char c_calval[25]; if (i_button_cal_status == 1) { if (input == 0) { scale.setSamplesInUse(16); From eaa76a3688725ecbb75499983e4bb133e94cc224 Mon Sep 17 00:00:00 2001 From: Vid Tadel Date: Sat, 22 Nov 2025 22:16:11 +0100 Subject: [PATCH 06/15] blink wifi icon when connecting --- src/wifi_setup.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/wifi_setup.cpp b/src/wifi_setup.cpp index 602c27c..0e6851a 100644 --- a/src/wifi_setup.cpp +++ b/src/wifi_setup.cpp @@ -43,6 +43,7 @@ void setupAP() { Serial.println("WiFi: DecentScale"); Serial.print("IP: "); Serial.println(WiFi.softAPIP()); + b_wifiEnabled = true; } void connectToWifi() { @@ -60,9 +61,11 @@ void connectToWifi() { wifiCounter++; delay(1000); Serial.println("."); + // Toggle, to emulate blinking? + b_wifiEnabled = !b_wifiEnabled; if (wifiCounter > 20) { WiFi.disconnect(true); - delay(100); + delay(200); setupAP(); break; } @@ -72,6 +75,7 @@ void connectToWifi() { Serial.println(WiFi.SSID().c_str()); Serial.println("IP address: "); Serial.println(WiFi.localIP().toString().c_str()); + b_wifiEnabled = true; } void stopWifi() { WiFi.disconnect(true); } From 0bc35a2b3254bade113e9c0d0d5d75972fd7fcf5 Mon Sep 17 00:00:00 2001 From: Vid Tadel Date: Tue, 25 Nov 2025 11:49:41 +0100 Subject: [PATCH 07/15] fix crash when wifi is disabled in eeprom --- src/hds.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hds.ino b/src/hds.ino index efde5b1..4a3c475 100644 --- a/src/hds.ino +++ b/src/hds.ino @@ -307,9 +307,6 @@ void button_init() { } void _wifi_init(void *args) { - if (!readBoolEEPROMWithValidation(i_addr_enableWifiOnBoot, false)) { - return; - } b_wifiEnabled = true; setupWifi(); startWebServer(); @@ -345,6 +342,9 @@ void _wifi_init(void *args) { vTaskDelete(NULL); } void wifi_init() { + if (!readBoolEEPROMWithValidation(i_addr_enableWifiOnBoot, false)) { + return; + } xTaskCreate(_wifi_init, "Wifi Init Task", configMINIMAL_STACK_SIZE + 2048, NULL, 0, NULL); } From 191107833b2d18c8f047f4e478be571becf892d0 Mon Sep 17 00:00:00 2001 From: Sofronio Date: Tue, 25 Nov 2025 15:39:13 +0800 Subject: [PATCH 08/15] no battery update fix There should be a millis() given to t_batteryRefresh for it to update the battery level in loop(). Another if (t_batteryRefresh > 0){ was added to ensure the power off low battery was only called once the updateBattery() was called first. --- include/power.h | 24 +++++++++++++----------- src/hds.ino | 3 ++- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/include/power.h b/include/power.h index be4577a..9d0b583 100644 --- a/include/power.h +++ b/include/power.h @@ -200,21 +200,23 @@ void shut_down_now() { void shut_down_low_battery(float voltage) { - Serial.print("Low battery, voltage:"); - Serial.println(voltage); - refreshOLED((char*)"Low battery", FONT_M); + if (t_batteryRefresh > 0){ + Serial.print("Low battery, voltage:"); + Serial.println(voltage); + refreshOLED((char*)"Low battery", FONT_M); #ifdef ESPNOW - if (b_espnow) { - b_power_off = 1; - updateEspnow(1); - } - sendBlePowerOff(3); + if (b_espnow) { + b_power_off = 1; + updateEspnow(1); + } + sendBlePowerOff(3); #endif #ifdef BUZZER - buzzer.off(); + buzzer.off(); #endif - delay(1000); - esp32_sleep(); + delay(1000); + esp32_sleep(); + } } void shut_down_now_nobeep() { diff --git a/src/hds.ino b/src/hds.ino index 4a3c475..cffcc76 100644 --- a/src/hds.ino +++ b/src/hds.ino @@ -429,7 +429,6 @@ void setup() { ADS_init(); #endif delay(50); - updateBattery(BATTERY_PIN); if (b_ble_enabled) { ble_init(); } @@ -704,6 +703,7 @@ void setup() { Serial.println("Setup complete..."); t_bootTare = millis(); b_bootTare = true; + updateBattery(BATTERY_PIN); } /** @@ -1311,6 +1311,7 @@ void loop() { #endif //DEBUG if (millis() - t_batteryRefresh > i_batteryRefreshTareInterval){ updateBattery(BATTERY_PIN); + t_batteryRefresh = millis(); } checkBattery(); if (b_menu) { From cd77ee0a20721fc597cd687fae1106c69c002f92 Mon Sep 17 00:00:00 2001 From: Sofronio Date: Wed, 26 Nov 2025 10:45:53 +0800 Subject: [PATCH 09/15] option to quick boot Added menu option to quick boot HDS. Also changed b_ble_enabled to b_wifiOnBoot to start wifi. --- .gitignore | 1 + include/menu.h | 38 +++++++++++++++++++++++++++++++-- include/parameter.h | 5 ++++- src/hds.ino | 52 ++++++++++++++++++++++++++++----------------- 4 files changed, 74 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index 2fb6b27..f0038d0 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .vscode/c_cpp_properties.json .vscode/extensions.json .vscode/launch.json +.DS_Store diff --git a/include/menu.h b/include/menu.h index 86736d7..204af1d 100644 --- a/include/menu.h +++ b/include/menu.h @@ -56,6 +56,8 @@ void btnFuncWhileConnectedOn(); void btnFuncWhileConnectedOff(); void autoSleepOn(); void autoSleepOff(); +void quickBootOn(); +void quickBootOff(); // Top-level menu options // 1/5 define the 1st level menu @@ -74,6 +76,7 @@ Menu menuFlipScreen = { "Flip Screen", NULL, NULL, NULL }; Menu menuTimeOnTop = { "Time On Top", NULL, NULL, NULL }; Menu menuBtnFuncWhileConnected = { "Button with BLE", NULL, NULL, NULL }; Menu menuAutoSleep = { "Auto Sleep", NULL, NULL, NULL }; +Menu menuQuickBoot = { "Quick Boot", NULL, NULL, NULL }; // 2/5 define the 2st level menu #ifdef BUZZER @@ -124,7 +127,7 @@ Menu menuTimeOnTopOff = { "Weight On Top", timeOnTopOff, NULL, &menuTimeOnTop }; Menu *timeOnTopMenu[] = { &menuTimeOnTopBack, &menuTimeOnTopOn, &menuTimeOnTopOff }; -// Enable button fucntion while BLE connected +// Enable button function while BLE connected Menu menuBtnFuncWhileConnectedBack = { "Back", NULL, NULL, &menuBtnFuncWhileConnected }; Menu menuBtnFuncWhileConnectedOn = { "Enable Buttons", btnFuncWhileConnectedOn, @@ -136,11 +139,18 @@ Menu *btnFuncWhileConnectedMenu[] = { &menuBtnFuncWhileConnectedBack, &menuBtnFuncWhileConnectedOn, &menuBtnFuncWhileConnectedOff }; +// Auto sleep function Menu menuAutoSleepBack = { "Back", NULL, NULL, &menuAutoSleep }; Menu menuAutoSleepOn = { "Auto Sleep On", autoSleepOn, NULL, &menuAutoSleep }; Menu menuAutoSleepOff = { "Auto Sleep Off", autoSleepOff, NULL, &menuAutoSleep }; Menu *autoSleepMenu[] = { &menuAutoSleepBack, &menuAutoSleepOn, &menuAutoSleepOff }; +// Quick boot function(aka no delay when pressing the button to boot the scale) +Menu menuQuickBootBack = { "Back", NULL, NULL, &menuQuickBoot }; +Menu menuQuickBootOn = { "Quick Boot On", quickBootOn, NULL, &menuQuickBoot }; +Menu menuQuickBootOff = { "Quick Boot Off", quickBootOff, NULL, &menuQuickBoot }; +Menu *quickBootMenu[] = { &menuQuickBootBack, &menuQuickBootOn, &menuQuickBootOff }; + // Menu menuFactoryBack = { "Back", NULL, NULL, &menuFactory }; // Menu menuCalibrateVoltage = { "Calibrate 4.2v", calibrateVoltage, NULL, // &menuFactory }; Menu menuFactoryDebug = { "Debug Info", enableDebug, NULL, @@ -157,7 +167,7 @@ Menu *mainMenu[] = { &menuCalibration, &menuWifi, // &menuWiFiUpdate, &menuAbout, &menuLogo, &menuHeartbeat, &menuFlipScreen, &menuTimeOnTop, - &menuBtnFuncWhileConnected, &menuAutoSleep, + &menuBtnFuncWhileConnected, &menuAutoSleep, &menuQuickBoot, //, &menuFactory }; // &menuHolder1, &menuHolder2, &menuHolder3, &menuHolder4, @@ -184,6 +194,7 @@ void linkSubmenus() { menuTimeOnTop.subMenu = timeOnTopMenu[0]; menuBtnFuncWhileConnected.subMenu = btnFuncWhileConnectedMenu[0]; menuAutoSleep.subMenu = autoSleepMenu[0]; + menuQuickBoot.subMenu = quickBootMenu[0]; // menuFactory.subMenu = factoryMenu[0]; } @@ -389,6 +400,26 @@ void autoSleepOff() { Serial.println("Autosleep off stored in EEPROM."); } +void quickBootOn() { + b_quickBoot = true; + actionMessage = "Quick Boot On"; + t_actionMessage = millis(); + t_actionMessageDelay = 1000; + EEPROM.put(i_addr_quickBoot, b_quickBoot); + EEPROM.commit(); + Serial.println("Quick boot on stored in EEPROM."); +} + +void quickBootOff() { + b_quickBoot = false; + actionMessage = "Quick Boot Off"; + t_actionMessage = millis(); + t_actionMessageDelay = 1000; + EEPROM.put(i_addr_quickBoot, b_quickBoot); + EEPROM.commit(); + Serial.println("Quick boot off stored in EEPROM."); +} + void calibrate() { b_menu = false; b_calibration = true; // 让按钮进入校准状态3 @@ -1120,6 +1151,9 @@ void selectMenu() { } else if (currentSelection == &menuAutoSleep) { currentMenu = autoSleepMenu; currentMenuSize = getMenuSize(autoSleepMenu); + } else if (currentSelection == &menuQuickBoot) { + currentMenu = quickBootMenu; + currentMenuSize = getMenuSize(quickBootMenu); } // else if (currentSelection == &menuFactory) { // currentMenu = factoryMenu; diff --git a/include/parameter.h b/include/parameter.h index b0a72e0..91ff8e6 100644 --- a/include/parameter.h +++ b/include/parameter.h @@ -88,7 +88,9 @@ float f_filtered_temperature = 0; bool b_ads1115InitFail = true; //ads1115 not detected flag bool b_wifiOnBoot = false; bool b_autoSleep = true; - +bool b_quickBoot = false; +unsigned int i_buttonBootDelay = 500; +bool b_showChargingUI = false; //电子秤参数和计时点 // Enhanced tracking system global variables @@ -246,6 +248,7 @@ int i_addr_timeOnTop = i_addr_screenFlipped + sizeof(b_screenFlipped); int i_addr_btnFuncWhileConnected = i_addr_timeOnTop + sizeof(b_timeOnTop); //b_btnFuncWhileConnected int i_addr_enableWifiOnBoot = i_addr_btnFuncWhileConnected + sizeof(b_btnFuncWhileConnected); //b_wifiOnBoot int i_addr_autoSleep = i_addr_enableWifiOnBoot + sizeof(b_wifiOnBoot); +int i_addr_quickBoot = i_addr_autoSleep + sizeof(b_autoSleep); //int i_addr_enableWifiOnBoot = i_addr_btnFuncWhileConnected + sizeof(b_wifiOnBoot); diff --git a/src/hds.ino b/src/hds.ino index cffcc76..0b50c23 100644 --- a/src/hds.ino +++ b/src/hds.ino @@ -145,6 +145,15 @@ void buttonCircle_Released() { } void buttonCircle_Pressed() { + if (b_showChargingUI && i_buttonBootDelay == 0) { + //change GPIO_power_on_with from BATTERY_CHARGING to enter scale loop + GPIO_power_on_with = BUTTON_CIRCLE; + b_showChargingUI = false; + b_ble_enabled = true; + ble_init(); + wifi_init(); + } + if (b_menu) { navigateMenu(1); // Navigate to next menu item } @@ -160,6 +169,11 @@ void buttonCircle_Pressed() { } void buttonSquare_Pressed() { + if (b_showChargingUI && i_buttonBootDelay == 0) { + //change GPIO_power_on_with from BATTERY_CHARGING to enter scale loop + GPIO_power_on_with = BUTTON_SQUARE; + } + if (b_menu) { selectMenu(); // Select current menu item } @@ -342,7 +356,7 @@ void _wifi_init(void *args) { vTaskDelete(NULL); } void wifi_init() { - if (!readBoolEEPROMWithValidation(i_addr_enableWifiOnBoot, false)) { + if (!b_wifiOnBoot) { return; } xTaskCreate(_wifi_init, "Wifi Init Task", configMINIMAL_STACK_SIZE + 2048, NULL, 0, NULL); @@ -352,6 +366,17 @@ void setup() { Serial.begin(115200); while (!Serial) // Wait for the Serial port to initialize (typically used in Arduino to ensure the Serial monitor is ready) ; + if (!EEPROM.begin(512)) { + Serial.println("EEPROM init failed!"); + while (1) { + delay(1000); + } + } + + if (readBoolEEPROMWithValidation(i_addr_quickBoot, false)) + i_buttonBootDelay = 0; + + Serial.println("EEPROM init success"); button_init(); linkSubmenus(); pinMode(BATTERY_CHARGING, INPUT_PULLUP); @@ -388,7 +413,7 @@ void setup() { b_button_pressed = true; // Mark button as pressed } - if (millis() - t_power_on_button >= 500) { + if (millis() - t_power_on_button >= i_buttonBootDelay) { Serial.println("Button held for 0.5 second. Powering on..."); // Execute power on logic break; // Exit loop to continue with other code @@ -432,13 +457,6 @@ void setup() { if (b_ble_enabled) { ble_init(); } - if (!EEPROM.begin(512)) { - Serial.println("EEPROM init failed!"); - while (1) { - delay(1000); - } - } - Serial.println("EEPROM init success"); Serial.println("Begin!"); #if defined(ACC_MPU6050) || defined(ACC_BMA400) ACC_init(); @@ -598,20 +616,16 @@ void setup() { //calibration value is not valid, go to calibration procedure. } #endif - if (b_ble_enabled) { + b_wifiOnBoot = readBoolEEPROMWithValidation(i_addr_enableWifiOnBoot, false); + if (b_wifiOnBoot) { wifi_init(); } - // //wifiota - // #ifdef WIFI + // Enter Menu if (digitalRead(BUTTON_CIRCLE) == LOW && digitalRead(BUTTON_SQUARE) == LOW) { - //wifiOta(); - b_menu = true; refreshOLED((char *)"HDS Setup", FONT_EXTRACTION); delay(1000); - //showMenu(); } - // #endif #if DEBUG Serial.print("digitalRead(BUTTON_CIRCLE):"); @@ -913,8 +927,6 @@ void pureScale() { // Quick zero handling if (b_weight_quick_zero || b_bootTare) { f_displayedValue = 0.0; - resetTracking(); - resetStableOutput(); // Also reset stable output } } @@ -1320,8 +1332,10 @@ void loop() { if (b_chargingOLED) { if (digitalRead(BATTERY_CHARGING) == LOW && !b_calibration) { float perc = map(f_batteryVoltage * 1000, showEmptyBatteryBelowVoltage * 1000, showFullBatteryAboveVoltage * 1000, 0, 100); //map funtion doesn't take float as input. - chargingOLED((int)perc, f_batteryVoltage); //show charging ui + chargingOLED((int)perc, f_batteryVoltage); + b_showChargingUI = true; //show charging ui } else { + b_showChargingUI = false; if (f_batteryVoltage > 4.1) { //charging complete Serial.println("Charging compelete."); From 2b5cf58d403b4b9abe2ae29f63aeae1c4ef1f644 Mon Sep 17 00:00:00 2001 From: Sofronio Date: Wed, 26 Nov 2025 12:20:29 +0800 Subject: [PATCH 10/15] very quick touch will drain battery fix very quick touch may drain the battery cause the else { // If the button is released if (b_button_pressed) { will make the program fall in to a while loop, when a very short press causing b_button_pressed is false, and esp32_sleep() would be never called. --- src/hds.ino | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/hds.ino b/src/hds.ino index 0b50c23..beb7644 100644 --- a/src/hds.ino +++ b/src/hds.ino @@ -407,6 +407,12 @@ void setup() { b_ble_enabled = true; } while (true && GPIO_power_on_with > 0) { + if (i_buttonBootDelay == 0){ + Serial.println("Quick boot. Powering on..."); + // Execute power on logic + break; // Exit loop to continue with other code + } + if (digitalRead(GPIO_power_on_with) == LOW) { // Button is pressed if (!b_button_pressed) { t_power_on_button = millis(); @@ -419,17 +425,12 @@ void setup() { break; // Exit loop to continue with other code } } else { - // If the button is released - if (b_button_pressed) { - //Power on by button press - Serial.println("Button released before 0.5 second."); - Serial.println("Going to sleep now."); - stopWebServer(); - stopWifi(); - esp32_sleep(); - //shut_down_now_nobeep(); - break; // Exit loop to enter sleep mode - } + Serial.println("Button released before 0.5 second."); + Serial.println("Going to sleep now."); + stopWebServer(); + stopWifi(); + esp32_sleep(); + break; // Exit loop to enter sleep mode b_button_pressed = false; // Reset mark } } From 8ade760b078e0d05b96ed6be5cbc1fdd34f3df65 Mon Sep 17 00:00:00 2001 From: Vid Tadel Date: Wed, 26 Nov 2025 07:08:35 +0100 Subject: [PATCH 11/15] use stable pioarduino version --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 1765c24..29ad451 100644 --- a/platformio.ini +++ b/platformio.ini @@ -16,7 +16,7 @@ data_dir = web_apps [env:esp32s3] ;-- esp32 -platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.31/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip board = esp32-s3-devkitc-1 framework = arduino #board_build.partitions = From 6f52d9e3ff8f8a9da74ecf4e2f39343f3a96e781 Mon Sep 17 00:00:00 2001 From: Vid Tadel Date: Tue, 2 Dec 2025 08:32:32 +0100 Subject: [PATCH 12/15] don't turn on wifi if charging only --- src/hds.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hds.ino b/src/hds.ino index beb7644..ec10ef8 100644 --- a/src/hds.ino +++ b/src/hds.ino @@ -618,7 +618,7 @@ void setup() { } #endif b_wifiOnBoot = readBoolEEPROMWithValidation(i_addr_enableWifiOnBoot, false); - if (b_wifiOnBoot) { + if (b_wifiOnBoot && GPIO_power_on_with != BATTERY_CHARGING) { wifi_init(); } // Enter Menu From 847fea40752ed85380dfabe669d56d9223ea420f Mon Sep 17 00:00:00 2001 From: Vid Tadel Date: Tue, 2 Dec 2025 09:43:54 +0100 Subject: [PATCH 13/15] reconfigure button taps --- include/config.h | 7 +++---- src/hds.ino | 15 ++++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/config.h b/include/config.h index a1bd453..a9e2242 100644 --- a/include/config.h +++ b/include/config.h @@ -61,10 +61,9 @@ #define ACEBUTTON //ACEBUTTON ACEBUTTONT #define DEBOUNCE 100 -#define LONGCLICK 1000 -#define DOUBLECLICK 300 -#define CLICK 200 -#define BUTTON_KEY_DELAY 150 +#define LONGPRESS_DELAY 900 // threshold for long press +#define DOUBLECLICK_DELAY 600 // max gap between two clicks +#define CLICK_DELAY 250 // max press time that still counts as a click //DISPLAY #define Margin_Top 0 //显示边框 diff --git a/src/hds.ino b/src/hds.ino index ec10ef8..3f827e9 100644 --- a/src/hds.ino +++ b/src/hds.ino @@ -273,9 +273,7 @@ void buttonCircle_LongPressed() { b_ble_enabled = true; ble_init(); wifi_init(); - } else if (GPIO_power_on_with == BUTTON_CIRCLE || GPIO_power_on_with == BUTTON_SQUARE) { - buttonCircle_DoubleClicked(); - } + } // sendUsbButton(1, 2); // if (deviceConnected) { // Serial.println("Send O button long pressed BLE command"); @@ -310,14 +308,17 @@ void button_init() { buttonCircle.init(BUTTON_CIRCLE); buttonSquare.init(BUTTON_SQUARE); config1.setEventHandler(aceButtonHandleEvent); - //config1.setFeature(ButtonConfig::kFeatureClick); + config1.setFeature(ButtonConfig::kFeatureClick); //config1.setFeature(ButtonConfig::kFeatureSuppressAfterClick); config1.setFeature(ButtonConfig::kFeatureDoubleClick); - config1.setFeature(ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); + // config1.setFeature(ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); config1.setFeature(ButtonConfig::kFeatureLongPress); //config1.setFeature(ButtonConfig::kFeatureSuppressAfterLongPress); - config1.setDoubleClickDelay(DOUBLECLICK); - config1.setLongPressDelay(LONGCLICK); + // config1.setDoubleClickDelay(DOUBLECLICK); + // config1.setLongPressDelay(LONGCLICK); + config1.setClickDelay(CLICK_DELAY); + config1.setDoubleClickDelay(DOUBLECLICK_DELAY); + config1.setLongPressDelay(LONGPRESS_DELAY); } void _wifi_init(void *args) { From d690aa516902839abdc6adc3fccb2efacddebc68 Mon Sep 17 00:00:00 2001 From: Sofronio Date: Thu, 4 Dec 2025 11:24:00 +0800 Subject: [PATCH 14/15] fix: prevent scaleTimer trigger immediately after menu exit - Add t_menuExitTime variable to track menu exit time - Implement 500ms protection period after exiting menu - Prevent scaleTimer() from triggering during menu transition --- include/menu.h | 3 +++ include/parameter.h | 4 ++++ src/hds.ino | 5 ++++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/menu.h b/include/menu.h index 204af1d..7040087 100644 --- a/include/menu.h +++ b/include/menu.h @@ -211,6 +211,9 @@ void exitMenu() { delay(1000); b_menu = false; // Optionally reset or perform an exit action + t_menuExitTime = millis(); + // Capture the moment when menu exit begins to establish a reference point + // This enables timing-based protection against unintended triggers } #ifdef BUZZER diff --git a/include/parameter.h b/include/parameter.h index 91ff8e6..12b505b 100644 --- a/include/parameter.h +++ b/include/parameter.h @@ -184,6 +184,10 @@ bool b_extraction = false; //萃取模式标识 int b_mode = 0; //0 = pourover; 1 = espresso; bool b_menu = false; +unsigned long t_menuExitTime = 0; +// Timestamp recording when the menu exit process started +// Used to implement a protection period preventing unintended operations + bool b_calibration = false; //Calibration flag bool b_ota = false; //wifi ota flag int i_calibration = 0; //0 for manual cal, 1 for smart cal diff --git a/src/hds.ino b/src/hds.ino index 3f827e9..ef0a4dd 100644 --- a/src/hds.ino +++ b/src/hds.ino @@ -189,9 +189,12 @@ void buttonSquare_Pressed() { b_powerOff = true; } if (!b_menu && !b_calibration && (!deviceConnected || b_btnFuncWhileConnected)) { - scaleTimer(); + if (millis() - t_menuExitTime > 500) + // Check if enough time has passed since menu exit (500ms protection period) + scaleTimer(); } + Serial.println("[] button pressed"); sendUsbButton(2, 1); if (deviceConnected) { From e51916eb3c06ad7cfea7c5d00ccb3849756385cb Mon Sep 17 00:00:00 2001 From: Vid Tadel Date: Thu, 4 Dec 2025 07:25:49 +0100 Subject: [PATCH 15/15] decrease click delay --- include/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/config.h b/include/config.h index a9e2242..5276a58 100644 --- a/include/config.h +++ b/include/config.h @@ -63,7 +63,7 @@ #define DEBOUNCE 100 #define LONGPRESS_DELAY 900 // threshold for long press #define DOUBLECLICK_DELAY 600 // max gap between two clicks -#define CLICK_DELAY 250 // max press time that still counts as a click +#define CLICK_DELAY 180 // max press time that still counts as a click //DISPLAY #define Margin_Top 0 //显示边框