Экономия аккумулятора, глубокий сон
- Войдите на сайт для отправки комментариев
Втр, 23/03/2021 - 20:21
Нужно сделать с максимально возможной экономией аккумулятора примерно такую штуку.
Есть датчик, при срабатывании он на выходе ставит единицу и удерживает ее минимум 2 секунды (может и дольше). В течение этого времени нужно отправлять через SoftwareSerial сообщение "alarm", пару раз в секунду достаточно. Когда датчик молчит, нужно спать с макс. энергосбережением и примерно раз в минуту отправлять сообщение "ping". Большая точность интервалов времени не обязательна, важно "не прозевать" срабатывание датчика.
С темой энергосбережения, сна и прерываний впервые столкнулся.
Ниже самый простой вариант, который приходит в голову. Такое будет работать?
Смущает частая "побудка", наверное будет жрать аккумулятор?
Как это все сделать правильнее и эффективнее?
#include <SoftwareSerial.h> #include "GyverPower.h" #define ALARM_PIN 3 #define RX_PIN 7 #define TX_PIN 8 SoftwareSerial channel(RX_PIN, TX_PIN); void setup() { channel.begin(9600); pinMode(ALARM_PIN, INPUT); attachInterrupt(digitalPinToInterrupt(ALARM_PIN), isr, RISING); power.setSleepMode(POWERDOWN_SLEEP); power.hardwareDisable(PWR_ALL); } void isr(){ power.wakeUp(); } byte counter = 0; void loop() { if(digitalRead(ALARM_PIN)){ channel.println("alarm"); counter = 0; }else if(++counter == 120){ channel.println("ping"); counter = 0; if(digitalRead(ALARM_PIN)) channel.println("alarm"); } power.sleep(SLEEP_512MS); }
...
Как это все сделать правильнее и эффективнее?
Дык ить эта... тып к аффтору биплиоОтики обратился?
------
А тут, вот тут конкретно, на этом форуме, нужно указать на чем ты все строишь - на Ардуино или голом контроллере? На каком? Сколько времени будет держаться входной сигнал тревоги? Если ты используешь Ардуино с бутлоадером, то, до начала исполнения программы, пройдет примерно секунда...
Ну и ысчо много чиво нужно проЯснить, ОК?
ОК. Подробности:
1) Доплеровский датчик движения RCWL-0516.
При обнаружении движения устанавливает на выходе в логическую единицу (3.3V), держит пока чувствует движение, и потом еще 2 секунды. То есть длительность сигнала тревоги 2 сек минимум или больше.
Питание по даташиту 4 - 28V, по факту отлично работает от 3.3, ниже - отказывается. Жрет зараза 2.5 мА, вне зависимости от наличия/отсутствия тревоги. После включения питания стартует 10 секунд, периодически включать/выключать не получится.
2) Через SoftwareSerial сообщения передаются в радиодуль HC-12, который пересылает на другой такой же радиомодуль на "базовой станции" по радиоканалу 433МГц. Модули умные, сами обеспечивают в протоколе контрольные суммы и так далее. Интерфейс у них UART. Питание 3,3-5В, ток покоя/передачи зависит от режима, режимов несколько, есть также режим сна, все настраиваются АТ командами, с конкретными режимом пока не определился, надо поэкспериментировать.
3) Между датчиком и модулем нужна "прокладка", которая как минимум по логической единице на входе (2 сек мин) будет посылать в UART радиомодуля сигнал (в коде выше я обозначил сигнал "alarm").
В идеале также будет слать на "базу" периодический пинг, реже напряжение аккумулятора, получать и обрабатывать подвтерждения базы, переводить радиомодуль в режим сна и т.п.
Сначала пробовал по минимуму сделать генератор UART сигнала на Attiny13, в общем получилось но не понравилось, частоту держит плохо, а радиомодулю нужен честный UART на 9600. Возиться с кварцами и паять лень, и контроллер поумнее захотелось.
Поэтому делаю на Arduino Pro Mini 168 8Мгц 3.3.V, светодиод и стабилизатор ампутирую.
Усройство после запуска будет работать непрерывно пока хватает питания, поэтому время загрузки бутлоадера не важно, а из сна POWERDOWN пробуждение вроде как быстрое (16+6 тактов).
4) Питание от одного 18650 с защитой на 2200 мАч, напрямую без преобразователей на VCC ардуины, на датчик и на радиомодуль.
5) Всего устройств с датчиками будет 4-5 шт и одна "база". Эксплуатация летом (от +10°C), в тайге, девственно чистый радиоэфир, но полное отсутствие розеток и ларьков с батарейками .
Предполагается, что датчики будут срабатывать крайне редко (пару раз в сутки по 10 минут).
В идеале нужно обеспечить непрерывную работу датчика на одном аккумуляторе в течение недели (170 часов).
Там кода внутри библиотеки вроде немного... Я могу попробовать вместо вызовов этой библиотеки вытащить в пример кода саму работу с регистрами и WDT (которые пока я не очень понимаю).
328й МК умеет просыпаться по LOW на некоторых пинах.
Напр.: http://heliosoph.mit-links.info/atmega328p-wakeup-sleep-via-interrupt/
Это как-будто бы реже будет будить МК.
Но есть проблема - этот ваш модуль по тревоге делает HIGH, если я не ошибаюсь. И это совершенно не то, что нужно. С другой стороны на нем есть место для припайки резисторов, которые увеличат время нахождения в аларме (если верно помню). Т.е. уже не 512мс можно ставить интервал сна, а секунды 4-8.
Но, в целом, насколько будет эффективней побудка по времени в отличии от побудки по событию - покажет только эксперимент. Ведь жрать там будет все. Да и просто от неаккуратного монтажа могут утечки пойти.
И, да, если вы собрались глухарей выслеживать или медведей каких, то учтите, что МКВ сенсоры не отличают теплокровного от ёлки и будут реагировать на колыхание и того и другого.
Банально, но надо пробовать и измерять потребление.
По скетчу: вроде из описания библиотеки power.wakeUp(); лишнее. Вредно ли это, или просто избыточно - не знаю.
И пробуждение из сна быстрое для внутреннего RC генератора. Если кварц, то намного больше. Это скорее просто для информации, на потребление заметного влияния оказать не должно.
пока это того самое, подумайте в сторону солнечной батареи. она не зарядит АКБ, но компенсирует некоторые затраты. Солнечная батарейка (панель) - источник тока, с таким АКБ ее можно цеплять через диод, не заморачиваясь со схемой заряда и контроля... если солнечная панель небольшая.
По идее время сна нужно бы поставить максимальное 8192 мс, но возможна проблема.
Если датчик включится непосредственно перед уходом в сон, но уже после проверки пина в loop(), то МК прозевает срабатывание датчика и проспит 8 сек.
Если подскажете, как избежать такой ситуации, буду очень благодарен!
Пока что сделал сон полсекунды именно из-за этого. За 2 сек включения датчика МК точно проснется 2-3 раза и напрямую проверит пин, опоздание тревоги в полсекунды допустимо. Решение вроде рабочее, но кривое и неэффективное.
Самый прожорливый это датчик движения, он постоянно потребляет 2.5 мА, мк и радиомодуль большую часть времени будут спать. Если грубо емкость аккумулятора 2200 мАч поделить на 2.5 мА получим 36 суток. Реально конечно будет меньше, но столько и не нужно. Достаточно одной недели.
Разумеется, это все надо будет пробовать и проверять.
Инвертировать можно. Но это ещё один потребитель энергии.
Low level interrupt on INT0 and INT1 is detected asynchronously. This implies that this interrupt can be used for waking the part also from sleep modes other than idle mode. The I/O clock is halted in all sleep modes except Idle mode. Note that if a level triggered interrupt is used for wake-up from power-down, the required level must be held long enough for the MCU to complete the wake-up to trigger the level interrupt. If the level disappears before the end of the start-up time, the MCU will still wake up, but no interrupt will be generated.
Насколько я понимаю даташит - никакие иные виды внешних прерываний не вытаскивают МК из спячки.
Если вы не используете это, то остается только периодически вскакивать по таймеру.
Сомнительно. См. цитирование выше.
Если датчик включится непосредственно перед уходом в сон, но уже после проверки пина в loop(), то МК прозевает срабатывание датчика и проспит 8 сек.
Если подскажете, как избежать такой ситуации, буду очень благодарен!
Модифицировать датчик так, чтобы он 2x времени аларм держал?
Переписал код, без внешних библиотек. Временно для отладки вместо SoftwareSerial отправляю в Serial и смотрю монитором, все работает
Еще раз кратко - сигнал на ALARM_PIN устанавливается в единицу на 2 секунды, при его появлении надо несколько раз послать в сериал "alarm", в остальное время нужно спать иногда отправляя сообщение "ping".
Если сигнал появится во время сна, прерывание alarmRising разбудит, сигнал будет обнаружен и обработан. Если появится в процессе отправки "ping", тоже будет обработан.
Но если появится после проверки digitalRead(ALARM_PIN) но перед уходом в сон, событие будет потеряно. Точнее говоря будет обнаружено после сна в полсекунды (длительность сигнала 2 сек). Опоздание в полсекунды приемлимо.
Хочется сделать сон более длительным (8 секунд). Но тогда при потере сигнала перед засыпанием опоздание тревоги будет уже 8 секунд, это слишком много.
Как этого избежать? Как отменить засыпание при наличии единицы на пине ALARM_PIN?
Уверены в том, что просыпается по RISING, а не по WDT?
Ну я же только что проверил сам своими руками, по RISING отлично просыпается!
Сделал сон подольше (4 сек) чтоб успеть, добавил println("wake") при просыпании и потыкал в пин проводком. Вот лог из монитора:
Все повторы wake через идут 4 секунды.
А когда ткнул в пин сон был меньше секунды!
См строчку 08:41:42.317 wake который прямо перед alarm
Уверены в том, что просыпается по RISING, а не по WDT?
И там индусы... Ну что ж, будем знать.
И главное, с 15-го года могли бы и исправить в даташите.(
Как этого избежать? Как отменить засыпание при наличии единицы на пине ALARM_PIN?
Интересно, думал что POWERDOWN с полностью отключенной периферией потребляет меньше любого другого режима, какие-то микроамперы... Кстати, у моих Pro Mini кварц 8Мгц, специально такие использую.
В данном случае, пока датчик не включится, и работы-то нет никакой, наверное проще спать. Если разница между сном 8 и 0.5 сек несущественная, это сильно упрощает дело. Но все равно хочется разобраться с долгим сном. Спасибо за советы, буду копать дальше!
Голый контроллер, без кварца, 8 MHz во сне, Powerdown
Меньше мне сделать не удалось. Пишуть, что оне PicoPower, но я так и не добился.
Интересно, думал что POWERDOWN с полностью отключенной периферией потребляет меньше любого другого режима, какие-то микроамперы...
Кстати, у моих Pro Mini кварц 8Мгц, специально такие использую.
Понятно, что POWERDOWN круче всех, но вы пишите, что у вас есть доплеровский модуль который всегда включен и ест 2.5 мА. Поэтому СИЛЬНО стараться снизить до 10 мкА может нет смысла.
И еще раз напомню, если вы используете кварц, то выход из спячки намного дольше, чем вы писали выше. Для общего потребления это не существенно.
power-down aatiny13a https://youtu.be/cWddjLl2KCQ
Краткие итоги, может кому пригодится.
Плата Mini Pro которая "3.3V" кварц 8МГц контроллер Atmega168PA,самый дешевый китай с надписью www.betemcu.cn
Сначала отпаял светодиод питания и стабилизатор, на "пустом скетче" стала потреблять 4.5 мА.
Сделал режиме сна POWERDOWN с полностью отключенной периферией, ток всего 5 мкА!
При этом регулярно просыпается по таймеру ватчдога и сразу же по нажатию кнопки, где прерывание, мигает диодиком.
Мерял с питанием от акк 18650, заряженного до 4 вольт. Мультиметр UT33C, разрешение у него 1 мкА точность ±1% или ±2 разрешения, хотя немолодой уже, но раньше вроде сильно не врал. Но мне уже без разницы 5 или 7 мкА, этого уже достаточно, все равно датчик будет жрать 2.5 мА.
Измерил осциллографом примерное время просыпания, очень грубо. От переднего фронта после кнопки до фронта на 13 пине, который мигает. Получилось 2.69 миллис, для моей задачи этого достаточно.
Всем кто помогал и подсказывал, спасибо!
Вопросов есть еще много, но уже по другим темам.