Увы.. Работа Arduino Mega с сетевой картой оказалась не очень стабильной. Время от времени карта «зависает» и спасает только ресет всего устройства. Для того чтобы сделать «reset» есть два пути: 1) Подать на pin reset напряжение 2) Воспользоваться библиотекой /avr/wdt.h
Мы пойдем вторым путем..
//если давно не было подключения к интернету, думаем что контроллер завис и ресетим..
if ( millis ( ) > fail_timer ) <
ConsPrint ( «RESTART ARDUINO. » ) ;
wdt_enable ( WDTO_15MS ) ;
delay ( 1500 ) ;
Значения могут быть следующие:
WDTO_15MS
WDTO_30MS
WDTO_60MS
WDTO_120MS
WDTO_250MS
WDTO_500MS
WDTO_1S
WDTO_2S
WDTO_4S
WDTO_8S
,т.е. «назначаем рестарт через столько то времени». Но! Есть еще и возможность успеть сбросить таймер перезапуска : wdt_reset(); или вовсе отменить: wdt_disable();
Используя этот функционал мы например можем сделать следующую логику приложения:
запускаем таймер «ресет через 5 секунд»
Урок 4. Что такое Reset на Arduino (кнопка Reset и её назначение, единоразовое выполнение кода)
запускаем «опасный для зависания код»
если код выполнился — сбрасываем таймер, перезагрузки не будет
если код не выполнился — произойдет автоматическая перезагрузка arduino
ВКонтакте ( X )
Источник: xn--90acbu5aj5f.xn--p1ai
Как сбросить программу ардуино
После нажатия на кнопку RESET, а также по сигналу DTR микросхемы FT232R на плате Arduino Duemilanove или по сигналу на выводе D7 микросхемы ATmega8U2 платы Arduino Uno, управление передаётся загрузчику (bootloader) Arduino, расположенному в верхних 2 КБ памяти программ (Flash) (адрес 0x7800 для микроконтроллера ATmega328p). Загрузчик проверяет, есть ли связь с Arduino IDE, а затем передаёт управление по адресу 0x0000 памяти программ, где расположен код скетча.
Таким образом, чтобы перезагрузить Arduino программным способом (теплый рестарт или soft reset), достаточно добавить в скетч функцию программного сброса:
void softReset() asm volatile («jmp 0»); >
void(* softReset) (void) = 0;
Вызов в скетче этой функции приведёт к программному рестарту скетча Arduino.
Источник: 2150692.ru
Arduino.ru
Возможен ли программный ресет. По задумки 2 мк общаются друг с другом. После всех манипуляций мк№1 записывает данные во внешнюю память и посылает сообщение мк№2 о том что связь прекращается и о том чтобы мк№2 сосчитал данные со внешней память. Всё общение проходит нормально. Но когда мк№2 начинает считывать данные с памяти то он зависает.
Прочём при старте обоих мк они удачно считывают с памяти всё содержимое.
- Войдите на сайт для отправки комментариев
Ср, 18/04/2012 — 01:36
chervyachok
Arduino как освободить память. Не хватает памяти UNO NANO.
void(* resetFunc) (void) = 0; // Reset MC function resetFunc(); //вызов
- Войдите на сайт для отправки комментариев
Ср, 18/04/2012 — 11:18
ООО спасибо. Работает. Скажи пожалуйста откуда ты узнал про это? Я весь инет перерыл прежде чем написать суда! Может есть место где всё более детально описано про arduino? (кроме оф сайта)
- Войдите на сайт для отправки комментариев
Ср, 18/04/2012 — 22:43
Кстати да, если не трудно — объясните эту магию 🙂
Для людей не испорченных глубоким знанием C, что вообще происходит в этом коде?
- Войдите на сайт для отправки комментариев
Чт, 19/04/2012 — 03:25
chervyachok
На самом деле ето не настоящий резет а просто перевод стека в начало програмного кода (в нулевой адрес). Тоесть программа начинает исполнятся с самого начала, при етом не влияя на установки МК на момент исполнения. Например: Если у вас на момент исполнения был установлен какой то порт в «1» и в начале программы его значение не возвращается в «поумолчанию = 0» то после так званой «програмной перезагрузки» порт так и останеться с «1».
Если попроще то вот для визуальной демонстрации:
void(* resetFunc) (void) = 0; void setup() < pinMode(13, OUTPUT); Serial.begin(9600); >void loop() < delay(5000); digitalWrite(13, HIGH); delay(100); digitalWrite(13, LOW); delay(100); digitalWrite(13, HIGH); delay(100); if (Serial.available()>0) < digitalWrite(13, LOW); delay(500); digitalWrite(13, HIGH); resetFunc(); >else < digitalWrite(13, LOW); delay(1000); >>
если ничего не слать в порт то результатом будет двойное мигание светодиодом после продолжытельной паузы.
если же послать чтото, то перед перезагрузкой выход 13 установится в «1» и светодиод будет гореть даже после перезагрузки и до момента его го выключения (11й ряд).
Поетому используя даную функцию необходимо быть внимательным и заведомо устанавливать нужные значения.
Ну а если нужен самый настоящий резет то (наверно, в теории, хотя сам не пробовал) програмно прижымать пин Reset к земле другим пином.
- Войдите на сайт для отправки комментариев
Чт, 19/04/2012 — 03:37
chervyachok
LEVV2006 пишет:
весь инет перерыл прежде чем написать суда! Может есть место где всё более детально описано про arduino? (кроме оф сайта)
Кстати уже в сотый раз убедился что от правильно поставленого вопроса зависит возможность получения правильного ответа. Если погуглить «arduino reset function» то почти сразу наткнетесь на тоже и еще + несколько вариантов.
А я вот досихпор не могу правильно сформулировать вопрос дядюшке гуглю насчет следующего arduino.ru/forum/programmirovanie/udalenie-proshyvki-programnym-putem
- Войдите на сайт для отправки комментариев
Чт, 19/04/2012 — 07:40
chervyachok пишет:
А я вот досихпор не могу правильно сформулировать вопрос дядюшке гуглю насчет следующего arduino.ru/forum/programmirovanie/udalenie-proshyvki-programnym-putem
avr write flash memory или
«avr flash запись» в Яндексе — и DiHalt вам популярно объяснит, как записать что-нибудь поверх существующей программы.
- Войдите на сайт для отправки комментариев
Чт, 19/04/2012 — 08:12
chervyachok пишет:
Ну а если нужен самый настоящий резет то (наверно, в теории, хотя сам не пробовал) програмно прижымать пин Reset к земле другим пином.
ATMEL не советует делать это, поскольку метод не дает стабильных результатов.
подача сигнала на reset-ногу приводит к запуску цикла инициализации, НО — первым делом производится инициализация всех I/O-выводов в качестве входов. Низкий уровень на RESET при этом естественным образом пропадает — слишком рано для полноценной отработки процесса инициализации.
watchdog — для AVR это магическое слово (а по совместительству еще и таймер), позволяющее автоматически перезапустить МК в случае зависания программы (ну или целенаправленно — если возникает такое желание).
void reboot() < wdt_disable(); wdt_enable(WDTO_15MS); while (1) <>>
Однако, при «полноценном» ресете необходимо помнить, что он запустит и бутлоадер, который, в свою очередь, в определенных условиях может решить, что настал момент для перезаписи программы, и .
- Войдите на сайт для отправки комментариев
Пт, 20/04/2012 — 02:59
step962, у меня возникли некоторые вопросы, разЪясните, пожалуйста:
1. Для чего сначала отключаем затем включаем watchdog?
wdt_disable(); wdt_enable(WDTO_15MS);
2. По-умолчанию данный таймер отключен?
3. Играет ли какую-нибудь роль, что происходит в теле цикла? наприер:
void reboot() < wdt_disable(); wdt_enable(WDTO_15MS); while (1) < if(digitalRead(pin))else > >
pin в течении 15 мс меняется, произойдет сброс?
- Войдите на сайт для отправки комментариев
Пт, 20/04/2012 — 07:55
1. Возможно необязательно. Без wdt_disable не проверял. Но, поскольку ватчдог имеет три режима работы, могу предположить, что для корректного переключения этих режимов требуется отключение таймера на время проведения работ.
2. Соответствующие разделы в даташите (10.8-10.9 для ATmega328) не слишком большие. Недвусмысленного ответа на этот вопрос я там, однако, не нашел. Но в описании регистра WDTCSR сказано, что бит WDIE, ведающий разрешением прерывания от сторожевого таймера, по умолчанию сброшен. То есть, по крайней мере прерывание (а это два режима из трех возможных) замаскировано по умолчанию.
Для бита WDE, который разрешает системный ресет, в качестве значения по умолчанию указан х. Видимо, тут требуется также и значения каких-то фьюзов учитывать. Но для программ, сгенерированных из-под Arduino IDE, можно сказать, что таймер по умолчанию отключен, т.к. не нужно его сбрасывать.
3. Роль играет только своевременное выполнение инструкции сброса сторожевого таймера (макрос «wdt_reset()»). Если таковая не вызывается в течение времени, на которое настроен сторожевой таймер (от 15 мс до 8 с), то происходит сброс системы или генерация прерывания или прерывание+сброс системы — в зависимости от режима, в котором работает таймер. Так что
pin в течении 15 мс меняется, произойдет сброс?
pin в течении 15 мс меняется, произойдет сброс.
- Войдите на сайт для отправки комментариев
Втр, 01/05/2012 — 01:19
Кто-нибудь разоборался со сторожевым таймером? Может, кто-нибудь поделится готовым скетчем?
У меня следующая проблема: есть ардуина с датчиком и беспроводным модулем (эдакий беспроводной датчик). Система работает некоторое время (случайная величина, обычно несколько часов работает нормально, но потом вешается). Нажатие на кнопку RESET — полностью нормализует работу до следующего «зависона».
Как понимаю, сторожевой таймер — это «то, что доктор прописал». Логику действий понимаю так:
1. Деактивируем сторожевой таймер (в функции setup)
2. задаем значение сторожевому таймеру (setup) — даем значение времени, несколько большее длительности основного цикла.
3. активируем сторожевой таймер (setup)
4. сбрасываем сторожевой таймер (уже в функции loop)
соответственно, если программный сброс сторожевого таймера не произошел (из-за «зависания») — сторожевой таймер ребутнет контроллер и все пойдет заново.
P.S. прошу поправить, если неправильно понял и помогите с кодом (наверняка уже кто-то писал подобное).
- Войдите на сайт для отправки комментариев
Втр, 01/05/2012 — 02:50
По умолчанию он выключен. Когда мы его «активируем» (в setup) он начинает тикать, и увеличивать свой внутрений регистр. Когда он «переполнится» — происходит ресет (или вызывается указанная вами функция, как сконфигурите). Поэтому нужно его регулярно «обнолять». Где-нибудь в loop(). Говорить ему «все хорошо, скетч работает».
С какой скоростью он «тикает» — зависет от тактовой частоты и пред-делителей.
Вообщем сериал Lost смотрели? Помните там мужичек сидель годами в бункере и каждые несколько часов нажимал кнопку что-бы мир не возрвался? Сбрасывал таймер. Вот у нас тоже самое. «бомба» — это сторожевой таймер, мужичек — наш скетч. Разница только в том, что кнопку «начать отсчет заново» мы можем нажать когда хотим, а он мог только в последний момент 🙂
Конкретно как его конфигурировать (какие порты, какие биты за что отвечают) — читать даташит.
Ну или, как всегда, пытаться найти библиотеку где это уже сделали за нас.#include Читать можно тут http://tushev.org/articles/electronics/48-arduino-and-watchdog-timer
Вообщем скетч должен выглядеть примерно так:
ОСТОРОЖНО! ОН МОЖЕТ ПОЛОМАТЬ ЗАЛИВКУ НОВЫХ СКЕТЧЕЙ. Заблокировать вашу дуину. Дочитайте до конца.
#include int counter=0; void setup() < wdt_disable(); // запретили как можно скорее собаку, что-бы не уйти в бесконечный ребут Serial.begin(9600); Serial.println(«Starting. «); delay(1000); // что-бы четче видеть рестар скетча wdt_enable(WDTO_4S); // активировали таймер, каждые 4-ре секунды его нужно сбрасывать >void loop() < wdt_reset(); // говорим собаке что «В Багдаде все спокойно», начинается очередной отсчет 4-х секунд. Serial.println(counter); counter++; if(counter==5)< while(true)<>// создаем зависание, через 4 секунды должен произойти ресет, так как не вызывается wdt_reset(); > delay(500); >
К сожалению, арудино бутлоадеры имеют «большие проблемы» с этой собакой. При ресете она не деактивируется. Поэтому ее нужно побыстрому запретить в самом начале setup(). И рекомендуют ставить «отсчет» не меньше двух секунд, что-бы бутлоадер успел отработать до «очередной сработки» и скетч начал выполнятся. Иначе мы получаем бесконечный ребут и незвозможность заливать скетчи.
С этим имели проблему старые бутлоадеры, потом это «починили», а в свежих версиях arduino mega, как говорят в комментах (и мой опыт) — опять «поломали». Он начинает тикать «очень быстро» и даже не успевает дойти до setup()
Лечится через вырубание питания и зажатия ресета, подруб питания и отпускание ресета в момент заливки.
Но, естественно толку «в таком виде» — от него нет. Использовать — нельзя (по крайней мере на моей mega1280). Вроде есть фиксы бутлоадера для этого, но пока он мне не настолько нужен что-бы лезть в перешивку бутлоадера.
Так что «используйте преведенный скетч» на свой страх и риск. Лично у меня получается выводить плату из бесконечного ребута «легко», но гарантировать что так будет и на вашей плате — я не могу. Впрочем может у вас вообще не будет этого лока.
- Войдите на сайт для отправки комментариев
Источник: arduino.ru