Add an external watchdog module

This commit is contained in:
Quency-D 2026-01-22 15:03:40 +08:00
parent 7d1f52252b
commit c89a0e9929
10 changed files with 96 additions and 3 deletions

View file

@ -110,6 +110,10 @@ void setup() {
board.begin();
#ifdef HAS_EX_WATCHDOG
ex_watchdog.begin();
#endif
#ifdef DISPLAY_CLASS
DisplayDriver* disp = NULL;
if (display.begin()) {
@ -228,4 +232,7 @@ void loop() {
ui_task.loop();
#endif
rtc_clock.tick();
#ifdef HAS_EX_WATCHDOG
ex_watchdog.loop();
#endif
}

View file

@ -29,6 +29,10 @@ void setup() {
board.begin();
#ifdef HAS_EX_WATCHDOG
ex_watchdog.begin();
#endif
// For power saving
lastActive = millis(); // mark last active time since boot
@ -124,11 +128,17 @@ void loop() {
ui_task.loop();
#endif
rtc_clock.tick();
#ifdef HAS_EX_WATCHDOG
ex_watchdog.loop();
#endif
if (the_mesh.getNodePrefs()->powersaving_enabled && // To check if power saving is enabled
the_mesh.millisHasNowPassed(lastActive + nextSleepinSecs * 1000)) { // To check if it is time to sleep
if (!the_mesh.hasPendingWork()) { // No pending work. Safe to sleep
#ifdef HAS_EX_WATCHDOG
board.sleep(ex_watchdog.getIntervalMs()>1800?1800:ex_watchdog.getIntervalMs()); // To sleep. Wake up after 30 minutes or when receiving a LoRa packet
#else
board.sleep(1800); // To sleep. Wake up after 30 minutes or when receiving a LoRa packet
#endif
lastActive = millis();
nextSleepinSecs = 5; // Default: To work for 5s and sleep again
} else {

View file

@ -24,6 +24,10 @@ void setup() {
board.begin();
#ifdef HAS_EX_WATCHDOG
ex_watchdog.begin();
#endif
#ifdef DISPLAY_CLASS
if (display.begin()) {
display.startFrame();
@ -111,4 +115,7 @@ void loop() {
ui_task.loop();
#endif
rtc_clock.tick();
#ifdef HAS_EX_WATCHDOG
ex_watchdog.loop();
#endif
}

View file

@ -559,6 +559,10 @@ void setup() {
board.begin();
#ifdef HAS_EX_WATCHDOG
ex_watchdog.begin();
#endif
if (!radio_init()) { halt(); }
fast_rng.begin(radio_get_rng_seed());
@ -588,4 +592,7 @@ void setup() {
void loop() {
the_mesh.loop();
rtc_clock.tick();
#ifdef HAS_EX_WATCHDOG
ex_watchdog.loop();
#endif
}

View file

@ -58,6 +58,10 @@ void setup() {
board.begin();
#ifdef HAS_EX_WATCHDOG
ex_watchdog.begin();
#endif
#ifdef DISPLAY_CLASS
if (display.begin()) {
display.startFrame();
@ -145,4 +149,7 @@ void loop() {
ui_task.loop();
#endif
rtc_clock.tick();
#ifdef HAS_EX_WATCHDOG
ex_watchdog.loop();
#endif
}

View file

@ -0,0 +1,11 @@
#pragma once
class ExWatchdogManager {
public:
unsigned long next_feed_watchdog;
ExWatchdogManager() { next_feed_watchdog = 0; }
virtual bool begin() { return false; }
virtual void loop() { }
virtual unsigned long getIntervalMs() const { return 0; }
virtual void feed() { }
};

View file

@ -14,6 +14,11 @@ build_flags = ${nrf52_base.build_flags}
-D LORA_TX_POWER=22
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
-D HAS_EX_WATCHDOG
-D EX_WATCHDOG_DONE_PIN=9
-D EX_WATCHDOG_WAKE_PIN=10
-D EX_WATCHDOG_TIMEOUT_MS=480000 ;(6*60*1000) ; 6 minute watchdog
build_src_filter = ${nrf52_base.build_src_filter}
+<helpers/*.cpp>
+<../variants/heltec_mesh_solar>

View file

@ -13,6 +13,7 @@ VolatileRTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1);
SolarSensorManager sensors = SolarSensorManager(nmea);
SolarExWatchdog ex_watchdog;
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display;
@ -121,3 +122,30 @@ bool SolarSensorManager::setSettingValue(const char* name, const char* value) {
}
return false; // not supported
}
bool SolarExWatchdog::begin() {
next_feed_watchdog = 0;
pinMode(EX_WATCHDOG_WAKE_PIN, INPUT);
pinMode(EX_WATCHDOG_DONE_PIN, OUTPUT);
delay(1);
digitalWrite(EX_WATCHDOG_DONE_PIN, LOW);
delay(1);
feed();
return true;
}
void SolarExWatchdog::loop() {
if (millis() > next_feed_watchdog) {
feed();
next_feed_watchdog = millis() + EX_WATCHDOG_TIMEOUT_MS;
}
}
unsigned long SolarExWatchdog::getIntervalMs() const {
return next_feed_watchdog - millis();
}
void SolarExWatchdog::feed() {
digitalWrite(EX_WATCHDOG_DONE_PIN, HIGH);
delay(1);
digitalWrite(EX_WATCHDOG_DONE_PIN, LOW);
}

View file

@ -8,6 +8,7 @@
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
#include <helpers/sensors/LocationProvider.h>
#include <helpers/ExWatchdogManager.h>
#ifdef DISPLAY_CLASS
#include <helpers/ui/ST7789Display.h>
#endif
@ -30,10 +31,20 @@ public:
bool setSettingValue(const char* name, const char* value) override;
};
class SolarExWatchdog : public ExWatchdogManager {
public:
SolarExWatchdog() {}
bool begin() override;
void loop() override;
unsigned long getIntervalMs() const override;
void feed() override;
};
extern MeshSolarBoard board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern SolarSensorManager sensors;
extern SolarExWatchdog ex_watchdog;
#ifdef DISPLAY_CLASS
extern DISPLAY_CLASS display;

View file

@ -34,8 +34,8 @@
#define PIN_SERIAL1_RX (37)
#define PIN_SERIAL1_TX (39)
#define PIN_SERIAL2_RX (9)
#define PIN_SERIAL2_TX (10)
#define PIN_SERIAL2_RX (-1)
#define PIN_SERIAL2_TX (-1)
////////////////////////////////////////////////////////////////////////////////
// I2C pin definition