Можно ли узнать, как долго ESP8266 находился в глубоком сне?

Я работаю над устройством с низким энергопотреблением, в котором реализован микроконтроллер ESP8266 и используется его функция глубокого сна. В прошивке используется библиотека Arduino C++.

Часть функциональности требует знания времени. Для этого я использую configTime для получения времени (т.е. NTP). Но для снижения энергопотребления я подключаюсь к WiFi только каждые 24 часа. ESP8266 просыпается каждый час (чтобы решить, следует ли ему что-то делать или вернуться в спящий режим). Чтобы сохранить время, я записываю последнюю известную временную метку unix в память RTC и после пробуждения добавляю количество времени, в течение которого устройство было переведено в режим глубокого сна (например, 1 час).

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

Есть ли способ с помощью API ESP8266 определить, как долго устройство фактически находилось в глубоком сне? Таким образом, при пробуждении вместо того, чтобы слепо добавлять 1 час к сохраненной в RTC временной метке unix, я могу добавить количество времени, в течение которого MCU находился в глубоком сне. техническое описание, по-видимому, RTC упоминается всего несколько раз и не очень подробно.

Если встроенного ПО не существует, какое аппаратное решение можно использовать?

Размышление вслух: я думаю, что компромисс может состоять в том, чтобы определить, была ли нажата кнопка сброса (возможно, защелка/триггер/регистрация?). В этом случае я все еще не смогу сказать, как долго MCU спит, но, по крайней мере, я смогу сказать, должен ли я добавить время. Я обнаружил, что system_get_rst_info зависит от того, как устройство перешло в спящий режим (т. е. если его вывести из глубокого сна нажатием кнопки сброса, причина в REANSON_DEEP_SLEEP_AWAKE), поэтому я не мог не вижу, как использовать это в этом случае. Я полагаю, что мог бы добавить внешний RTC, избавляя от необходимости вычислять, как долго микроконтроллер находился в глубоком сне, и просто использовать эту внешнюю микросхему для учета времени.

Изменить: по-видимому, rtctime.dsleep() обеспечивает отслеживание времени в глубоком сне, но это только LUA, поэтому мне это бесполезно. исходный код написан на C, но я ничего не вижу это поможет.

Время сохраняется в глубоком сне. Т.е. rtctime.get() будет продолжать работать (при условии, что время было доступно до сна).

, 👍0

Обсуждение

Аппаратным решением может быть флип/флоп, или scr, или защелкивающаяся штуковина bjt, которая зажимается нажатием физической кнопки, которая также использует фетр, чтобы сначала потянуть вниз. Затем вы можете быстро запросить этот бит состояния при загрузке, чтобы определить, сделала ли это кнопка. Затем вы сбрасываете защелку/JK/SCR с помощью другого GPIO. Итак, он сжигает два GPIO, но работает хорошо., @dandavis

@dandavis Хорошая идея, я попробую., @Nick Bolton


2 ответа


Лучший ответ:

0

Я считаю, что ответ нет (вы не можете точно сказать, как долго ESP8266 находился в спящем режиме), учитывая следующие ограничения:

  1. Если нельзя использовать внешний RTC.
  2. Если MCU не подключается к Wi-Fi при каждом выходе из режима сна.
  3. Если пользователь может произвольно разбудить MCU, нажав кнопку сброса.

Другими словами, если ESP8266 не подключается к Wi-Fi каждый раз, когда просыпается, вы можете оценить время только на основе того, как долго он должен находиться в глубоком сне, но вы можете не знаю наверняка, не подключившись к Интернету или не используя внешний RTC.

,

-1

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

,

Что, если я сплю 1 час, а через 1 секунду нажимаю кнопку сброса? Время будет 59 минут и 59 секунд, как я уже упоминал в своем вопросе., @Nick Bolton

Я всегда использую метку времени unix в миллисекундах, т.е.... gettimeofday(&tv,NULL); time_stamp[ptr] = (int64_t)(tv.tv_sec*1000LL + tv.tv_usec /(1000LL));, @Ahmad Firdaus Idris