From a8b3fc5ce3fdca7fad0aa809d4aefe4feb1197ab Mon Sep 17 00:00:00 2001 From: Nick Dunklee Date: Mon, 16 Mar 2026 22:15:10 -0600 Subject: [PATCH] fix(t1000-e): fix extended uptime failures in GPS and sensor code - Fix millis() wraparound (49-day) in T1000SensorManager::loop() and MicroNMEALocationProvider::loop() by switching from absolute comparison (millis() > next_*) to elapsed-time arithmetic ((uint32_t)(millis() - last_*) >= interval) with uint32_t timestamps; previous pattern could stall GPS updates and time sync for up to ~24 days after wraparound - Fix division-by-zero crash in get_heater_temperature() when ntc_volt == 0 (open circuit or bad ADC read); now returns 0.0f safely - Fix out-of-bounds array access in get_heater_temperature(): loop exit at i == 0 caused ntc_res2[i-1] / ntc_temp2[i-1] at index -1; loop exhaustion at i == 136 caused ntc_res2[136] one-past-end read; clamped i to [1, 135] with early-exit returns for edge temperatures and guarded interpolation denominator against zero --- .../sensors/MicroNMEALocationProvider.h | 6 +++--- variants/t1000-e/t1000e_sensors.cpp | 21 ++++++++++++++----- variants/t1000-e/target.cpp | 8 +++---- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/helpers/sensors/MicroNMEALocationProvider.h b/src/helpers/sensors/MicroNMEALocationProvider.h index 1de7532758..e4f9286186 100644 --- a/src/helpers/sensors/MicroNMEALocationProvider.h +++ b/src/helpers/sensors/MicroNMEALocationProvider.h @@ -41,7 +41,7 @@ class MicroNMEALocationProvider : public LocationProvider { RefCountedDigitalPin* _peripher_power; int _pin_reset; int _pin_en; - long next_check = 0; + uint32_t last_check = 0; long time_valid = 0; public : @@ -127,8 +127,8 @@ public : if (!isValid()) time_valid = 0; - if (millis() > next_check) { - next_check = millis() + 1000; + if ((uint32_t)(millis() - last_check) >= 1000) { + last_check = millis(); if (_time_sync_needed && time_valid > 2) { if (_clock != NULL) { _clock->setCurrentTime(getTimestamp()); diff --git a/variants/t1000-e/t1000e_sensors.cpp b/variants/t1000-e/t1000e_sensors.cpp index f02541382d..7bfa06f05d 100644 --- a/variants/t1000-e/t1000e_sensors.cpp +++ b/variants/t1000-e/t1000e_sensors.cpp @@ -32,11 +32,12 @@ static char ntc_temp2[136] = { }; static float get_heater_temperature(unsigned int vcc_volt, unsigned int ntc_volt) { + if (ntc_volt == 0) { + return 0.0f; // avoid division by zero on open circuit / sensor fault + } int i = 0; - float Vout = 0, Rt = 0, temp = 0; - Vout = ntc_volt; - - Rt = (HEATER_NTC_RP * vcc_volt) / Vout - HEATER_NTC_RP; + float Rt = 0, temp = 0; + Rt = (HEATER_NTC_RP * (float)vcc_volt) / ntc_volt - HEATER_NTC_RP; for (i = 0; i < 136; i++) { if (Rt >= ntc_res2[i]) { @@ -44,7 +45,17 @@ static float get_heater_temperature(unsigned int vcc_volt, unsigned int ntc_volt } } - temp = ntc_temp2[i - 1] + 1 * (ntc_res2[i - 1] - Rt) / (float)(ntc_res2[i - 1] - ntc_res2[i]); + if (i <= 0) { + return (float)ntc_temp2[0]; + } + if (i >= 136) { + return (float)ntc_temp2[135]; + } + int denom = ntc_res2[i - 1] - ntc_res2[i]; + if (denom == 0) { + return (float)ntc_temp2[i - 1]; + } + temp = ntc_temp2[i - 1] + 1 * (ntc_res2[i - 1] - Rt) / (float)denom; temp = (temp * 100 + 5) / 100; return temp; diff --git a/variants/t1000-e/target.cpp b/variants/t1000-e/target.cpp index da8fa48bb3..30395bb717 100644 --- a/variants/t1000-e/target.cpp +++ b/variants/t1000-e/target.cpp @@ -162,18 +162,18 @@ bool T1000SensorManager::querySensors(uint8_t requester_permissions, CayenneLPP& } void T1000SensorManager::loop() { - static long next_gps_update = 0; + static uint32_t last_gps_update = 0; + constexpr uint32_t GPS_UPDATE_INTERVAL_MS = 1000; _nmea->loop(); - if (millis() > next_gps_update) { + if ((uint32_t)(millis() - last_gps_update) >= GPS_UPDATE_INTERVAL_MS) { if (gps_active && _nmea->isValid()) { node_lat = ((double)_nmea->getLatitude())/1000000.; node_lon = ((double)_nmea->getLongitude())/1000000.; node_altitude = ((double)_nmea->getAltitude()) / 1000.0; - //Serial.printf("lat %f lon %f\r\n", _lat, _lon); } - next_gps_update = millis() + 1000; + last_gps_update = millis(); } }