Watchog в Arduino Pro Micro
- Войдите на сайт для отправки комментариев
Здравствуйте! Прошу совета знатоков.
Возникло желание применить ардуину для считывания данных с одного прибора.
Имеется плата Arduino Pro Micro.
Алгоритм приёма данных простой. Микроконтроллер ардуины периодически опрашивает линию строба данных и при появлении строба принимает байт с шины данных и пересылает его в компьютер по каналу USB.
Естественно, следует предусмотреть выход из цикла опроса, если строб не появляется за заданное время. Думал осуществить выход на начало программы с испольэованием сторожевого таймера, но встретились затруднения.
Для пробы взял такой скетч (заимствовано с сайта https://uscr.ru/arduino-watchdog-bootloop-i-proshivka-zagruzchika-optiboot/, с незначительными изменениями):
// взято отсюда: https://uscr.ru/arduino-watchdog-bootloop-i-proshivka-zagruzchika-optiboot/ #include <avr/wdt.h> void setup() { wdt_disable(); // бесполезная строка, до которой не доходит выполнение при bootloop pinMode(17, OUTPUT); // initialize digital pin 17 (RXLED) as an output pinMode( 7, OUTPUT); pinMode( 4, INPUT_PULLUP); pinMode( 6, INPUT_PULLUP); pinMode(18, INPUT_PULLUP); pinMode(19, INPUT_PULLUP); pinMode(20, INPUT_PULLUP); pinMode(21, INPUT_PULLUP); pinMode(10, INPUT_PULLUP); pinMode(14, INPUT_PULLUP); pinMode(16, INPUT_PULLUP); pinMode(15, INPUT_PULLUP); pinMode( 1, INPUT_PULLUP); pinMode( 0, INPUT_PULLUP); pinMode( 2, INPUT_PULLUP); pinMode( 3, INPUT_PULLUP); pinMode( 5, INPUT_PULLUP); pinMode( 8, INPUT_PULLUP); pinMode( 9, INPUT_PULLUP); delay(5000); // Задержка, чтобы было время перепрошить устройство в случае bootloop Serial.begin(9600); Serial.println("Setup.."); wdt_enable (WDTO_8S); // Для тестов не рекомендуется устанавливать значение менее 8 сек. Serial.println("Watchdog enabled."); } int timer = 0; void loop(){ // Каждую секунду мигаем светодиодом и значение счетчика пишем в Serial if(!(millis()%1000)){ timer++; Serial.println(timer); digitalWrite(17, digitalRead(17)==1?0:1); delay(1); } // wdt_reset(); }
В результате: после подачи питания (втыканием ардуины в разъём USB компьютера) всё работает, периодически происходит перезагрузка программы по watchdog'у. Стоит включить монитор порта (ардуинский либо гипертерминал) - watchdog пропадает.
Что можно сделать?
А откуда видно, что ватчдог работает?
А откуда видно, что ватчдог работает?
Дак Ардуина гавкает же. Коротко и страшно.
А откуда видно, что ватчдог работает?
Дак Ардуина гавкает же. Коротко и страшно.
А!!!
Я для проверки поддержки ватчдога использую этот скетч (для нано)
Когда watchdog не работает - светодиод мигает периодически, когда работает - пачками. На глаз - в соответствии с ожидаемым.
а в чем смысл этого кода? вроде в первом посте заявлялось. что ардуина должна перегружаться при отсуствии входящих импульсов. А в коде - перезагрузка без вариантов, какждые 8 секунд.
ИМХО, вы что-то другое пытались сделать, но у вас явно не вышло.
Когда watchdog не работает - светодиод мигает периодически, когда работает - пачками. На глаз - в соответствии с ожидаемым.
интересно, а с чего мигание пачками является "ожидаемым"? логику работы этого кода можете словами обьяснить?
Микроконтроллер ардуины периодически опрашивает линию строба данных и при появлении строба принимает байт с шины данных и пересылает его в компьютер по каналу USB.
Естественно, следует предусмотреть выход из цикла опроса, если строб не появляется за заданное время.
В смысле выход из цикла опроса? Вы же написали: периодически опрашивает линию строба, есть данные - принимает байт, нет - ну и нет. Зачем wdt?
Зачем wdt?
А вдруг зависла (С)
В смысле выход из цикла опроса? Вы же написали: периодически опрашивает линию строба, есть данные - принимает байт, нет - ну и нет. Зачем wdt?
думаю, это продвинутый вариант вопроса "Помогите выйти из цикла while (или for)", которые тут периодически возникают.
Автор пишет блокирующий цикл, а потом не знает, как выполнять остальной код программы :) А этот ТС продвинутый - догадался wdt приспособить для выхода из цикла.
Зачем wdt?
А вдруг зависла (С)
вам не нравится вачдог, да вы его готовить не умеете...
PS москвичи из СМУ радиострой сожрали у нас всех собак еже что, умели готовить )))
Строб короткий, и кроме проверки его состояния, в цикле ничего сделать не удаётся. Если строб появился - выход на продолжение программы, если нет - выход только по прерыванию.
При подключенном USB с поднятым CDC драйвером на стороне хоста (сиречь "открытым монитором" ;) ), каждое прерываение USB, а хост их рождает регулярно, проверяя "жив ли пациент", производит ресет таймера вочдога. Если это тебе мешает - меняй логику программы или выводи диагностику не через USB.
Если строб появился - выход на продолжение программы, если нет - выход только по прерыванию.
Так если строб не появился и мы перезагрузили микроконтроллер, мы же опять вернемся в этот цикл, не?
А этот короткий строб не появится как раз когда мы решили перезагрузиться?
Когда watchdog работает, программа с периодом 8 с уходит на перезапуск, при этом в миганиях появляется дополнительно 5-секундная пауза (оператор delay(5000) в процедуре setup()).
Мы, конечно, вернёмся к циклу опроса, но прежде, например, можем сообщить что-нибудь компьютеру...
И все же я не вижу необходмости в wdt. Ждете внешний сигнал? - задействуйте прерывания. А в свободное время общайтесь с компьютером. Рассматривали такой вариант?
ширина шины данных какова - раз, строб отдельная линия? - два, может проще через прерывание ловить строб и выполнять опрос шины данных?
При подключенном USB с поднятым CDC драйвером на стороне хоста (сиречь "открытым монитором" ;) ), каждое прерываение USB, а хост их рождает регулярно, проверяя "жив ли пациент", производит ресет таймера вочдога. Если это тебе мешает - меняй логику программы или выводи диагностику не через USB.
Выходит, прерывания от USB начинают поступать, когда я запускаю терминал? А при выходе из терминала прерывания будут продолжаться? Ардуна-то и после закрытия терминала продолжает работать так, будто сторожевой таймер отключился...
ширина шины данных какова - раз, строб отдельная линия? - два, может проще через прерывание ловить строб и выполнять опрос шины данных?
Шина данных - 4 разряда.
На самом деле стробов - 10 линий (выше я несколько упростил задачу), но мы всегда знаем, какую линию опрашивать, и на другие не обращаем внимания. Прерыванием опрашивать дольше, чем программным опросом, да и десять источников прерываний, кажется, не осуществить...
При подключенном USB с поднятым CDC драйвером на стороне хоста (сиречь "открытым монитором" ;) ), каждое прерываение USB, а хост их рождает регулярно, проверяя "жив ли пациент", производит ресет таймера вочдога. Если это тебе мешает - меняй логику программы или выводи диагностику не через USB.
Не в курсе дел CDC и хоста, может там и есть прерывания, но о каком сбросе WDT идет речь?
Строб короткий, и кроме проверки его состояния, в цикле ничего сделать не удаётся. Если строб появился - выход на продолжение программы, если нет - выход только по прерыванию.
может вы пример своего кода выложите? Что-то мне кажется. что вариантов тут только два - либо вы строб проверяете неправильно, либо быстродействия камня тупо не хвтает на задачу и надо брать более быстрый МК
При подключенном USB с поднятым CDC драйвером на стороне хоста (сиречь "открытым монитором" ;) ), каждое прерываение USB, а хост их рождает регулярно, проверяя "жив ли пациент", производит ресет таймера вочдога. Если это тебе мешает - меняй логику программы или выводи диагностику не через USB.
Не в курсе дел CDC и хоста, может там и есть прерывания, но о каком сбросе WDT идет речь?
wdt_reset();
Это функция такая ;)). Она использована в CDC.cpp в CDC_Setup(), которая вызывается ...и так далее... в итоге в ISR(USB_COM_vect). Авторы взводят свой таймер на 120мс, но от этого ресетится сам вочдог таймер, так как в контроллере он один. Настройки они потом возвращают, а толку то? Все ж исходники открыты - сиди-изучай-радуйся! ;)))
может вы пример своего кода выложите? Что-то мне кажется. что вариантов тут только два - либо вы строб проверяете неправильно, либо быстродействия камня тупо не хвтает на задачу и надо брать более быстрый МК
Проблема возникает при использовании Serial, так?
А Вы не пробовали не насиловать его пины? Если убрать строки №№21-22, ничего не меняется?
у ардуины прерывание аппаратное, не может оно не ловить, там же триггер взведён
Может не доходить до него.
Может не доходить до него.
то-есть аппаратное прерывание реально может не отработать?
Ну, например, если МК сам по себе перегружается каждую секунду, как у него может отработать 8-секундный вочдог?
Ну, например, если МК сам по себе перегружается каждую секунду, как у него может отработать 8-секундный вочдог?
я о другом, ловить строб не программно, а по человечески, через прерывание
Ой, да мы тогда вообще о разном. Я даже не знаю о каком стробе речь :(((
Ой, да мы тогда вообще о разном. Я даже не знаю о каком стробе речь :(((
Строки 9 и 10 его скетча, где он программно ловит строб, там всё равно поймать с длительностью лучше 0,1 микросекунды не удастся
Проблема возникает при использовании Serial, так?
А Вы не пробовали не насиловать его пины? Если убрать строки №№21-22, ничего не меняется?
Не вполне понимаю вопрос. Вывод по оператору Serial происходит же через интерфейс USB, и выводы 0 и 1 для этого не задействованы.
Проверить смогу только завтра.
Не вполне понимаю вопрос. Вывод по оператору Serial происходит же через интерфейс USB, и выводы 0 и 1 для этого не задействованы.
на МК Атмега нет интерфейса USB. Он делается сторонней микросхемой - преобразователем, выводы которой подключены к ногам 0 и 1 МК. Так что можно сказать. что USB и 0 и 1 - это одно и то же.
У Микро есть - там ATmega32u4.
У Микро есть - там ATmega32u4.
ну значит не угадал
У Микро есть - там ATmega32u4.
ну значит не угадал
Дракула просто так постил разве )))
Могу, конечно, ошибаться, т.к. микры под рукой нет, но судя вот по этой схеме, как раз задействованы. USB работает черезе пины контроллера 3 и 4, они же D1 и D0, они же TX и RX и они же D- и D+ для USB. Т.е. если эта схема верна, то пины 0 и 1 как раз используются в полный рост.
Шина данных - 4 разряда.
На самом деле стробов - 10 линий (выше я несколько упростил задачу), но мы всегда знаем, какую линию опрашивать, и на другие не обращаем внимания. Прерыванием опрашивать дольше, чем программным опросом, да и десять источников прерываний, кажется, не осуществить...
Хотел было сказать, что двух прерываний PCINT хватит для отслеживания 10 линий, но, блин, у вас Micro. У нее один PCINT. Выбор этой ардуинки чем-то обоснован?
Да, при использовании прерываний реакция на строб будет медленнее чем при опросе в цикле. Тут нужно знать длительности импульсов чтобы судить, можете их привести?
И я все еще не понимаю назначения wdt. Из-за короткого строба замутили цикл опроса на ассемблере,чтобы не пропустить данные. И вдруг на тебе, сбрасываем МК каждые N секунд.
Выбор этой ардуинки чем-то обоснован?
Дак в первом же посте: "Имеется плата Arduino Pro Micro".
Шина данных - 4 разряда.
На самом деле стробов - 10 линий (выше я несколько упростил задачу), но мы всегда знаем, какую линию опрашивать, и на другие не обращаем внимания. Прерыванием опрашивать дольше, чем программным опросом, да и десять источников прерываний, кажется, не осуществить...
Хотел было сказать, что двух прерываний PCINT хватит для отслеживания 10 линий, но, блин, у вас Micro. У нее один PCINT. Выбор этой ардуинки чем-то обоснован?
НЕА! У неё 4 INT и 8 PCINT
НЕА! У неё 4 INT и 8 PCINT
Я о том, что прерывание PCINT одно, а источников-то 8, верно. Всё ж не 10. Делать часть на INT, часть на PCINT уже различная обработка получается, хотелось бы универсально.
НЕА! У неё 4 INT и 8 PCINT
Я о том, что прерывание PCINT одно, а источников-то 8, верно. Всё ж не 10. Делать часть на INT, часть на PCINT уже различная обработка получается, хотелось бы универсально.
так у него решено с обработкой с какой из 10 линий приходит строб, вроде как...
Я тоже за аппаратное решение средствами INT
Выбор этой ардуинки чем-то обоснован?
Дак в первом же посте: "Имеется плата Arduino Pro Micro".
Что не исключает наличие у ТС других плат. Поэтому хотелось бы услышать ответ от него.
Я бы при наличии той же УНО использовал все-таки ее из-за трех прерываний PCINT.
Что не исключает наличие у ТС других плат. Поэтому хотелось бы услышать ответ от него.
Других плат нет. Pro Micro показалась на первый взгляд подходящей для данной задачи. В одном флаконе тебе и микроконтроллер, и питание, и интерфейс USB, и "облегчённое" программирование... Только корпус приделать да разъём подпаять. Выходит не всё так просто...
P.S. А может знает кто верный способ выйти из прерывания не в точку вызова, а на произвольно заданный адрес? Как вариант - на начало программы. Тогда можно было бы выходить из бесконечного цикла по таймеру. Или воэложить проверку таймаута на компьютер, принимающий данные, и при отсутствии таковых пусть он пошлёт ардуине какой-нибудь символ, отчего возникнет прерывание и будут выполнены действия по приведению устройств в исходное состояние...
(Мечтательно...) Вот был, к примеру, в фортране оператор RETURN m - возврат из подпрограммы на метку m...
Это по нашему, создать проблему и героически её преодолевать )))
(Мечтательно...) Вот был, к примеру, в фортране оператор RETURN m - возврат из подпрограммы на метку m...
Здесь есть почти полный аналог, только ... из прерывания ... надеюсь, Вы знаете, что делаете, и знаете, как это правильно делать. Гуглите по словам setjmp и longjmp.
Вы заметили мой пост #37? Проверили?
Могу, конечно, ошибаться, т.к. микры под рукой нет, но судя вот по этой схеме, как раз задействованы. USB работает черезе пины контроллера 3 и 4, они же D1 и D0, они же TX и RX и они же D- и D+ для USB. Т.е. если эта схема верна, то пины 0 и 1 как раз используются в полный рост.
Женя! Это не так. D0 и D1 это контакты 20 и 21 чипа. Ты, возможно, путаешь с 328ым чипом. У 32U4 usb - совершенно отдельные пины никак не связанные с UART. На общие контакты платы они отдельно от разъема USB не выводятся.
Вы заметили мой пост #37? Проверили?
Проверил - осталось как прежде.
Женя! Ты, возможно, путаешь
Вполне вероятно, я сразу предупредил, что могу ошибаться.
А что не так со схемой, на которую я ссылаюсь? С этого сайта? Я её неверно прочитал или она неверна?
Женя! Ты, возможно, путаешь
Вполне вероятно, я сразу предупредил, что могу ошибаться.
А что не так со схемой, на которую я ссылаюсь? С этого сайта? Я её неверно прочитал или она неверна?
не так прочитал ;)) она верна... не расстраивайся!