diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index 7c8420194..e8945e3df 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -77,7 +77,7 @@ public: } void poll() override { - if (millis() >= dismiss_after) { + if (millis_passed(dismiss_after)) { _task->gotoHomeScreen(); } } @@ -156,7 +156,7 @@ class HomeScreen : public UIScreen { int next_sensors_refresh = 0; void refresh_sensors() { - if (millis() > next_sensors_refresh) { + if (millis_passed(next_sensors_refresh)) { sensors_lpp.reset(); sensors_nb = 0; sensors_lpp.addVoltage(TELEM_CHANNEL_SELF, (float)board.getBattMilliVolts() / 1000.0f); @@ -764,7 +764,7 @@ void UITask::loop() { } #endif #if defined(BACKLIGHT_BTN) - if (millis() > next_backlight_btn_check) { + if (millis_passed(next_backlight_btn_check)) { bool touch_state = digitalRead(PIN_BUTTON2); #if defined(DISP_BACKLIGHT) digitalWrite(DISP_BACKLIGHT, !touch_state); @@ -790,10 +790,10 @@ void UITask::loop() { if (curr) curr->poll(); if (_display != NULL && _display->isOn()) { - if (millis() >= _next_refresh && curr) { + if (millis_passed(_next_refresh) && curr) { _display->startFrame(); int delay_millis = curr->render(*_display); - if (millis() < _alert_expiry) { // render alert popup + if (!millis_passed(_alert_expiry)) { // render alert popup _display->setTextSize(1); int y = _display->height() / 3; int p = _display->height() / 32; @@ -818,7 +818,7 @@ void UITask::loop() { _auto_off = millis() + AUTO_OFF_MILLIS; } #endif - if (millis() > _auto_off) { + if (millis_passed(_auto_off)) { _display->turnOff(); } #endif @@ -829,7 +829,7 @@ void UITask::loop() { #endif #ifdef AUTO_SHUTDOWN_MILLIVOLTS - if (millis() > next_batt_chck) { + if (millis_passed(next_batt_chck)) { uint16_t milliVolts = getBattMilliVolts(); if (milliVolts > 0 && milliVolts < AUTO_SHUTDOWN_MILLIVOLTS) { if(!board.isExternalPowered()) { diff --git a/examples/companion_radio/ui-orig/UITask.cpp b/examples/companion_radio/ui-orig/UITask.cpp index 552904677..8c3b03e0a 100644 --- a/examples/companion_radio/ui-orig/UITask.cpp +++ b/examples/companion_radio/ui-orig/UITask.cpp @@ -335,7 +335,7 @@ void UITask::loop() { _need_refresh = true; _firstBoot = false; } - if (millis() >= _next_refresh && _need_refresh) { + if (millis_passed(_next_refresh) && _need_refresh) { _display->startFrame(); renderCurrScreen(); _display->endFrame(); @@ -351,7 +351,7 @@ void UITask::loop() { _auto_off = millis() + AUTO_OFF_MILLIS; } #endif - if (millis() > _auto_off) { + if (millis_passed(_auto_off)) { _display->turnOff(); } } diff --git a/examples/simple_repeater/UITask.cpp b/examples/simple_repeater/UITask.cpp index 6a8514388..a16e79794 100644 --- a/examples/simple_repeater/UITask.cpp +++ b/examples/simple_repeater/UITask.cpp @@ -1,6 +1,7 @@ #include "UITask.h" #include #include +#include #ifndef USER_BTN_PRESSED #define USER_BTN_PRESSED LOW @@ -46,7 +47,7 @@ void UITask::begin(NodePrefs* node_prefs, const char* build_date, const char* fi void UITask::renderCurrScreen() { char tmp[80]; - if (millis() < BOOT_SCREEN_MILLIS) { // boot screen + if (!millis_passed(BOOT_SCREEN_MILLIS)) { // boot screen // meshcore logo _display->setColor(DisplayDriver::BLUE); int logoWidth = 128; @@ -94,7 +95,7 @@ void UITask::renderCurrScreen() { void UITask::loop() { #ifdef PIN_USER_BTN - if (millis() >= _next_read) { + if (millis_passed(_next_read)) { int btnState = digitalRead(PIN_USER_BTN); if (btnState != _prevBtnState) { if (btnState == USER_BTN_PRESSED) { // pressed? @@ -112,14 +113,14 @@ void UITask::loop() { #endif if (_display->isOn()) { - if (millis() >= _next_refresh) { + if (millis_passed(_next_refresh)) { _display->startFrame(); renderCurrScreen(); _display->endFrame(); _next_refresh = millis() + 1000; // refresh every second } - if (millis() > _auto_off) { + if (millis_passed(_auto_off)) { _display->turnOff(); } } diff --git a/examples/simple_room_server/UITask.cpp b/examples/simple_room_server/UITask.cpp index 640a1d2d1..054dec197 100644 --- a/examples/simple_room_server/UITask.cpp +++ b/examples/simple_room_server/UITask.cpp @@ -1,6 +1,7 @@ #include "UITask.h" #include #include +#include #ifndef USER_BTN_PRESSED #define USER_BTN_PRESSED LOW @@ -46,7 +47,7 @@ void UITask::begin(NodePrefs* node_prefs, const char* build_date, const char* fi void UITask::renderCurrScreen() { char tmp[80]; - if (millis() < BOOT_SCREEN_MILLIS) { // boot screen + if (!millis_passed(BOOT_SCREEN_MILLIS)) { // boot screen // meshcore logo _display->setColor(DisplayDriver::BLUE); int logoWidth = 128; @@ -94,7 +95,7 @@ void UITask::renderCurrScreen() { void UITask::loop() { #ifdef PIN_USER_BTN - if (millis() >= _next_read) { + if (millis_passed(_next_read)) { int btnState = digitalRead(PIN_USER_BTN); if (btnState != _prevBtnState) { if (btnState == USER_BTN_PRESSED) { // pressed? @@ -112,14 +113,14 @@ void UITask::loop() { #endif if (_display->isOn()) { - if (millis() >= _next_refresh) { + if (millis_passed(_next_refresh)) { _display->startFrame(); renderCurrScreen(); _display->endFrame(); _next_refresh = millis() + 1000; // refresh every second } - if (millis() > _auto_off) { + if (millis_passed(_auto_off)) { _display->turnOff(); } } diff --git a/examples/simple_sensor/UITask.cpp b/examples/simple_sensor/UITask.cpp index 757ea1dc6..20923eee9 100644 --- a/examples/simple_sensor/UITask.cpp +++ b/examples/simple_sensor/UITask.cpp @@ -1,6 +1,7 @@ #include "UITask.h" #include #include +#include #ifndef USER_BTN_PRESSED #define USER_BTN_PRESSED LOW @@ -46,7 +47,7 @@ void UITask::begin(NodePrefs* node_prefs, const char* build_date, const char* fi void UITask::renderCurrScreen() { char tmp[80]; - if (millis() < BOOT_SCREEN_MILLIS) { // boot screen + if (!millis_passed(BOOT_SCREEN_MILLIS)) { // boot screen // meshcore logo _display->setColor(DisplayDriver::BLUE); int logoWidth = 128; @@ -94,7 +95,7 @@ void UITask::renderCurrScreen() { void UITask::loop() { #ifdef PIN_USER_BTN - if (millis() >= _next_read) { + if (millis_passed(_next_read)) { int btnState = digitalRead(PIN_USER_BTN); if (btnState != _prevBtnState) { if (btnState == USER_BTN_PRESSED) { // pressed? @@ -112,14 +113,14 @@ void UITask::loop() { #endif if (_display->isOn()) { - if (millis() >= _next_refresh) { + if (millis_passed(_next_refresh)) { _display->startFrame(); renderCurrScreen(); _display->endFrame(); _next_refresh = millis() + 1000; // refresh every second } - if (millis() > _auto_off) { + if (millis_passed(_auto_off)) { _display->turnOff(); } } diff --git a/src/helpers/ArduinoHelpers.h b/src/helpers/ArduinoHelpers.h index 97596daa3..e5bb15daf 100644 --- a/src/helpers/ArduinoHelpers.h +++ b/src/helpers/ArduinoHelpers.h @@ -24,6 +24,12 @@ public: unsigned long getMillis() override { return millis(); } }; +// Wrap-safe millis deadline check. Handles the 49-day millis() overflow +// using signed comparison (2's complement). Use instead of millis() >= target. +inline bool millis_passed(unsigned long target) { + return (long)(millis() - target) > 0; +} + class StdRNG : public mesh::RNG { public: void begin(long seed) { randomSeed(seed); } diff --git a/src/helpers/esp32/SerialBLEInterface.cpp b/src/helpers/esp32/SerialBLEInterface.cpp index dcfa0e1e3..f02840ac6 100644 --- a/src/helpers/esp32/SerialBLEInterface.cpp +++ b/src/helpers/esp32/SerialBLEInterface.cpp @@ -1,5 +1,6 @@ #include "SerialBLEInterface.h" #include "esp_mac.h" +#include // See the following for generating UUIDs: // https://www.uuidgenerator.net/ @@ -183,12 +184,12 @@ size_t SerialBLEInterface::writeFrame(const uint8_t src[], size_t len) { #define BLE_WRITE_MIN_INTERVAL 60 bool SerialBLEInterface::isWriteBusy() const { - return millis() < _last_write + BLE_WRITE_MIN_INTERVAL; // still too soon to start another write? + return !millis_passed(_last_write + BLE_WRITE_MIN_INTERVAL); // still too soon to start another write? } size_t SerialBLEInterface::checkRecvFrame(uint8_t dest[]) { if (send_queue_len > 0 // first, check send queue - && millis() >= _last_write + BLE_WRITE_MIN_INTERVAL // space the writes apart + && millis_passed(_last_write + BLE_WRITE_MIN_INTERVAL) // space the writes apart ) { _last_write = millis(); pTxCharacteristic->setValue(send_queue[0].buf, send_queue[0].len); @@ -238,7 +239,7 @@ size_t SerialBLEInterface::checkRecvFrame(uint8_t dest[]) { oldDeviceConnected = deviceConnected; } - if (adv_restart_time && millis() >= adv_restart_time) { + if (adv_restart_time && millis_passed(adv_restart_time)) { if (pServer->getConnectedCount() == 0) { BLE_DEBUG_PRINTLN("SerialBLEInterface -> re-starting advertising"); pServer->getAdvertising()->start(); // re-Start advertising diff --git a/src/helpers/radiolib/CustomSX1276.h b/src/helpers/radiolib/CustomSX1276.h index bee252743..087a6784d 100644 --- a/src/helpers/radiolib/CustomSX1276.h +++ b/src/helpers/radiolib/CustomSX1276.h @@ -1,6 +1,7 @@ #pragma once #include +#include #define RH_RF95_MODEM_STATUS_CLEAR 0x10 #define RH_RF95_MODEM_STATUS_HEADER_INFO_VALID 0x08 @@ -79,7 +80,7 @@ class CustomSX1276 : public SX1276 { // wait for channel activity detected or timeout unsigned long timeout = millis() + 16; - while(!this->mod->hal->digitalRead(this->mod->getIrq()) && millis() < timeout) { + while(!this->mod->hal->digitalRead(this->mod->getIrq()) && !millis_passed(timeout)) { this->mod->hal->yield(); if(this->mod->hal->digitalRead(this->mod->getGpio())) { return(RADIOLIB_PREAMBLE_DETECTED); diff --git a/src/helpers/sensors/EnvironmentSensorManager.cpp b/src/helpers/sensors/EnvironmentSensorManager.cpp index 73842d9ee..ed81e39f9 100644 --- a/src/helpers/sensors/EnvironmentSensorManager.cpp +++ b/src/helpers/sensors/EnvironmentSensorManager.cpp @@ -1,4 +1,5 @@ #include "EnvironmentSensorManager.h" +#include #include @@ -893,7 +894,7 @@ void EnvironmentSensorManager::loop() { if (gps_active) { _location->loop(); } - if (millis() > next_gps_update) { + if (millis_passed(next_gps_update)) { if(gps_active){ #ifdef RAK_WISBLOCK_GPS diff --git a/src/helpers/sensors/MicroNMEALocationProvider.h b/src/helpers/sensors/MicroNMEALocationProvider.h index eec466d3a..c8f5b1273 100644 --- a/src/helpers/sensors/MicroNMEALocationProvider.h +++ b/src/helpers/sensors/MicroNMEALocationProvider.h @@ -4,6 +4,7 @@ #include #include #include +#include #ifndef GPS_EN #ifdef PIN_GPS_EN @@ -143,7 +144,7 @@ public : if (!isValid()) time_valid = 0; - if (millis() > next_check) { + if (millis_passed(next_check)) { next_check = millis() + 1000; // Re-enable time sync periodically when GPS has valid fix if (!_time_sync_needed && _clock != NULL && (millis() - _last_time_sync) > TIME_SYNC_INTERVAL) { diff --git a/variants/heltec_mesh_solar/target.cpp b/variants/heltec_mesh_solar/target.cpp index d140864cd..533c4da69 100644 --- a/variants/heltec_mesh_solar/target.cpp +++ b/variants/heltec_mesh_solar/target.cpp @@ -69,7 +69,7 @@ void SolarSensorManager::loop() { _location->loop(); - if (millis() > next_gps_update) { + if (millis_passed(next_gps_update)) { if (_location->isValid()) { node_lat = ((double)_location->getLatitude())/1000000.; node_lon = ((double)_location->getLongitude())/1000000.; diff --git a/variants/heltec_tracker/target.cpp b/variants/heltec_tracker/target.cpp index f32c41ff4..cca1ecc14 100644 --- a/variants/heltec_tracker/target.cpp +++ b/variants/heltec_tracker/target.cpp @@ -1,6 +1,7 @@ #include #include "target.h" +#include #include HeltecV3Board board; @@ -75,7 +76,7 @@ void HWTSensorManager::loop() { _location->loop(); - if (millis() > next_gps_update) { + if (millis_passed(next_gps_update)) { if (gps_active && _location->isValid()) { node_lat = ((double)_location->getLatitude())/1000000.; node_lon = ((double)_location->getLongitude())/1000000.; diff --git a/variants/meshadventurer/target.cpp b/variants/meshadventurer/target.cpp index 8795a4cbe..63d910c43 100644 --- a/variants/meshadventurer/target.cpp +++ b/variants/meshadventurer/target.cpp @@ -1,6 +1,7 @@ #include #include "target.h" +#include #include MeshadventurerBoard board; @@ -67,7 +68,7 @@ bool MASensorManager::querySensors(uint8_t requester_permissions, CayenneLPP& te void MASensorManager::loop() { static long next_gps_update = 0; _location->loop(); - if(millis() > next_gps_update && gps_active) { + if(millis_passed(next_gps_update) && gps_active) { if(_location->isValid()) { node_lat = ((double)_location->getLatitude()) / 1000000.; node_lon = ((double)_location->getLongitude()) / 1000000.; diff --git a/variants/nano_g2_ultra/target.cpp b/variants/nano_g2_ultra/target.cpp index 69a2772cc..f535385a0 100644 --- a/variants/nano_g2_ultra/target.cpp +++ b/variants/nano_g2_ultra/target.cpp @@ -81,7 +81,7 @@ void NanoG2UltraSensorManager::loop() { _location->loop(); - if (millis() > next_gps_update) { + if (millis_passed(next_gps_update)) { if (_location->isValid()) { node_lat = ((double)_location->getLatitude()) / 1000000.; node_lon = ((double)_location->getLongitude()) / 1000000.; diff --git a/variants/t1000-e/target.cpp b/variants/t1000-e/target.cpp index 425328270..eeef1aa69 100644 --- a/variants/t1000-e/target.cpp +++ b/variants/t1000-e/target.cpp @@ -1,6 +1,7 @@ #include #include "t1000e_sensors.h" #include "target.h" +#include #include T1000eBoard board; @@ -151,7 +152,7 @@ void T1000SensorManager::loop() { _nmea->loop(); - if (millis() > next_gps_update) { + if (millis_passed(next_gps_update)) { if (gps_active && _nmea->isValid()) { node_lat = ((double)_nmea->getLatitude())/1000000.; node_lon = ((double)_nmea->getLongitude())/1000000.; diff --git a/variants/thinknode_m1/target.cpp b/variants/thinknode_m1/target.cpp index 69306fc0e..dd03b07f8 100644 --- a/variants/thinknode_m1/target.cpp +++ b/variants/thinknode_m1/target.cpp @@ -98,7 +98,7 @@ void ThinkNodeM1SensorManager::loop() { _location->loop(); - if (millis() > next_gps_update) { + if (millis_passed(next_gps_update)) { if (_location->isValid()) { node_lat = ((double)_location->getLatitude())/1000000.; node_lon = ((double)_location->getLongitude())/1000000.;