как реализовать периодический wakeup из sleep mode?

d00m
Offline
Зарегистрирован: 21.02.2013

всем привет.

второй день пытаюсь сообразить и на писать код, при котором 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 сек.)
тогда я смогу "поиграться" этим параметром времени и выбрать нужное окно для приема-передачи.
а все остальное время ардуина будет спать.
 
прошу совета и пример кода если можно..
спасибо 
Gres
Gres аватар
Offline
Зарегистрирован: 26.03.2013

Эту библиотеку не знаю, все делаю ручками. Алоритм должен быть такой:

1. Программа выполняет требуемую работу.

2. Включает режим сна.

3. Уходит спать.

4. Просыпается через заданное время.

5. Отключает режим сна.

6. Переходит к пункту 1.

d00m
Offline
Зарегистрирован: 21.02.2013

да, все так.

и используя библиотеку LowPower, чтобы уснуть на 8 сек нужно просто вызвать 

LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

но вот беда, в цикле loop() все происходит не совсем понятно для меня. чтото оченьбыстро выполняется, чтото нет, 

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

вот мне нужно в коде выделить для этой операции опеределенное количество времени. 

но самое главное - это сделать вот эту часть алгоритма:

2. Включает режим сна.

3. Уходит спать.

4. Просыпается через заданное время.

5. Отключает режим сна.

как научить ее засыпать и просыпаться через заданное время?

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

поэтому и начал использовать библиотеку LowPower - она работает и проверена на моем устройстве - Anarduino+RF96(LoRa)

bwn
Онлайн
Зарегистрирован: 25.08.2014

Вроде на длительные промежутки делали на DS3231. У нее есть выход будильника. Сам с прерываними не занимался, мысли вслух.
Ну а с интервалом работы - самое простое классика "мигаем светодиодом без delay()". Хотя без подтверждения о приеме это кривые костыли. ИМХО.

d00m
Offline
Зарегистрирован: 21.02.2013

это на millis() которое? тоже думал в эту сторону.. но мне же еще надо засыпать и просыпаться раз в минуту. тут это не поможет..

разве по прерываниям бортового таймера такое не сделать?

bwn
Онлайн
Зарегистрирован: 25.08.2014

Имеется в виду, что не заснет пока не отработан заданный интервал. 5-10-50 секунд.
А разбудить, в этой теме  человек вроде прикрутил. У него правда период сна большой.

d00m
Offline
Зарегистрирован: 21.02.2013

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

 

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

Пытаюсь понять - а зачем вам засыпать больше, чем на 8 секунд?

Проснулся и снова спать, и только на восьмой раз проснулся и что-то делаешь. В чем проблема?

Восемь секунд для мегагерцевого чипа - это и так дофига.

d00m
Offline
Зарегистрирован: 21.02.2013

ну я думал что лучше уснуть на нужно время сразу, чем дергать его по 8 сек.

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

axill
Offline
Зарегистрирован: 05.09.2011

Вообще то надо начать с того, что режимов сна у atmega328 несколько

нас может интересовать два - idle и powerdown 

idle самый простой, в нем продолжают работать все таймеры, однако потребление остаётся высоким и толком такой режим батарею не экономит

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

внешние прерывания чтобы генератор периодически нужно какое то внешнее устройство. Выше упоминали ds3231, если оно есть в проекте, то можно настраивать будильники на точное время срабатывания и каждый раз их переводить вперёд. Тогда МК будет спать и минуты и часы, сколько надо

специально ставить ds3231 нет необходимости. Настраиваем собаку, у неё максимальная время как раз 8 секунд. используем счётчик чтобы насчитать столько раз по 8 секунд сколько нужно. Как только досчитали - делаем свою работу. Пока не досчитали - сразу спать. Считать можно в loop. Чтобы по переполнению счетчика собаки ардуино не перегружалась надо настроить обработчик прерывания для собаки, код можно оставить пустым

d00m
Offline
Зарегистрирован: 21.02.2013

странно..

ипользуя 

LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

потребление около 3.9mA

а с собакой раза в два больше..

d00m
Offline
Зарегистрирован: 21.02.2013

ну и похоже что две подряд строки:

LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

заставляют спать дуину уже 16 сек. то, что надо.

axill
Offline
Зарегистрирован: 05.09.2011

d00m пишет:

странно..

ипользуя 

LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

потребление около 3.9mA

а с собакой раза в два больше..

Здесь вопрос в том, что реально эта библиотека делает. Я делаю без библиотеки, это совсем не сложно.

потребление микроконтроллера в режиме сна должно быть меньше 0.1 мкА. Все, что выше - повод задуматься над тем что ещё можно сделать. Ваши 3.9мА это очень много

d00m
Offline
Зарегистрирован: 21.02.2013

на данный момент потребление 1.5mA и я пока успокоюсь на этом.

новая беда появилась - ардуина ресетится похоже.

у меня в setup() есть println который при старте выводит небольшой баннер-приветствие:

>>>>> server #2 init ok. [434MHz], 7 sens

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

а я вижу что он периодически появляется при работе Сервера:

>>>>> server #2 init ok. [434MHz], 7 sens
>>> no requests from Client
>>> send to Client failed
>>> send to Client failed
>>>>> server #2 init ok. [434MHz], 7 sens
>>> no requests from Client
>>> send to Client failed
>>> send to Client failed
 

 

