четверг, 6 февраля 2014 г.

Энергосбережение при работе с nRF24L01

Даташит гласит, что в режиме RX трансивер ест 13.5мА.
Это довольно много для батарейных устройств. Постоянное потребление такого тока посадит аккум AAA (1000мАч, 1.2В, 360мАч в пересчете на 3.3В) за какие-то сутки, а это значит, что создавать долгоживущие устройства, в основном работающие в режиме ожидания команды, нам не светит?
Попробуем раскурить эту задачу, тем более, что куриво нехилое - 75 страниц даташита.
Впрочем, большая часть уже выкурена ранее

Какие есть варианты:
1. надеяться, что чип не потребляет столько, если в эфире тихо
2. надеяться, что чип в режиме энергосбережения (их два) держит ухо на макухе и таки палит эфир
3. возможно заниженная скорость обмена сэкономит еще немного
4. стараться всегда спать и просыпаться, проверяя эфир, как можно реже (зависит от требований к отзывчивости устройства)


Итак, режимы энергосбережения по даташиту:
Power down - потребление 0.1мкА, красота. Правда ничего не работает, кроме SPI.
Standby-I - 26мкА. Эфир таки слушать нельзя. Зачем этот режим нужен тогда? Из PowerDown в Standby чип выходит 150мкс (1.5мс при internal oscillator, wtf is this?), потом в RX/TX еще 130мкс
Standby-II - 320мкА, только для режима передатчика, режим активен при пустой очереди передачи TX FIFO и CE=1

Варианты 1 и 2 (из начала статьи) отпали, к сожалению. Вариант 3 (занижение скорости обмена) экономит совсем немного - с 13.5мА на 2Мбит/с до 12.6мА на 250кбит/с.

Вариант 4 был бы совсем жизнеспособен, если бы RX Settling (выход из Standby-I в RX mode) не занимал аж 130мкс. С другой стороны, если время реакции устройства равное, скажем, 50мс приемлемо, тогда можем просыпаться из PowerDown на 1мс каждые 49мс и получим среднее потребление в районе 0.3мА, а это уже в 50раз более долгая жизнь от 1 аккумулятора.
А вот передатчику придется попасть в ту 1 мс, когда активен приемник, а значит он должен будет сделать 50 попыток передачи с интервалом 1мс (настраивается, см.регистр SETUP_RETR). А тут облом, передатчик может сделать до 15 попыток, а максимальная задержка между попытками - 4мс, значит делаем поправку на это, просыпаемся каждые 46мс на 4мс. Новое расчетное среднее потребление - 1мА (15 суток).

Либо еще вариант - использовать команду REUSE_TX_PL, в даташите так и написано "вы можете вручную долбить отправку одного и того же пакета снова и снова пока не надоест, используя данную команду".
Значит 15 попыток с интервалом 0.5мс займут у передатчика 7.5мс времени, а чтобы покрыть 50мс период - делаем 7 подходов. Передатчику пофиг на потребление, он где-нибудь от розетки будет запитан. В итоге именно этот вариант и был применен в моем проекте беспроводного выключателя (выключатель на nRF24L01): питания там было очень в обрез, поэтому большую часть времени все спят, просыпаются по собаке (WDT) каждые 64мс, камень опрашивает сенсоры, а радио слушает эфир, затем снова засыпают в Power Down.
В другом проекте (беспроводной индикатор для бани) приемник вообще от 2 батареек ААА уже год работает и садиться походу не собирается.

Вариант 5. Бонусный. Можно совсем крохами питаться, если построить работу следующим образом: проснулся, спросил у роутера (мастера, сервера, арбитра, нужное подчеркнуть) "есть чо?", получил ответ, выполнил команду при необходимости и тут же уснул. Если настроить собаку на 128мс, то просыпаться придется всего 8 раз в секунду, отзывчивость при этом должна быть удовлетворительной, отправка запроса и чтение ответа должно уложиться навскидку в 500мкс, судя по диаграмме "ESB cycle" из ДШ, а среднее потребление - 60мкА. Блеск! 250 суток от одного мизинчикового аккумулятора. НО (куда ж без "но"), придется усложнять софт роутера, с ходу видится такой вариант:
- на роутер по проводу поступает пакет для беспроводного выключателя, команда включить свет
- роутер заряжает этот пакет в W_ACK_PAYLOAD соответствующего PIPE
- когда выключатель просыпается и спрашивает "есть чо?", то в ответ в ACK_PAYLOAD получает адресованный ему пакет
- затем роутер сбрасывает W_ACK_PAYLOAD, т.е. записывает туда пакет, который всем радиоустройствам знаком как "новых данных нет".
Бонусы: вроде даже просто, никакой лишней долбежки, никаких пустых ожиданий ни со стороны RX, ни со стороны TX, следовательно минимальное энергопотребление. Разве что параллельных каналов всего 6, чтобы поддерживать данным алгоритмом больше 6 устройств, надо что то придумать. Например не ложить сразу пакет в W_ACK_PAYLOAD, а держать его в памяти, в хэш-таблице "адрес-пакет", пока он не будет востребован.
Еще бонус: поскольку девайс сам обращается к "роутеру" за данными, отпадает проблема защиты сети от несанкционированной отправки управляющих команд на радиоустройства. Упрощается код, поскольку устройства всегда в режиме TX, не нужно дергать туда сюда (RX-TX-RX..): послал запрос, в ACK_PAYLOAD получил пакет. Все.
upd: вариант 5 позже был описан в отдельной статье

