Как отслеживать миллисекунды в спящем режиме

В моем приложении мне нужно отслеживать время работы приложения, а также использовать спящие режимы. Однако при использовании спящих режимов Timer0 отключается, и, следовательно, миллисекунды перестают считать.

Есть ли способ измерить/подсчитать, как долго Arduino находился в спящем режиме?

Чтобы дать вам дополнительную справочную информацию, вот чего я пытаюсь достичь: Я использую датчик давления, который отправляет прерывание на Arduino каждые 80 мс и пробуждает его. Программа выполняет различные процедуры для обработки данных, которые могут занимать от 2 мс до 60 мс. Затем он переходит в спящий режим, пока не произойдет другое внешнее прерывание, примерно через 20-78 мс. В приложении есть много процессов, зависящих от времени, таких как секундомер, таймер и будильник, поэтому мне нужно иметь возможность отслеживать их, желательно с помощью millis(). Устройство работает от одноячеечной батареи LiPo емкостью 250 мАч, которой в настоящее время хватает примерно на 4 часа. Я использую ATMega1284.

В большинстве спящих режимов Timer0 отключен. Это означает, что millis() перестает считать. Есть ли способ без использования RTC (и пространство, и вес в большом почете), чтобы поддерживать подсчет миллисекунд в спящем режиме?

Я заметил, что SLEEP_MODE_IDLE поддерживает работу Timer0, но это означает, что каждую миллисекунду прерывание пробуждает устройство. Пожалуйста, поправьте меня, если я ошибаюсь, но, учитывая, что мой цикл может выполняться около 60 мс, я не вижу большого преимущества в спящем режиме на 1 мс.

Возможные решения:

  • Использовать Timer2 для функции millis?
  • Используйте сторожевой таймер, чтобы подсчитать, сколько времени прошло во время спящий режим и добавить это в millis() при пробуждении?
  • Если бы существовал ОЧЕНЬ маленький SMD RTC, который не нуждался бы во внешнем компоненты, такие как генераторы и т. д., то это может быть осуществимо.

, 👍1

Обсуждение

[MAX31343](https://www.maximintegrated.com/en/products/analog/real-time-clocks/MAX31343.html) в 8-контактном корпусе WLP 2,1 мм x 2,3 мм...?, @Majenko

Я думаю, вам в любом случае понадобится RTC, если вы делаете будильники. Милли будет дрейфовать слишком сильно, чтобы быть очень полезным для точного хронометража. Если пространство является проблемой, вы можете использовать асинхронный режим timer2 и подключить кристалл 32 кГц к контактам TOSC. Затем вы можете использовать спящий режим «Энергосбережение». Я закончил проект часов, но немного потрудился, чтобы выяснить, как настроить код. После калибровки он стал точным с точностью до минуты в год., @Gerben

@Majenko - MAX31343 записывает только секунды, а не миллисекунды, @Glyn Davidson


2 ответа


3

Единственный способ поддерживать работу millis() — это спать в спящем режиме. SLEEP_MODE_IDLE. Переключение на Таймер 2 ничего не изменит, т.к. все таймеры, кроме сторожевого таймера, останавливаются в других спящих режимах. сторожевой таймер ужасно неточен, поэтому вы не хотите полагаться на него для любой хронометраж.

Я не вижу особых преимуществ в спящем режиме на 1 мс.

Переход в спящий режим на 1 мс позволяет немного сэкономить электроэнергию. Но если ты это сделаешь 60 раз каждые 80 мс вы сэкономите много энергии. Я предлагаю вы делаете именно это: ложитесь спать, когда закончите свои расчеты. Когда вы просыпаетесь, если видите, что пробуждение пришло извне прерывание, тем вы его обрабатываете. В противном случае вы просто снова заснете.

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

,

Спасибо @Эдгар. Как только я разместил вопрос, я начал искать в библиотеке прерывание 80 мс, но оказалось, что библиотека просто запрашивает данные каждые 80 мс, а датчик отправляет прерывание, как только данные готовы., @Glyn Davidson

Я пробовал постоянно выключать таймер 1 и таймер 3, а также выключать АЦП и БПК на 59,95 секунды каждой минуты и использовать спящий режим бездействия. Основной цикл проверяет, не произошло ли прерывание, в противном случае он снова переходит в спящий режим. Влияние этого на энергопотребление было минимальным. Сейчас попробую с часами реального времени., @Glyn Davidson


2

Я нашел часы RealTimeClock, которые мог бы использовать: RV-8803. . Он имеет размеры всего 3,2 мм x 1,5 мм x 0,8 мм, имеет внутренний XTAL и может показывать время с точностью до сотой доли секунды. Sparkfun делает раздельную плату (BOB-16281) и сопровождает библиотека.

Учитывая, что в моей схеме уже есть несколько развязывающих конденсаторов и я могу использовать внутренние подтягивающие резисторы ATMega1284, я думаю, что, вероятно, смогу интегрировать RV-8803 без каких-либо дополнительных компонентов.

На макетной плате прерывания работают хорошо, и вместо этого я могу использовать спящий режим EXTENDED_STANDBY. Единственным недостатком является то, что RTC записывает время в сотых долях секунды, тогда как моя программа раньше использовала миллисекунды. Мне нужно убедиться, что сотые доли достаточно точны для моих нужд.

В противном случае я рассмотрю предложение @Gerben выше.

,