Watchdog или как подружить ардуино со сторожевым псом

Emeljanowich
Emeljanowich аватар
Offline
Зарегистрирован: 30.04.2015

Здравствуйте друзья.

Сделал я ответственный проект и появилось у меня необходимость использовать защиту от зависания. В процессе отладки программы и настройки ИМ я единожды заметил зависание МК. Дабы этого не повторилось установил на свою Pro mini Watchdog. К сожалению в этом процессе имеются подводные камни, о которых я сейчас расскажу.

За основу я взял материал из этого сайта:  https://geektimes.ru/post/255800/ . Но там не совсем точно и понятно описан процесс лечения ардуино. И делается это следующим образом:

1. Открываем среду ардуино и далее Файл - Настройки и в строчку Boards Manadger копируем ссылку https://github.com/Optiboot/optiboot/releases/download/v6.2/package_optiboot_optiboot-additional_index.json

2. Далее Инструменты - Платы - Менеджер плат, листаем в низ и там находим:

Устанавливаем данное преложение.

3. После чего в меню Платы появляются дополнительные пункты и названия их начинаются со слов Optiboot.

4. Далее подключаем пациента для прошивки загрузчика через ISP порт. Этот процесс детально рассмотрен, повторять не буду.

5. Прошиваем загрузчик, предварительно выбрав соответствующий контроллер:

6. После замены загрузчика, МК полность готов для работы с WatchdogОМ) Единственно, при прошивке обычным способом нужно указывать ту плату, чей загрузчик вы в неё прошивали, т.е. в моем случае это уже не "Pro mini" а "Optiboot on 32-pin cpus " в остальном все аналогично.

Надеюсь был полезен! Удачи! :) 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Emeljanowich, молодец! Но можно было просто залить загрузчик от Уно :)

Short Circuit
Short Circuit аватар
Offline
Зарегистрирован: 17.05.2015

в про-мини  такого нету как в уно?

bwn
Offline
Зарегистрирован: 25.08.2014

Short Circuit пишет:

в про-мини  такого нету как в уно?

Зальете и будет.)))) Смотрите, на что в IDE откликается.

Short Circuit
Short Circuit аватар
Offline
Зарегистрирован: 17.05.2015

нет, в смысле в пршивке про-мини - вочдога нет?

Emeljanowich
Emeljanowich аватар
Offline
Зарегистрирован: 30.04.2015

Watchdog есть, но он работает не корректно. Прочитайте статью по ссылке в первом посте.

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Здравствуйте.

Делаю всё вышеуказанным способом.

Программатор (uno) прошила Arduino ISP

К программатору подключаю свою плату nano

.

Загрузка успешно авершена

Заливаю скетч

#include <avr/wdt.h>
 
void setup() {
  wdt_disable(); // бесполезная строка до которой не доходит выполнение при bootloop
  Serial.begin(9600);
  Serial.println("Setup..");
  
  Serial.println("Wait 5 sec..");
  delay(5000); // Задержка, чтобы было время перепрошить устройство в случае bootloop
  wdt_enable (WDTO_8S); // Для тестов не рекомендуется устанавливать значение менее 8 сек.
  Serial.println("Watchdog enabled.");
}
 
int timer = 0;
 
void loop(){
  // Каждую секунду мигаем светодиодом и значение счетчика пишем в Serial
  if(!(millis()%1000)){
    timer++;
    Serial.println(timer);
    digitalWrite(13, digitalRead(13)==1?0:1); delay(1);
  }
//  wdt_reset();
}

Ардуина зависает. Что я не так сделала?

b707
Offline
Зарегистрирован: 26.05.2017

Irinka пишет:

Ардуина зависает. Что я не так сделала?

кто ж знает, что вы не так сделали? - по описанию все должно работать.

Хотя я вон на ватчдог неделю потратил только что :)

А "зависает" - это как выглядит? Вообще должно не зависать, а сваливаться в бесконечный ресет

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

5. Прошиваем загрузчик, предварительно выбрав соответствующий контроллер:

Я на этом этапе выбираю Ардуино Нано, верно?

b707
Offline
Зарегистрирован: 26.05.2017

Irinka пишет:

5. Прошиваем загрузчик, предварительно выбрав соответствующий контроллер:

Я на этом этапе выбираю Ардуино Нано, верно?

неверно, нужно выбирать Уно. В загрузчике Нано нет поддержки ватчдога

Сорри, был невнимателен и не увидел на картинке, что вы Нано выбираете. Выбирайте Уно и все получится.

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Благодарю. Работает.

Теперь при прошивке Nano нужно выбирать плату Uno

 

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Еще вопрос, wdt_reset(); лучше вызывать в LOOPe постоянно или сделать так

void loop(){
 if(!(millis()%5000)){
wdt_reset();
}

  if(!(millis()%1000)){
    timer++;
    Serial.println(timer);
    digitalWrite(13, digitalRead(13)==1?0:1); delay(1);
}
}

 