Важно также правильно стартовать при ограниченном питании, по сути это означает, что включение модуля (PWR_UP) лучше отложить на самый последний момент, после всех других инициализаций, либо включать его и держать в Standby. У меня до внедрения этого правила не всегда запускался беспроводной выключатель: начинает стартовать при полузаряженном конденсаторе (BOD 2V) с включением модуля и тут же разряжает его помирает. А все оттого, что источник много тока не дает, кондер еще толком не зарядился, а камень уже стартует. да еще и модуль заводит, а тот прожорливый, вот и крэшится все.

Практические замеры

(это потребление только модуля nRF24L01)
 - дефолтные настройки. PWRUP=1, PRIMRX=1, CE=1 - 15.3мА,
   после записи RF_DR_LOW в RF_SETUP (скорость 250кбит/с)  - 14.3мА
   если CE=0 (standby-I) - около 25мкА
 - в режиме RX в одиночестве (в эфире никого) - 15.3мА
 - в режиме RX и постоянном приеме данных - так же
 - в режиме TX без передачи (Standby-II) - 331мкА
 - в режиме TX без передачи, CE=0 (Standby-I) - 24.5мкА
 - в режиме TX при передаче пакет за пакетом без перерывов - 8.2мА
 - то же после понижения мощности радио:
   2Mbps, -18dBm - 5.8мА
   1Mbps, -18dBm - 5.95мА
   250kbps, -18dBm - 9.8мА (!) wtf?

Некоторые изыскания по дальности/пробиваемости
Тестировалось 2 устройства, находящихся через помещение друг от друга, через 2 стены панельного дома.
На дефолтных настройках скорости и мощности связь была неудовлетворительной и ненадежной. Не поленился перепрошить и проверить на 250кбитс - ничего не изменилось. однако от позиционирования девайса много зависит - стоит чуть чуть повернуть или приподнять - пакеты ходят отлично, еще чуть в сторону - и уже темно и глухо..

Ссылки

http://nrqm.ca/nrf24l01/
nrf datasheet - даташит на модуль
radiomodules

UDP: Вариант 5 дал минимальнейшее потребление, об этом в отдельной статье

