WatchDog на Arduino Nano — не восстанавливается

Я пытаюсь добавить сторожевой таймер на Arduino Nano для своего кода, и я точно следую коду в данное руководство, но по истечении времени не сброса сторожевого таймера- он сбрасывается, но не перезагружается.

В последнем абзаце говорится, что: "

Однако в загрузчике Optiboot я не нашел ничего похожего (если Я ошибаюсь, поправьте меня, пожалуйста!), используемый Arduino UNO и другими новыми платами. Такое впечатление, что этой проверкой они пожертвовали ради размера. Так что, это возможно, что сторожевой таймер будет включен после сброса, поэтому - если вы установите слишком низкое значение, ваша плата может никогда не выйти из загрузчика этап. Итак, чтобы всегда быть в безопасности, установите сторожевой таймер на более длительное время. периоды (2S и более).

Поэтому я пробовал 8 секунд, но результат тот же.

Что не так?

EDIT1:

#include <avr/wdt.h>
int k=1;
void setup() {
  Serial.begin(9600);
  wdt_enable(WDTO_8S);
}
void loop() {
  // делаем что-то здесь
  k++;
  wdt_reset();
  Serial.println(1000 * k);
  delay(1000 * k);

}

, 👍1

Обсуждение

Опишите пожалуйста "сбрасывает, но не перезагружается". Что происходит? Что не так? Попробуйте раздел 11.8 таблицы данных Atmega328p, в которой описаны режимы работы сторожевого таймера. Вам может понадобиться дополнительная настройка, чтобы получить желаемый результат., @JRobert

Опубликуйте **фактический тестовый код**, который вы используете. Связанная страница показывает только код, который не должен сбрасываться, если только «сделать что-то здесь» не займет слишком много времени. (Отредактируйте свой вопрос, чтобы сделать это)., @Nick Gammon

@NickGammon добавил, @Guy . D

Как сказал @JRobert, что вы подразумеваете под «сбрасывается, но не перезагружается»? Вы имеете в виду сброс сторожевого таймера или процессора? Если процессор перезагружается, он перезагружается., @Nick Gammon


5 ответов


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

3

"старый" загрузчик Nano не сбрасывает флаг Watchdog, и, пока загрузчик ожидает загрузки, плата перезагружается.

прошить "новый" загрузчик в Nano

В IDE 1.8.6 вы можете выбрать версию Nano в меню "Инструменты". Это «новый» загрузчик, если вы выберете «Atmega328p», и «старый», если вы выберете «Atmega328p (старый загрузчик)». Если вы вызовете «Записать загрузчик», он будет использовать загрузчик для выбранной опции.

,

Не могли бы вы сослаться?, @Guy . D

как записать загрузчик? вам нужен программатор или другой Arduino. https://www.arduino.cc/en/Tutorial/ArduinoISP, @Juraj

где взять этот "НОВЫЙ" загрузчик?, @Guy . D

я расширил ответ, @Juraj

Полный процесс записи загрузчика описан здесь: https://docs.arduino.cc/built-in-examples/arduino-isp/ArduinoISP. Приведенный выше ответ является кратким и предполагает, что программист готов подключиться к целевому «Нано»., @6v6gt


1

Это работает на Uno R3.

Скетч перезапускается каждые 4 секунды, когда wdt_reset() закомментирован.

Скопируйте код и попробуйте.

  #include <avr/wdt.h>

  void setup() {
    pinMode(13,OUTPUT);
    digitalWrite(13,LOW);

    delay(50);
    digitalWrite(13,HIGH);    // мигать светодиодом, чтобы определить, когда работает setup()
    delay(50);
    digitalWrite(13,LOW);
    delay(50);
    digitalWrite(13,HIGH);
    delay(50);
    digitalWrite(13,LOW);
    delay(50);
    digitalWrite(13,HIGH);
    delay(50);
    digitalWrite(13,LOW);
    delay(50);

    wdt_enable(WDTO_4S);

  }
  void loop() {
    digitalWrite(13,HIGH);
    delay(500);
    digitalWrite(13,LOW);
    delay(500);
    //wdt_reset();
   }
,

привет- тот же эффект ... возможно, Уно и Нано ведут себя по-разному?, @Guy . D

@Guy.D: Нам все еще нужно знать, что вы видите, и что вместо этого произойдет, как вы ожидали., @JRobert

@JRobert Я опишу, что я вижу: код работает нормально до тех пор, пока wdt не сбрасывается (что я делаю специально). После этого светодиоды на плате начинают мерцать без остановки, и данные перестают выводиться на последовательный монитор (эту часть я называю сбросом). Только после отключения питания плата снова загружается. Если бы я не выключил питание, это мерцающее состояние сохранялось бы вечно., @Guy . D

это не имеет смысла .... код, который я разместил, мигает светодиодами во время установки (), но нет последовательного кода ввода-вывода ..... похоже, что вы не загружаете новый скетч в Arduino, просто перезапуск старого скетча, @jsotola


0

После этого светодиоды на плате начинают непрерывно мерцать, а данные прекращаются. размещение на последовательном мониторе

Обязательно прочитайте техническое описание модели 328p, раздел 11.8. Есть несколько режимов работы - может прерываться; перезагрузить; или оба. Даже если он сбрасывается, он не перезагружает исходные данные ОЗУ, поэтому, например, строка 2 int k=1; выглядит как исполняемый оператор, но является инициализатором и не действует при сбросе, и k сохраняет свое текущее значение. Вероятно, есть и другие подобные аномалии, возникающие при срабатывании WDT.

Возможно, вам не нужно понимать WDT до последнего контрольного бита, но обязательно убедитесь, что вы используете его в том режиме, в котором хотите работать. Вероятно, во время тестирования будет удобно иметь небольшой скетч, который просто отключает сторожевой таймер, чтобы вы могли быстро вернуть Arduino для следующего теста.

,

1

Я заставил WDT работать в моем Nano со старым загрузчиком, используя этот код из старого сообщения на Форум Arduino.

Код добавляется после wdt_reset();

  //сбросить сторожевой таймер
  wdt_reset();
  //настраиваем прерывание WDT
  WDTCSR = (1 << WDCE) | (1 << WDE);
  //Запускаем сторожевой таймер с 4-секундным прескалером
  WDTCSR = (1 << WDIE) | (1 << WDE) | (1 << WDP3) | (1 << WDP0);
,

истинная проблема заключается в том, что интервалы wdt короче, чем время, в течение которого загрузчик ожидает загрузки, @Juraj


0

Проблема может заключаться в том, что после перезагрузки 328 по умолчанию устанавливает время сторожевого таймера 16 мс. WDP3 = 0, WDP2 = 0, WDP1 = 0, WDP0 = 0, поэтому, когда он сбрасывает и запускает вашу программу с начала вашего кода, она никогда не уходит слишком далеко. Я написал очень короткую программу восстановления, которая просто вызывает noInterrupts(); и загружайте его сразу после выключения/включения питания. Затем вы можете загрузить новую программу, которая не использует сторожевой таймер.

,