b707
Offline
Зарегистрирован: 26.05.2017

я бы без всяких условий вызывал. Если ЛУП длинный, иногда даже по несколько раз вызывают в разных местах.

wdt_reset() - это одна единственная запись в регистр ватчдога, контроллер он не перегрузит.

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Я не поняла вторую Вашу строчку, текст "контроллер он не перегрузит."

wdt_reset() сбрасывает сторожевой таймер, чтобы не произошла перезагрузка, так?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Перво наперво найди и убей автора вот этого 

 if(!(millis()%5000)){

и переделай правильно. 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Irinka пишет:

Еще вопрос, wdt_reset(); лучше вызывать в LOOPe постоянно или сделать так

Это транслируется в 1 инструкцию процессора. вызывать можно какугодно

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

DetSimen пишет:

Перво наперво найди и убей автора вот этого 

 if(!(millis()%5000)){

и переделай правильно. 

А почему только жэтого?

А как же?

if(!(millis()%1000)){

 

b707
Offline
Зарегистрирован: 26.05.2017

Irinka пишет:

А почему только жэтого?

А как же?

if(!(millis()%1000)){

 

И этого тоже :)

Фразу "контроллер он не перегрузит" надо понимать как "он не слишком сильно загрузит контроллер" , а не отсутствие ресета :)

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Цитата:
Фразу "контроллер он не перегрузит" надо понимать как "он не слишком сильно загрузит контроллер" , а не отсутствие ресета :)

Виновата...прочитала не ПЕРЕзагрузит

Буду вызыввать в loop-e)))

if(!(millis()%1000)){

if(!(millis()%5000)){

#include <avr/wdt.h>

unsigned long currentMillis;
unsigned long previousMillis = 0;
unsigned long previous1Millis = 0;
int timer = 0;

void setup() {
wdt_disable(); // бесполезная строка до которой не доходит выполнение при bootloop
Serial.begin(9600);
Serial.println("Setup..");
Serial.println("Wait 5 sec..");
delay(5000); // Задержка, чтобы было время перепрошить устройство в случае bootloop
wdt_enable (WDTO_8S); // Для тестов не рекомендуется устанавливать значение менее 8 сек.
Serial.println("Watchdog enabled.");
}

void loop() {
currentMillis = millis();

if (currentMillis - previous1Millis >= 5000) { 
wdt_reset();
previous1Millis = currentMillis;
}


if (currentMillis - previousMillis >= 1000) { 
timer++;
Serial.println(timer);
previousMillis = currentMillis;
}

}

Так?)))

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

можно и так. 

b707
Offline
Зарегистрирован: 26.05.2017

Irinka. мы ж вам оба с Дедом говорим, что можно вызывать wdt_reset() без всяких миллис. Из строк 21-24 оставьте только 22

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

b707 пишет:

Irinka. мы ж вам оба с Дедом говорим, что можно вызывать wdt_reset() без всяких миллис. Из строк 21-24 оставьте только 22

А я и напсиала:

Цитата:

Буду вызыввать в loop-e)))

Это я к тому, что вы сказали убрать if(!(millis()%1000)){ и if(!(millis()%5000)){

вот и спросила, будет правильно как выше код написала

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

 wdt_disable(); 

нужна ли эта строка?

b707
Offline
Зарегистрирован: 26.05.2017

Irinka пишет:

 wdt_disable(); 

нужна ли эта строка?

по документации, прежде чем менять параметр ватчдога, нужно выполнить wdt_disable();

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Спасибо

electro216
Offline
Зарегистрирован: 23.06.2016

Здравствуйте, подскажите как использовать watchdog? Я собираю свою плату на базе atmega328p и прошиваю ее под Arduino pro mini с 3.3 вольт с помощью программатора. 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

electro216 пишет:

Здравствуйте, подскажите как использовать watchdog? Я собираю свою плату на базе atmega328p и прошиваю ее под Arduino pro mini с 3.3 вольт с помощью программатора. 

и с 2016 года ни разу не потребовался WDT ? завидую....

в setup прописываете wdt_enable(WDTO_4S); - это 4 секунды

в loop прописываете wdt_reset();

bwn
Offline
Зарегистрирован: 25.08.2014

andycat пишет:

в loop прописываете wdt_reset();

Жестко Вы так. Где нибудь while запихнет и будет за бобиком гоняться.)))

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

bwn пишет:

andycat пишет:

в loop прописываете wdt_reset();

Жестко Вы так. Где нибудь while запихнет и будет за бобиком гоняться.)))

ну это будет не мои проблемы, ТС спросил как использовать, я и написал, а то что мозг надо включать - это по умолчанию требование.

Опять же не знаю как другие, а я сначала полностью код до рабочего состояния довожу, а только потом добавляю WDT на всякий случай.

