Как вывести ESP8266 из глубокого сна в определенную дату и время?

Я хочу перевести свой ESP8266 в режим глубокого сна, а затем разбудить его в определенный день и время, [примерно] с точностью до секунды.

Редактировать: К сожалению, глубокий сон ESP8266 не поддерживает значения, превышающие примерно 3,5 часа. Я пытался спать по часу, пока не будет достигнуто желаемое время, но обнаружил, что это не очень точно; часто десятки секунд дрейфа на каждом следе, что в сумме составляет много минут дрейфа через несколько часов.

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

Редактировать: я использую WAKE_RF_DISABLED, чтобы отключить Wi-Fi для экономии энергии при пробуждении, поэтому, когда он просыпается, обычно нет подключения к Интернету для проверки времени (я хочу подключиться только к WiFi раз в 24 часа).

, 👍1

Обсуждение

В течение какого периода времени вы ожидаете точность в одну секунду? Это важно., @Elliot Alderson

Каждые 24 часа в определенное время, но мне нужно решение, которое я могу использовать гибко, поэтому, возможно, просыпаюсь каждые несколько дней., @Nick Bolton

Вам нужно 1 ppm или лучше, если вы хотите точность в 1 секунду за период в 1 неделю. Это не будет легко или дешево. Для дешевого RTC точность будет ограничена самим кристаллом, а не чипом, который считает тактовые циклы., @Elliot Alderson

