Почему сторожевой пес кусается слишком быстро?
В настоящее время пытаюсь внедрить сторожевой таймер в свой проект. Я использую библиотеку WDTZero для управления сторожевым таймером на моем MKR NB 1500. Программа пытается измерить данные, отправить их на сервер, заснуть, проснуться и повторить процесс. Иногда код может зависнуть, если он не может подключиться к серверу NTP или серверу, на котором хранятся данные, я хочу, чтобы сторожевой таймер сбрасывал программу в тех случаях, когда это происходит.
Набросок программы приведен ниже. Причина, по которой сеть NB часто находится после разных подключений, заключается в том, что NB 1500 не может подключиться к другому серверу, если GPRS-соединение уже открыто, поэтому я всегда сбрасываю его перед попыткой другого подключения.
void setup()
{
setup_watchdog(); // Устанавливаем сторожевой таймер
delay(1000);
connect_GPRS_NB(); //Подключается к сети NB и открывает GPRS-соединение
request_NTP(); // Запрашивает epoch1970 с сервера NTP и затем закрывает соединение
timezone_adjustment(); // Приспосабливает время эпохи к моему часовому поясу (в Норвегии)
set_RTC(); //Активирует SAMD21 RTC с этим временем, скорректированным часовым поясом
disconnect_NB(); //Отключается от сети NB
delay(2000);
MyWatchDoggy.clear(); //Сбрасывает сторожевой таймер
}
void loop()
{
connect_GPRS_NB(); //Подключается к сети NB и открывает GPRS-соединение
get_ENV_data(); //Выполняет измерения с использованием экрана MKR NB ENV
connect_to_server(); //Подключается к серверу, на котором будут храниться данные
write_to_server(); //Записываем данные на сервер
disconnect_from_server(); //Отключается от сервера
disconnect_NB(); //Отключается от сети NB
LowPower.deepSleep(300000); //Уходит в глубокий сон на 5 минут
delay(3000);
MyWatchDoggy.clear(); //Сбрасывает сторожевой таймер
}
Все вышеперечисленные функции написаны в других файлах .cpp и импортированы через файлы заголовков в основной файл. Вот код для активации и настройки сторожевого таймера:
#include "watchdog.hpp"
#include "GPRS_NB_connection.hpp"
WDTZero MyWatchDoggy;
void setup_watchdog()
{
MyWatchDoggy.attachShutdown(NVIC_SystemReset); // вызывает функцию сброса
MyWatchDoggy.setup(WDT_SOFTCYCLE8M); //8-минутный сторожевой таймер
}
Программа отлично работает описанным в начале поста способом, когда сторожевой таймер не включен. Но при включении сторожевой собаки она кусает через 30 секунд, тогда как собака должна была кусать только через 8 минут. Я вижу это, потому что данные отправляются на сервер примерно каждые 25-30 секунд. Сначала я подумал, что неправильно активировал сторожевой таймер, поэтому написал еще одну программу для проверки:
#include <Arduino.h>
#include <WDTZero.h>
#include <RTCZero.h>
WDTZero MyWatchDoggy;
RTCZero rtc;
void set_RTC()
{
rtc.begin();
rtc.setYear(0);
rtc.setMonth(0);
rtc.setDay(0);
rtc.setHours(0);
rtc.setMinutes(0);
rtc.setSeconds(0);
}
void shutdown()
{
Serial.println("Shutting down");
}
void setup()
{
Serial.begin(9600);
while (!Serial)
{
}
Serial.println("Starting up Arduino");
MyWatchDoggy.attachShutdown(shutdown);
MyWatchDoggy.setup(WDT_SOFTCYCLE8M);
set_RTC();
}
void loop()
{
Serial.print(rtc.getMinutes());
Serial.print("/");
Serial.print(rtc.getSeconds());
Serial.println("");
delay(1000);
}
Но в этой программе сторожевой таймер кусается примерно через 8 минут, как и должно быть.
Я не привожу код функций, описанных в первом коде, так как знаю, что они работают без сторожевого таймера, а сам код очень длинный. Но если вы считаете, что проблема может быть вызвана этими функциями по какой-либо причине, я отредактирую сообщение и включу все коды функций.
@5TableLegs, 👍1
1 ответ
Лучший ответ:
В библиотеке WDTZero длительное время сторожевого таймера достигается путем перезапуска сторожевого таймера в прерывании сторожевого таймера до тех пор, пока не будет достигнуто требуемое время.
Это не работает, если MCU спит.
- WatchDog на Arduino Nano — не восстанавливается
- AsyncWebServer дает сброс wdt
- Сброс Arduino с помощью ПО (каждый день)
- Программный сброс AVR без ватчдога
- Я получаю сброс сторожевого таймера в NodeMCU. Как навсегда отключить или остановить это?
- Получение сброса wdt + перезагрузка каждые 5 секунд с помощью простого кода кнопки/реле
- Причина сброса wdt: 4, режим загрузки: (3,6)
- esp32s: ошибка: 'WDT_TIMEOUT' не был объявлен в этой области
Что было бы обходным путем для этого? Есть ли способ полностью отключить WDT перед переходом в спящий режим, а затем снова включить его в начале цикла?, @5TableLegs
@5TableLegs
wdt.setup(WDT_OFF);
, @JurajСпасибо. Я не могу найти WDT_ON на странице ресурсов в GitHub. Итак, я предполагаю, что сторожевой таймер будет автоматически включен при выполнении MyWatchDoggy.setup(cycleOfChoice)?, @5TableLegs