d00m
Offline
Зарегистрирован: 21.02.2013

думал кстати, что это термосенсоры потребляют

но отсоединял их и резистор для паразитного питания - все равно 1.1 - 1.5mA

Radjah
Offline
Зарегистрирован: 06.08.2014

Я тут статейку одну нагуглил про экономие энергии. http://inet-deal.mpa.ru/articles/arduino-003.html

Там самое минимальное потребление было 0,35 мкА, но при пробуждении из такой спячки скорее всего придется переинициализировать все устройства.

d00m
Offline
Зарегистрирован: 21.02.2013

да, я давно видел тоже.

0.35uA он получает путем выключения ADC, что у меня тоже происходит через либу LowPower, ключ ADC_OFF: 

    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); 

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

d00m
Offline
Зарегистрирован: 21.02.2013

и еще вопрос - если я буду питать девайс от аккумулятора 6V 7Ач то это же надо через Vin подключать,   в таком случае код, который измеряет напряжение на Vcс не будет показывать реальное состояние батареи.. так ведь?

axill
Offline
Зарегистрирован: 05.09.2011

d00m пишет:

и еще вопрос - если я буду питать девайс от аккумулятора 6V 7Ач то это же надо через Vin подключать,   в таком случае код, который измеряет напряжение на Vcс не будет показывать реальное состояние батареи.. так ведь?

через VIN лучше не подключать. Там стоит стабилизатор который сам сожрет 5-10ма. Лучше применить импульсный преобразователь на микросхеме с низким собственным потреблением

чтобы измерять напряжение на аккумуляторе надо плюсовую клемму подключить к аналоговому входу ардуины через резистивный делитель с коэффициентом 5/7.2в, т.е. Чтобы на ардуину не попадало более 5вольт

d00m
Offline
Зарегистрирован: 21.02.2013

путем более внимательного чтения чужих примеров кода, удалось получить 43 микроА во время сна.

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

чтото можно сделать в этом случае, для уменьшени потребления? как-то отключать цепь питания на сенсоры во время сна, и подключать ее когда МК проснется.

Sur
Offline
Зарегистрирован: 02.09.2015

d00m пишет:

 как-то отключать цепь питания на сенсоры во время сна, и подключать ее когда МК проснется.

Ключами на полевиках например.

alexvs
Offline
Зарегистрирован: 22.07.2014

Я запитал 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()

d00m
Offline
Зарегистрирован: 21.02.2013

>Я запитал 18В20 от ноги контроллера и после снятия показаний переключаю вывод в LOW

это как так? ему же надо 3-5 вольт..

 у меня на гирлянду с ds18b20 идет три провода - GND и Vin + Pin 8

 

bwn
Онлайн
Зарегистрирован: 25.08.2014

Вместо Vin питаете от пина.

d00m
Offline
Зарегистрирован: 21.02.2013

или термосенсоры можно питать от цифрового пина??

счас вот померял - на 8 пине 4.76v 

этого должно хватить.

но у меня же десяток сенсоров будет. и каждый из них на метровом проводе.

это никак не повлияется на нагрузку на этот пин? не спалит ниче?

d00m
Offline
Зарегистрирован: 21.02.2013

так

а можно питать от того же пина на котором Data для сенсоров? ну вот у меня 8 для этого.

или выбрать другой свободный для целей питания?

bwn
Онлайн
Зарегистрирован: 25.08.2014

До 40мА на пин, до 200мА на корпус Atmegi. Если у вас DS18B20, то можете питать паразитным питанием (посмотрите даташит), включать их звездой не рекомендуется. Обычно это один шлейф, с небольшими ответвлениями.

d00m
Offline
Зарегистрирован: 21.02.2013

магия какаято - все работает от отдельного цифрового пина)

и теперь во время сна все те же 44 микроампера!

но странно, почему не 14..

девайс питаю от USB-FTDI, джампер на 5 вольтах.

то есть Vin приходит 5 вольт и видимо эти 30 микроампер кушает стабилизатор на ардуине?

d00m
Offline
Зарегистрирован: 21.02.2013

да, у меня как раз паразитное питание, и сенсоры соединены.. видимо как раз звездой - я просто контакты на концах проводов от сенсоров соединил вместе и подключил к бредборду.

а нужно как?

alexvs
Offline
Зарегистрирован: 22.07.2014

У меня 14мкА - это голая Атмега 328 + кварц на 8МГц, контроль питания выключен фьюзами.

Тут описание поделки http://geektimes.ru/post/263716/

bwn
Онлайн
Зарегистрирован: 25.08.2014

d00m пишет:

да, у меня как раз паразитное питание, и сенсоры соединены.. видимо как раз звездой - я просто контакты на концах проводов от сенсоров соединил вместе и подключил к бредборду.

а нужно как?

Провода короткие, если нет глюков, можно и так.

d00m
Offline
Зарегистрирован: 21.02.2013

alexvs пишет:

У меня 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Ач и пустить через стабилизатор.

d00m
Offline
Зарегистрирован: 21.02.2013

bwn пишет:

Провода короткие, если нет глюков, можно и так.

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