diff --git a/src/mesh/MeshModule.cpp b/src/mesh/MeshModule.cpp index 2f2863fa56..62d3c82bc4 100644 --- a/src/mesh/MeshModule.cpp +++ b/src/mesh/MeshModule.cpp @@ -10,6 +10,7 @@ std::vector *MeshModule::modules; const meshtastic_MeshPacket *MeshModule::currentRequest; +uint8_t MeshModule::numPeriodicModules = 0; /** * If any of the current chain of modules has already sent a reply, it will be here. This is useful to allow @@ -35,6 +36,15 @@ MeshModule::~MeshModule() modules->erase(it); } +// ⚠️ **Only call once** to set the initial delay before a module starts broadcasting periodically +int32_t MeshModule::setStartDelay() +{ + int32_t startDelay = MESHMODULE_MIN_BROADCAST_DELAY_MS + numPeriodicModules * MESHMODULE_BROADCAST_SPACING_MS; + numPeriodicModules++; + + return startDelay; +} + meshtastic_MeshPacket *MeshModule::allocAckNak(meshtastic_Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex, uint8_t hopLimit) { diff --git a/src/mesh/MeshModule.h b/src/mesh/MeshModule.h index a88f1e6ff6..f08b8f49cf 100644 --- a/src/mesh/MeshModule.h +++ b/src/mesh/MeshModule.h @@ -9,6 +9,9 @@ #include #endif +#define MESHMODULE_MIN_BROADCAST_DELAY_MS 30 * 1000 // Min. delay after boot before sending first broadcast by any module +#define MESHMODULE_BROADCAST_SPACING_MS 15 * 1000 // Initial spacing between broadcasts of different modules + /** handleReceived return enumeration * * Use ProcessMessage::CONTINUE to allows other modules to process a message. @@ -119,6 +122,12 @@ class MeshModule */ static const meshtastic_MeshPacket *currentRequest; + // We keep track of the number of modules that send a periodic broadcast to schedule them spaced out over time + static uint8_t numPeriodicModules; + + // Set the start delay for module that broadcasts periodically + int32_t setStartDelay(); + /** * If your handler wants to send a response, simply set currentReply and it will be sent at the end of response handling. */ diff --git a/src/modules/DetectionSensorModule.cpp b/src/modules/DetectionSensorModule.cpp index c479867fc8..ca682b7720 100644 --- a/src/modules/DetectionSensorModule.cpp +++ b/src/modules/DetectionSensorModule.cpp @@ -81,7 +81,7 @@ int32_t DetectionSensorModule::runOnce() } LOG_INFO("Detection Sensor Module: init"); - return DELAYED_INTERVAL; + return setStartDelay(); } // LOG_DEBUG("Detection Sensor Module: Current pin state: %i", digitalRead(moduleConfig.detection_sensor.monitor_pin)); @@ -161,4 +161,4 @@ bool DetectionSensorModule::hasDetectionEvent() bool currentState = digitalRead(moduleConfig.detection_sensor.monitor_pin); // LOG_DEBUG("Detection Sensor Module: Current state: %i", currentState); return (moduleConfig.detection_sensor.detection_trigger_type & 1) ? currentState : !currentState; -} +} \ No newline at end of file diff --git a/src/modules/NodeInfoModule.cpp b/src/modules/NodeInfoModule.cpp index b55d47d5ba..ce4a6bd066 100644 --- a/src/modules/NodeInfoModule.cpp +++ b/src/modules/NodeInfoModule.cpp @@ -97,8 +97,9 @@ NodeInfoModule::NodeInfoModule() : ProtobufModule("nodeinfo", meshtastic_PortNum_NODEINFO_APP, &meshtastic_User_msg), concurrency::OSThread("NodeInfo") { isPromiscuous = true; // We always want to update our nodedb, even if we are sniffing on others - setIntervalFromNow(30 * - 1000); // Send our initial owner announcement 30 seconds after we start (to give network time to setup) + + setIntervalFromNow(setStartDelay()); // Send our initial owner announcement 30 seconds + // after we start (to give network time to setup) } int32_t NodeInfoModule::runOnce() @@ -112,4 +113,4 @@ int32_t NodeInfoModule::runOnce() sendOurNodeInfo(NODENUM_BROADCAST, requestReplies); // Send our info (don't request replies) } return Default::getConfiguredOrDefaultMs(config.device.node_info_broadcast_secs, default_node_info_broadcast_secs); -} +} \ No newline at end of file diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index 95a47f0a18..e0f5b513fc 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -28,8 +28,9 @@ PositionModule::PositionModule() nodeStatusObserver.observe(&nodeStatus->onNewStatus); if (config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER && - config.device.role != meshtastic_Config_DeviceConfig_Role_TAK_TRACKER) - setIntervalFromNow(60 * 1000); + config.device.role != meshtastic_Config_DeviceConfig_Role_TAK_TRACKER) { + setIntervalFromNow(setStartDelay()); + } // Power saving trackers should clear their position on startup to avoid waking up and sending a stale position if ((config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER || diff --git a/src/modules/Telemetry/AirQualityTelemetry.cpp b/src/modules/Telemetry/AirQualityTelemetry.cpp index 6a8077f033..392bd61483 100644 --- a/src/modules/Telemetry/AirQualityTelemetry.cpp +++ b/src/modules/Telemetry/AirQualityTelemetry.cpp @@ -50,12 +50,12 @@ int32_t AirQualityTelemetryModule::runOnce() nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I].first = found.address.address; nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I].second = i2cScanner->fetchI2CBus(found.address); - return 1000; + return setStartDelay(); } #endif return disable(); } - return 1000; + return setStartDelay(); } return disable(); } else { diff --git a/src/modules/Telemetry/DeviceTelemetry.h b/src/modules/Telemetry/DeviceTelemetry.h index 19b7d5b014..a1d55a596e 100644 --- a/src/modules/Telemetry/DeviceTelemetry.h +++ b/src/modules/Telemetry/DeviceTelemetry.h @@ -18,7 +18,7 @@ class DeviceTelemetryModule : private concurrency::OSThread, public ProtobufModu uptimeWrapCount = 0; uptimeLastMs = millis(); nodeStatusObserver.observe(&nodeStatus->onNewStatus); - setIntervalFromNow(45 * 1000); // Wait until NodeInfo is sent + setIntervalFromNow(setStartDelay()); // Wait until NodeInfo is sent } virtual bool wantUIFrame() { return false; } @@ -62,4 +62,4 @@ class DeviceTelemetryModule : private concurrency::OSThread, public ProtobufModu uint32_t uptimeWrapCount; uint32_t uptimeLastMs; -}; +}; \ No newline at end of file diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index 6a5e8376dc..3fa3e848a4 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -107,8 +107,6 @@ int32_t EnvironmentTelemetryModule::runOnce() if (moduleConfig.telemetry.environment_measurement_enabled) { LOG_INFO("Environment Telemetry: init"); - // it's possible to have this module enabled, only for displaying values on the screen. - // therefore, we should only enable the sensor loop if measurement is also enabled #ifdef SENSECAP_INDICATOR result = indicatorSensor.runOnce(); #endif @@ -171,7 +169,9 @@ int32_t EnvironmentTelemetryModule::runOnce() #endif #endif } - return result; + // it's possible to have this module enabled, only for displaying values on the screen. + // therefore, we should only enable the sensor loop if measurement is also enabled + return result == UINT32_MAX ? disable() : setStartDelay(); } else { // if we somehow got to a second run of this module with measurement disabled, then just wait forever if (!moduleConfig.telemetry.environment_measurement_enabled) { diff --git a/src/modules/Telemetry/HealthTelemetry.cpp b/src/modules/Telemetry/HealthTelemetry.cpp index 1b9b498130..a2a18ba035 100644 --- a/src/modules/Telemetry/HealthTelemetry.cpp +++ b/src/modules/Telemetry/HealthTelemetry.cpp @@ -62,7 +62,7 @@ int32_t HealthTelemetryModule::runOnce() if (max30102Sensor.hasSensor()) result = max30102Sensor.runOnce(); } - return result; + return result == UINT32_MAX ? disable() : setStartDelay(); } else { // if we somehow got to a second run of this module with measurement disabled, then just wait forever if (!moduleConfig.telemetry.health_measurement_enabled) { diff --git a/src/modules/Telemetry/PowerTelemetry.cpp b/src/modules/Telemetry/PowerTelemetry.cpp index 38a5c6f117..04bcbe2009 100644 --- a/src/modules/Telemetry/PowerTelemetry.cpp +++ b/src/modules/Telemetry/PowerTelemetry.cpp @@ -65,7 +65,7 @@ int32_t PowerTelemetryModule::runOnce() if (max17048Sensor.hasSensor() && !max17048Sensor.isInitialized()) result = max17048Sensor.runOnce(); } - return result; + return result == UINT32_MAX ? disable() : setStartDelay(); #else return disable(); #endif