Почему сторожевой пес кусается слишком быстро?

watchdog arduino-mkr

В настоящее время пытаюсь внедрить сторожевой таймер в свой проект. Я использую библиотеку 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 минут, как и должно быть.

Я не привожу код функций, описанных в первом коде, так как знаю, что они работают без сторожевого таймера, а сам код очень длинный. Но если вы считаете, что проблема может быть вызвана этими функциями по какой-либо причине, я отредактирую сообщение и включу все коды функций.

, 👍1


1 ответ


Лучший ответ:

1

В библиотеке WDTZero длительное время сторожевого таймера достигается путем перезапуска сторожевого таймера в прерывании сторожевого таймера до тех пор, пока не будет достигнуто требуемое время.

Это не работает, если MCU спит.

,

Что было бы обходным путем для этого? Есть ли способ полностью отключить WDT перед переходом в спящий режим, а затем снова включить его в начале цикла?, @5TableLegs

@5TableLegs wdt.setup(WDT_OFF);, @Juraj

Спасибо. Я не могу найти WDT_ON на странице ресурсов в GitHub. Итак, я предполагаю, что сторожевой таймер будет автоматически включен при выполнении MyWatchDoggy.setup(cycleOfChoice)?, @5TableLegs