Вы уверены? «[DS3231 при ±3,5 ppm] поддерживает точность RTC с точностью ±2 минуты в год в диапазоне от -40°C до +85°C» (Источник: https://datasheets.maximintegrated.com/en/ds/DS3231. пдф), @Nick Bolton

Две минуты в год - это 120 секунд за 52 недели... хуже, чем дрейф на 2 секунды в неделю. Я уверен., @Elliot Alderson

Что ж, по словам Максима, это по-прежнему «чрезвычайно точно», и я склонен согласиться. Я не проектирую спутник GPS., @Nick Bolton

Как хотите, но вы изменили требования. Вы сказали «просыпаться каждые несколько дней» и «в определенную... дату», а позже вы сказали, что будете «повторно синхронизировать часы каждые 24 часа или около того». Все, что работает для вас. Мир., @Elliot Alderson

Да, я понял, что был слишком требователен; Я понимаю, что с DS3231 невозможно получить секунды больше года, и мне определенно не нужен такой уровень точности. Меня более чем устраивает 2 секунды дрейфа в неделю. Мир., @Nick Bolton


1 ответ


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

3

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

«DS3231 — это недорогие, чрезвычайно точные часы реального времени I2C (RTC)». DS3231 "поддерживает точность RTC в пределах ±2 минуты в год в диапазоне от -40°C до +85°C"

Решение 1. Периодически активируйте MCU и проверяйте внешний RTC

Возможно, наиболее энергоэффективным решением (по сравнению с решением для будильника ниже) будет периодический вывод ESP8266 из режима глубокого сна для проверки времени на внешнем RTC и, в зависимости от желаемой точности, переход в режим глубокого сна на более короткие периоды по мере того, как вы приближайтесь к целевому времени пробуждения (например, просыпайтесь и проверяйте RTC каждую минуту, когда вы находитесь примерно в 10 минутах от целевого времени).

Чтобы сэкономить электроэнергию, перед тем как перевести ESP8266 в спящий режим, вы можете просто использовать транзистор, подключенный к GPIO, чтобы отключить источник питания Vcc на модуле DS3231 (он будет использовать встроенную батарею 2032, пока питание не подается).

При перезапуске с выключенным Wi-Fi (ESP.deepSleep(1e6, WAKE_RF_DISABLED)) ESP8266 нужно пробудить только примерно на 200 мс, потребляя 20 мА, чтобы проверить DS3231, пришло ли время полностью проснуться. . Это, вероятно, самый энергоэффективный вариант, который вы можете получить, если хотите сохранять точное время.

Решение 2. Установите будильник на внешнем RTC, чтобы разбудить MCU

При использовании DS3231 вывод SQW можно подключить к выводу RST ESP8266 через моностабильную схему. Моностабильная схема важна, потому что вывод RST не может оставаться на низком уровне, иначе он не загрузится. Моностабильная схема создает импульс на выводе RST, когда вывод SQW DS3231 становится низким.

Примечание о энергопотреблении: ESP8266 должен потреблять всего 20 мкА в режиме глубокого сна, но модули DS3231 обычно потребляют около 1 мА при включении (что требуется для срабатывания сигнализации). возможно из-за EEPROM на модуле. Это энергопотребление имеет большое значение, если вы разрабатываете систему с низким энергопотреблением. Вот почему это второе решение менее энергоэффективно по сравнению с первым решением.

Следующий код устанавливает будильник на определенное время, и когда на выводе RST устанавливается низкий уровень (на основе вывода SQW DS3231), ESP8266 просыпается. Убедитесь, что вы раскомментировали SLEEP_DT и установили дату и время для пробуждения в определенную дату и время (конечно, вы можете установить это программно на любую дату и время), иначе он будет просыпаться каждые n секунд (значение SLEEP_SECONDS), но это также может быть полезно (время глубокого сна ESP8266 не очень точное).

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include <RTClib.h>

#define WIFI_SSID "Your WiFi SSID"
#define WIFI_PASS "Your WiFi password"

// раскомментируйте, чтобы проснуться в определенную дату и время
//#определить SLEEP_DT
#define SLEEP_DT_YEAR 2022
#define SLEEP_DT_MONTH 12
#define SLEEP_DT_DAY 02
#define SLEEP_DT_HOUR 15
#define SLEEP_DT_MINUTE 50
#define SLEEP_DT_SECOND 25

#define SLEEP_SECONDS 10 // проще для тестирования

RTC_DS3231 rtc;
WiFiUDP udp;
NTPClient ntp(udp);

void print_date(const DateTime& dt);

void setup() {
  Serial.begin(9600);
  while (!Serial) { delay(1); }
  
  Serial.println('\n');
  Serial.println("Hello RTC wake deep sleep");
  
  Serial.println("Init DS3231");
  if(!rtc.begin()) {
    Serial.println("DS3231 failed");
    while (true) { delay(1); }
  }

  // не требуется
  rtc.disable32K();

  // не используется
  rtc.disableAlarm(2);

  // по-видимому, может привести к проблемам, если не очистить
  rtc.clearAlarm(1);
  rtc.clearAlarm(2);

  // прекращаем колебания; позволяет будильнику работать
  rtc.writeSqwPinMode(DS3231_OFF);
  
  Serial.println("Init WiFi");
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  
  Serial.println("Connecting to " WIFI_SSID);
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
  }
  Serial.print("Connected, IP: ");
  Serial.println(WiFi.localIP());
  
  ntp.begin();
  bool ntpOk = ntp.update();

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, setting time");
    if (ntpOk) {
      Serial.println("Using time from NTP client");
      rtc.adjust(DateTime(ntp.getEpochTime()));
    }
    else {
      // непроверенный код
      Serial.println("NTP unavailable, using time of build");
      rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    }
  }
  
  Serial.print("Date and time set to: ");
  print_datetime(rtc.now());

#ifdef SLEEP_DT

  DateTime alarm(
    SLEEP_DT_YEAR,
    SLEEP_DT_MONTH,
    SLEEP_DT_DAY,
    SLEEP_DT_HOUR,
    SLEEP_DT_MINUTE,
    SLEEP_DT_SECOND);

  Serial.print("Setting alarm for date: ");
  print_datetime(alarm);
    
  if (!rtc.setAlarm1(alarm, DS3231_A1_Date)) {
    Serial.println("Failed to set alarm");
  }

#else

  // спать в течение заданных секунд в целях тестирования
  Serial.print("Setting alarm for seconds: ");
  Serial.print(SLEEP_SECONDS);
  Serial.println(" seconds");
  if (!rtc.setAlarm1(rtc.now() + TimeSpan(SLEEP_SECONDS), DS3231_A1_Second)) {
    Serial.println("Failed to set alarm");
  }
  