bwn
Offline
Зарегистрирован: 25.08.2014

To electro216, если будете на 8мГц перешивать, здесь загрузчик, да и вообще ту тему почитайте.

electro216
Offline
Зарегистрирован: 23.06.2016

andycat пишет:

electro216 пишет:

Здравствуйте, подскажите как использовать watchdog? Я собираю свою плату на базе atmega328p и прошиваю ее под Arduino pro mini с 3.3 вольт с помощью программатора. 

и с 2016 года ни разу не потребовался WDT ? завидую....

в setup прописываете wdt_enable(WDTO_4S); - это 4 секунды

в loop прописываете wdt_reset();

 

Спасибо за ответ. В общем без bootloader`a не нужно будет морочить голову, а прописать код как вы написали? Мне с ним еще не приходилось работать. Меня смутило, что в bootloader`e функция стоит wdt_disable(), а потом в setup активируем wdt_enable(WDTO_4S). 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Никогда bootloader не смотрел, так что не скажу.
А вообще логично, перед любым изменением WDT его необходимо disable

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

В 29 сообщении тема - к прочтению обязательно, иначе может не заработать

electro216
Offline
Зарегистрирован: 23.06.2016

Вот именно у меня не используется загрузчик, у меня такая конфигурация atmega328p + кварц 8Мгц птание 3.3 вольт. Прошиваю программатором из Arduino IDE (программатор из другой arduino :) ).

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

И что это меняет? Я аналогично шью через usbasp и это не отменяет прочтения литературы чтоб WDT работал

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Здравствуйте товарищи.

Загрузила в Нано код проверки WDT

#include <avr/wdt.h>
 
void setup() {
  wdt_disable(); // бесполезная строка до которой не доходит выполнение при bootloop
  Serial.begin(9600);
  Serial.println("Setup..");
  
  Serial.println("Wait 5 sec..");
  delay(5000); // Задержка, чтобы было время перепрошить устройство в случае bootloop
  wdt_enable (WDTO_8S); // Для тестов не рекомендуется устанавливать значение менее 8 сек.
  Serial.println("Watchdog enabled.");
}
 
int timer = 0;
 
void loop(){
  // Каждую секунду мигаем светодиодом и значение счетчика пишем в Serial
  if(!(millis()%1000)){
    timer++;
    Serial.println(timer);
    digitalWrite(13, digitalRead(13)==1?0:1); delay(1);
  }
//  wdt_reset();
}

Теперь нано ниначто не реагирует, не могу зилить ни один скетч.

Горит POW и моргает L

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Вопрос решен, помогла заливка загрузчика.

Еще вопрос, можно прошивать не через разъем SPI&

Не так:

А так:

Emeljanowich
Emeljanowich аватар
Offline
Зарегистрирован: 30.04.2015

Возможно, только 10 пин unо к контакту reset nano

bwn
Offline
Зарегистрирован: 25.08.2014

Irinka пишет:

Вопрос решен, помогла заливка загрузчика.

Еще вопрос, можно прошивать не через разъем SPI&

А на потом, купить переходник на СH340 (рублей 50-80), выводить наружу RX, TX, RESET и шить в свое удовольствие прямо в девайсе.

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Можно ссылку на переходник?)

sadman41
Offline
Зарегистрирован: 19.10.2016

Irinka пишет:

Можно ссылку на переходник?)

https://ru.aliexpress.com/store/product/CH340G-5V-USB-to-TTL-UART-Serial...

bwn
Offline
Зарегистрирован: 25.08.2014

Первый попавшийся. Если нет выхода RESET, проводок и конденсатор 0,1мкФ от линии DTR (вроде не ошибся).

sadman41
Offline
Зарегистрирован: 19.10.2016

У рободиновского точно есть ресет - сам пользуюсь таким.

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Ааа, такой купила. Спасибо.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

А какой загрузчик зашили, а то тут у меня аж два оказалось

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Всё как в инструкции в начале темы

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Получила две платы ардуино нано. 

На одну плату невозможно было залить скетч, помогла заливка загрузчика.

А вторую плату компьютер не видит, ком порт не определяется. (загрузчик залила через ардуино уно, всё нормально залилось).

Можно ли залить скетч через переходник BTE13-009B

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Либо иным спосбом)

sadman41
Offline
Зарегистрирован: 19.10.2016

USB-TTL переходник поможет, если в чипе есть загрузчик. Соединяете RX-TX-GND-RESET и, может быть VCC да и льёте штатным способом через ^U Arduino IDE. 

Если загрузчика нет - пишете его через ICSP и вторую ардуину (скетч Arduino ISP), а затем действуете как в первом абзаце.

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Т.е. загружаю в UNO скетч ArduinoISP

А дальше как?

sadman41
Offline
Зарегистрирован: 19.10.2016