как реализовать периодический wakeup из sleep mode?
- Войдите на сайт для отправки комментариев
Ср, 28/10/2015 - 12:42
всем привет.
второй день пытаюсь сообразить и на писать код, при котором arduino будет спать и раз в минуту будет просыпаться на заданный мной в некой константе период времени. пока нужно 5 секунд.
в эти 5 сек нужно выполнять некоторые операции по приему и передаче данных через радиоканал.
сейчас для режима sleep использую библиотеку LowPower, но у нее "можно" спать максимум 8 сек.
но даже с этим у меня проблемы разного рода..
void loop()
{
Serial.println("sleep");
delay(1000);
//driver.sleep();
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
...........
//мой полезный код
}
в приципе arduino засыпает, но такое впечатление, что мой код просто НЕ УСПЕВАЕТ выполнится, а программа опять начинает выполнять цикл с начала.
мне бы както привязать это к таймеру - чтобы мой код выполнялся не меньше чем указанное мной время.
но я не соображу как это сделать.
эти тайминги мне весь мозг выели уже.
я пока не догадался поставить этот delay(1000) после println - все не мог понять, почему же не выводится текст "sleep" на консоль.
потом понял, что для вывода нужно какое-то время, а ардуино "не ждет" и продолжает выполнять следующую инструкцию, а это как раз вход в режим сна, вот она и засыпает, и вывод не успевает напечататься.
так же?
тоже самое и с моим кодом приема-передачи скорее всего..
но там еще есть другой момент - синхронизация с другим устройством, поэтому мне нужен механизм который позволит задавать не время ожидания с помощью delay() (я так понял delay вообще лучше не использовать - он просто тормозит всю систему), а чтото вроде цикла while (не прошло 5 сек.)
тогда я смогу "поиграться" этим параметром времени и выбрать нужное окно для приема-передачи.
а все остальное время ардуина будет спать.
прошу совета и пример кода если можно..
спасибо
Эту библиотеку не знаю, все делаю ручками. Алоритм должен быть такой:
1. Программа выполняет требуемую работу.
2. Включает режим сна.
3. Уходит спать.
4. Просыпается через заданное время.
5. Отключает режим сна.
6. Переходит к пункту 1.
да, все так.
и используя библиотеку LowPower, чтобы уснуть на 8 сек нужно просто вызвать
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
но вот беда, в цикле loop() все происходит не совсем понятно для меня. чтото оченьбыстро выполняется, чтото нет,
похоже, что код для приема-передачи тоже "проскакивает" очень быстро и программа сразу на sleep переходит.
вот мне нужно в коде выделить для этой операции опеределенное количество времени.
но самое главное - это сделать вот эту часть алгоритма:
2. Включает режим сна.
3. Уходит спать.
4. Просыпается через заданное время.
5. Отключает режим сна.
как научить ее засыпать и просыпаться через заданное время?
я читал, что некоторые ардуино контроллеры при вызове режима сна могут становиться "кирпичами" и потом их надо какото перепрошивать, чтобы восстановить работоспособность.
поэтому и начал использовать библиотеку LowPower - она работает и проверена на моем устройстве - Anarduino+RF96(LoRa)
Вроде на длительные промежутки делали на DS3231. У нее есть выход будильника. Сам с прерываними не занимался, мысли вслух.
Ну а с интервалом работы - самое простое классика "мигаем светодиодом без delay()". Хотя без подтверждения о приеме это кривые костыли. ИМХО.
это на millis() которое? тоже думал в эту сторону.. но мне же еще надо засыпать и просыпаться раз в минуту. тут это не поможет..
разве по прерываниям бортового таймера такое не сделать?
Имеется в виду, что не заснет пока не отработан заданный интервал. 5-10-50 секунд.
А разбудить, в этой теме человек вроде прикрутил. У него правда период сна большой.
ага, вижу, что у него там модуль часов внешний. видимо без него, дольше чем на 8 сек не приспать дуину..
Пытаюсь понять - а зачем вам засыпать больше, чем на 8 секунд?
Проснулся и снова спать, и только на восьмой раз проснулся и что-то делаешь. В чем проблема?
Восемь секунд для мегагерцевого чипа - это и так дофига.
ну я думал что лучше уснуть на нужно время сразу, чем дергать его по 8 сек.
потребление же будет увеличиваться каждый раз когда он будет просыпаться.
Вообще то надо начать с того, что режимов сна у atmega328 несколько
нас может интересовать два - idle и powerdown
idle самый простой, в нем продолжают работать все таймеры, однако потребление остаётся высоким и толком такой режим батарею не экономит
режим powerdown лучшее что есть для экономии. Но в этом режиме все по максимуму отключено, проснуться из него можно только по двум событиям - внешние прерывания либо прерывание сторожевой собаки
внешние прерывания чтобы генератор периодически нужно какое то внешнее устройство. Выше упоминали ds3231, если оно есть в проекте, то можно настраивать будильники на точное время срабатывания и каждый раз их переводить вперёд. Тогда МК будет спать и минуты и часы, сколько надо
специально ставить ds3231 нет необходимости. Настраиваем собаку, у неё максимальная время как раз 8 секунд. используем счётчик чтобы насчитать столько раз по 8 секунд сколько нужно. Как только досчитали - делаем свою работу. Пока не досчитали - сразу спать. Считать можно в loop. Чтобы по переполнению счетчика собаки ардуино не перегружалась надо настроить обработчик прерывания для собаки, код можно оставить пустым
странно..
ипользуя
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
потребление около 3.9mA
а с собакой раза в два больше..
ну и похоже что две подряд строки:
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
заставляют спать дуину уже 16 сек. то, что надо.
странно..
ипользуя
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
потребление около 3.9mA
а с собакой раза в два больше..
Здесь вопрос в том, что реально эта библиотека делает. Я делаю без библиотеки, это совсем не сложно.
потребление микроконтроллера в режиме сна должно быть меньше 0.1 мкА. Все, что выше - повод задуматься над тем что ещё можно сделать. Ваши 3.9мА это очень много
на данный момент потребление 1.5mA и я пока успокоюсь на этом.
новая беда появилась - ардуина ресетится похоже.
у меня в setup() есть println который при старте выводит небольшой баннер-приветствие:
>>>>> server #2 init ok. [434MHz], 7 sens
так вот он же должен только один раз выводиться после включения.
а я вижу что он периодически появляется при работе Сервера:
думал кстати, что это термосенсоры потребляют
но отсоединял их и резистор для паразитного питания - все равно 1.1 - 1.5mA
Я тут статейку одну нагуглил про экономие энергии. http://inet-deal.mpa.ru/articles/arduino-003.html
Там самое минимальное потребление было 0,35 мкА, но при пробуждении из такой спячки скорее всего придется переинициализировать все устройства.
да, я давно видел тоже.
0.35uA он получает путем выключения ADC, что у меня тоже происходит через либу LowPower, ключ ADC_OFF:
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
но видимо мой мультиметр уже мешает - при питании ардуины от 3 вольт, амперметр в цепи приводит к каким-то глюкам, сам контроллер не работает, значения тока скачут постоянно..
и еще вопрос - если я буду питать девайс от аккумулятора 6V 7Ач то это же надо через Vin подключать, в таком случае код, который измеряет напряжение на Vcс не будет показывать реальное состояние батареи.. так ведь?
и еще вопрос - если я буду питать девайс от аккумулятора 6V 7Ач то это же надо через Vin подключать, в таком случае код, который измеряет напряжение на Vcс не будет показывать реальное состояние батареи.. так ведь?
через VIN лучше не подключать. Там стоит стабилизатор который сам сожрет 5-10ма. Лучше применить импульсный преобразователь на микросхеме с низким собственным потреблением
чтобы измерять напряжение на аккумуляторе надо плюсовую клемму подключить к аналоговому входу ардуины через резистивный делитель с коэффициентом 5/7.2в, т.е. Чтобы на ардуину не попадало более 5вольт
путем более внимательного чтения чужих примеров кода, удалось получить 43 микроА во время сна.
но это без термосенсоров. как только подаю питание на сенсоры - потребление возрастает до 0.2mA во время сна. ну это и логично вроде.. сенсоры питаются от источника питания, а не от ардуины.
чтото можно сделать в этом случае, для уменьшени потребления? как-то отключать цепь питания на сенсоры во время сна, и подключать ее когда МК проснется.
как-то отключать цепь питания на сенсоры во время сна, и подключать ее когда МК проснется.
Ключами на полевиках например.
Я запитал 18В20 от ноги контроллера и после снятия показаний переключаю вывод в LOW, датчик BH1750 запиал напрямую и использовал режим BH1750_ONE_TIME_HIGH_RES_MODE, nRF24 перключаю в radio.powerDown(), в результате при вызове LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF) потребляемый ток 14мкА. Схема запитана от CR2450, работает уже 2 месяца.
PS если перед вызовом powerDown вы используете вывод в сериал подставляйте Serial.flush()
>Я запитал 18В20 от ноги контроллера и после снятия показаний переключаю вывод в LOW
это как так? ему же надо 3-5 вольт..
у меня на гирлянду с ds18b20 идет три провода - GND и Vin + Pin 8
Вместо Vin питаете от пина.
или термосенсоры можно питать от цифрового пина??
счас вот померял - на 8 пине 4.76v
этого должно хватить.
но у меня же десяток сенсоров будет. и каждый из них на метровом проводе.
это никак не повлияется на нагрузку на этот пин? не спалит ниче?
так
а можно питать от того же пина на котором Data для сенсоров? ну вот у меня 8 для этого.
или выбрать другой свободный для целей питания?
До 40мА на пин, до 200мА на корпус Atmegi. Если у вас DS18B20, то можете питать паразитным питанием (посмотрите даташит), включать их звездой не рекомендуется. Обычно это один шлейф, с небольшими ответвлениями.
магия какаято - все работает от отдельного цифрового пина)
и теперь во время сна все те же 44 микроампера!
но странно, почему не 14..
девайс питаю от USB-FTDI, джампер на 5 вольтах.
то есть Vin приходит 5 вольт и видимо эти 30 микроампер кушает стабилизатор на ардуине?
да, у меня как раз паразитное питание, и сенсоры соединены.. видимо как раз звездой - я просто контакты на концах проводов от сенсоров соединил вместе и подключил к бредборду.
а нужно как?
У меня 14мкА - это голая Атмега 328 + кварц на 8МГц, контроль питания выключен фьюзами.
Тут описание поделки http://geektimes.ru/post/263716/
да, у меня как раз паразитное питание, и сенсоры соединены.. видимо как раз звездой - я просто контакты на концах проводов от сенсоров соединил вместе и подключил к бредборду.
а нужно как?
Провода короткие, если нет глюков, можно и так.
У меня 14мкА - это голая Атмега 328 + кварц на 8МГц, контроль питания выключен фьюзами.
Тут описание поделки http://geektimes.ru/post/263716/
спасибо! вот пример - к чему стремится надо)
значит мои 40мкА это вполне нормально и можно уже успокоиться на этом.
осталось понять чем питать этот девайс, чтобы прожил хотябы 3 месяца при нулевой температуре.
я думаю что нужен какойто аккум именно на 3.3v, чтобы подключать девайс сразу к Vcc, минуя стабилизатор.
кстати переставил джампер на USB-FTDI адаптере на 3 вольта - все работает. на цифровом пине, который питает термосенсоры, в момент измерения - 3.2 вольта.
так вот - думаю купить батарейный отсек для AA батарей, на 4 штуки например.
две АА последовательно - это уже 3 вольта. а остальные две - параллельно - для увеличения емкости батарейной сборки этой.
если АА батарейка около 2000mA, то в итоге, по идее будет около 4000mA в сборке?
или не заморачиваться и взять обычный аккум на 6 вольт 7Ач и пустить через стабилизатор.
Провода короткие, если нет глюков, можно и так.
провода стандартные, по метру. такие они продаются эти сенсоры на ebay - герметичные и сразу с проводом.