#endif // SLEEP_DT

  Serial.println("Going into deep sleep (wake on RST low)");
  Serial.flush();
  ESP.deepSleep(0);
}

void print_datetime(const DateTime& dt) {
  char df[] = "YYYY-MM-DD hh:mm:ss";
  Serial.println(dt.toString(df));
}

void loop() { }

Вот оно в действии...

Arduino IDE и вывод

Примечание. Время скачет, потому что я вырезал несколько кадров, чтобы вы не скучали (обещаю, никакого дыма и зеркал).

,

ESP8266 имеет встроенный RTC, способный отслеживать время в глубоком сне., @Juraj

«Несмотря на название RTC, RTC на самом деле не являются часами реального времени в обычном смысле этого слова. Хотя они поддерживают отсчет счетчика, пока модуль находится в спящем режиме, точность, с которой он это делает, сильно зависит от температуры окружающей среды. чип.": https://nodemcu.readthedocs.io/en/dev/modules/rtctime/, @Nick Bolton

«количество микросекунд для сна. Максимальное значение составляет 4294967295 мкс или ~ 71 минута».: https://nodemcu.readthedocs.io/en/dev/modules/rtctime/#rtctimedsleep, @Nick Bolton

@Juraj Обновленный ответ, спасибо., @Nick Bolton

Вы обманываете себя, если считаете, что точность вашего дешевого модуля RTC составляет 1 секунду в течение более чем нескольких часов. Вам необходимо тщательно откалибровать RTC и поддерживать его постоянную температуру, если вы хотите повысить точность., @Elliot Alderson

Я не уверен, что могу с тобой согласиться. Максим довольно известная компания. Если техническое описание не лжет ... «DS3231 - это недорогие, чрезвычайно точные часы реального времени I2C (RTC)» https://datasheets.maximintegrated.com/en/ds/DS3231.pdf, @Nick Bolton

Также ... «поддерживает точность RTC с точностью ± 2 минуты в год от -40 ° C до + 85 ° C»., @Nick Bolton

@ElliotAlderson К вашему сведению, я пометил ваш комментарий как недружественный (что противоречит кодексу поведения). Я предлагаю вам переосмыслить то, как вы общаетесь с другими. https://arduino.stackexchange.com/conduct#unfriendly-language, @Nick Bolton

Я постараюсь быть более дипломатичным. Предлагаемое вами решение не сможет обеспечить точность в 1 секунду в течение периода более нескольких дней, как указано в документации Maxim. Слова «чрезвычайно точный» означают разные вещи для разных людей., @Elliot Alderson

Спасибо. Я доволен (и большинство людей, вероятно, были бы счастливы) улучшением точности, которое DS3231 предлагает по сравнению с RTC глубокого сна ESP8266 (который, кажется, дрейфует на несколько секунд в течение часа). Если вы постоянно спите, чтобы добраться до 24 часов, то этот дрейф довольно плохой ... много минут. DS3231, безусловно, является значительным улучшением, не так ли?, @Nick Bolton

RTC обновляется из NTP, если доступно подключение к Интернету, @Juraj

Да, если есть подключение к интернету; нет, если вы отключаете WiFi для экономии энергии., @Nick Bolton

Я заметил, что с ESP8266 при пробуждении после глубокого сна время NTP (с использованием «configTime» и «localtime») сбрасывается на значение по умолчанию; 1970. С внешним RTC, конечно, это не проблема., @Nick Bolton

@Juraj Я думал о том, что вы сказали ... вы имели в виду, что если «configTime» используется на ESP8266, то «NTPClient» является избыточным?, @Nick Bolton

конечно это лишнее, @Juraj

Спасибо за подтверждение, интересно, почему самые популярные туториалы для "время esp8266" указывают на NTPClient; первые 3 результата все делают, и только до тех пор, пока вы не дойдете до 4-го, упоминается configTime., @Nick Bolton