18 комментариев:

  1. А можно ли carrier detect'ом увидеть несущую Wi-Fi или только такой же передатчик на NRF?
    Перебирал все каналы с 1 по 125 и тишина (передатчика NRF нету, только роутер).

    ОтветитьУдалить
  2. Этот комментарий был удален автором.

    ОтветитьУдалить
  3. Если посылка от передатчика приходит через равные промежутки времени то почему бы не засинхронизироваться под это и не включать приемник в нужный момент времени.
    Пока нет сигнала - включаемся чаще и ждем первую посылку. Как только успешно приняли первый пакет то засыпаем на время чуть меньшее чем задержка между посылками. И так по кругу.

    ОтветитьУдалить
  4. пакет от передатчика может прийти когда угодно.
    а если передатчик вдруг выключен или сломался? "ждем первую посылку" сразу сожрет все питание и выключатель умрет.

    ОтветитьУдалить
  5. Валерий, добрый день.
    Столкнулся с проблемой высокого потребления в powerdown режиме. Мой девайс использует сабж только в режиме TX. Раз в минуту идет отправка данных, после чего он переводится в powerdown режим. И все бы ничего - имею согласно даташиту ~1мкА потребления в этом режиме. Но, проходит время - примерно неделя - непрерывной работы. Лезу мерить ток - и получаю потребление в shutdown - уже порядка 1 мА. Модуль работает абсолютно штатно, все передается, потребление в других режимах не изменяется. Втыкаю новый модуль NRF24L01 - меряю и вижу правильный микроампер. Нашел описание подобной проблемы вот тут: https://devzone.nordicsemi.com/question/1764/nrf24l01-problem-in-power-down-mode/
    Но ответа там не нашел.
    Вы случайно не сталкивались? Не подскажите куда копать?

    ОтветитьУдалить
    Ответы
    1. нет. не сталкивался.
      используется ли на проблемной стороне REUSE_TX или FLUSH TX?
      если передатчик не получает ACK, TX FIFO не очищается, это надо обрабатывать руками.
      сколько разных модулей было протестировано? может это проблема экземпляра

      Удалить
    2. flush_tx использую, но думаю тут дело все же в железе. Пару модулей уже с таким "диагнозом"

      Удалить
    3. вот кажется я и столкнулся с чем-то подобным: у меня выключатель не всегда стартует, при включении питание там набирает обороты очень медленно (где то 0.15В в сек), и похоже в этом дело.
      Если перед включением разрядить кондер в 0, то все в норме.
      Если же схема была выключена "из розетки" на какое то время, в кондере остается где то 0.45В, при включении он заряжается до 1.3В и на этом все.
      Без модуля nRF проблемы не наблюдается. Куда копать пока неясно.
      В след.ревизии питание nRF все же через ногу проца сделаю, а в этой видимо придется разрядный резистор поставить.

      у Вас конденсаторы на питании nRF имеются?

      Удалить
  6. Не могли бы Вы разъяснить принцип использования команды REUSE_TX_PL. Из даташита не понятно.
    Вот, например, отправляю я байт с помощью команды W_TX_PAYLOAD, но примёмник ещё выключен. После 15 попыток выставляется бит MAX_RT в регистре STATUS, очищаю я регистр статус, а дальше что?

    ОтветитьУдалить
    Ответы
    1. все просто: при наступлении прерывания MAX_RT пишете по SPI команду REUSE_TX_PL (без каких-либо данных) и снова дергаете CE на 10мкс.
      MAX_RT в регистре статуса сбрасываете и все пойдет по-новой...

      Удалить
    2. Спасибо, попробую

      Удалить
  7. Подскажите, пожалуйста. замучился уже......
    Есть две железяки (одна только передает, вторая только принимает и что приняла на USART).
    PTX раз в минуту передает данные, CRC 1бит, 250кбит, 15 повторов через 2мс. Отправляю командой W_TX_PAYLOAD. Регистр DYNPLD и FEATURE = 0x00. В приемнике на трубе с адресом, по которому шлет PTX, стоит бит EN_AA. Да, и в передатчике адрес RX_ADDR_P0 соответствует адресу TX.
    Аппаратные прерывания не использую. А читаю статусный регистр.
    Так вот, ВСЕ 500 посылок от передатчика доходят до приемника, данные верные, но примерно в 30% посылок передатчик не ловит бит TX_DS (т.е. как я понимаю ACK), а выставляет бит MAX_RT.
    В чем может быть причина?
    И как все-таки отправлять пакет с запросом ASK, поскольку бит EN_AA устанавливается только на приемные трубы, может я что-то не так отправляю?

    ОтветитьУдалить
    Ответы
    1. может плохая связь, но тогда она в обе стороны должна быть плохой.
      проблема пакетов-дубликатов? там ситуация немного другая, как раз приемник пропускает RX_DR, но ACK повторно отдает, так что TX_DS должно быть всегда.
      причин тут может быть столько, что писать устанешь.. к тому же Вы не описали, что успели проверить при отлове косяка.
      для начала хорошо бы минимизировать код до самого простого.
      например светодиод на приемнике и передатчике, и передавать раз в секунду.
      также минимизировать настройки nRF - установить все дефолтные, т.е. самый минимум - поставить режим PRX и настроить длину пакета (см.первую статью).
      на приемнике светик на RX_DR, на передатчике TX_DS, и смотреть, нет ли провалов. Также кондеры на питание никогда не помешают.
      Опыт проводить в поле, вдали от микроволновок и роутеров )

      Удалить
    2. Случайно, удалось выяснить в чем причина, такого странного поведения. Я питал передатчик от литиевого аккумулятора, напряжение полного заряда у него около 4В. Вот, видимо, это повышенное напряжение так плохо влияло на NRF'ку. Как только отключил аккум., чтобы проверить сколько NRF'ка сможет отправить пакетов на ионисторе 1мкФ и напряжение чуть упало до 3.6В все ушедшие пакеты получили АСК, и кол-во повторов посылок сократилось до 0-3 (раньше было 10-14).
      Вот такие дела, т.е. при питании от литиевых батареек(аккум.) необходимо ставить малошумную и с малым падением кренку. Я остановил свой выбор на MCP1701AT.
      Спасибо, что откликнулись....

      Удалить
  8. Сергей, попробуйте в качестве акку использовать не LiPo, а LiFe, у них "рабочее" напряжение 3,2 вольта - то, что доктор прописал! Правда, они немного дороже ли-полек.

    ОтветитьУдалить
  9. МК выходит из power down в standby за 1.5мс при использовании кварца! исправьте пожалуйста! Это и означает надпись на английсом. А если вы используете внешний генератор тогда можно за 150мкс управиться, но так никто не делает т.к. все используют готовые платки.

    ОтветитьУдалить
  10. Подскажите пож-та, можно ли в режиме Standby-I менять адрес RX_ADDR_P0 и ТX_ADDR(да и вообще изменять конфигурационные регистры?),чтоб не терять 1.5 мс - на выход из режима Power down.

    ОтветитьУдалить