(Почему) успешное завершение getLocalTime() на ESP32 занимает несколько секунд
Это перекрестная публикация с https://github.com/espressif/arduino-esp32/discussions/ 8653, поскольку там это не дало никаких результатов.
Я заметил, что выполнение getLocalTime()
постоянно занимает 5–10+ секунд. До сих пор мне не удалось найти причину.
Я тестирую модуль ESP32-WROVER-B. При запуске устройство сначала подключается к Wi-Fi, а затем пытается синхронизировать время.
boolean initTime() {
struct tm timeinfo;
log_i("Synchronizing time.");
// Подключаемся к NTP-серверу со смещением TZ 0, вызываем setTimezone() позже
configTime(0, 0, "pool.ntp.org");
// getLocalTime использует тайм-аут по умолчанию 5 с -> цикл занимает не более 3*5 секунд
for (int i = 0; i < 3; i++) {
if (getLocalTime(&timeinfo)) {
log_i("UTC time: %s.", getCurrentTimestamp(SYSTEM_TIMESTAMP_FORMAT).c_str());
return true;
}
}
log_e("Failed to obtain time.");
return false;
}
...
10:12:28.118 > [ 3634][I][connectivity.h:17] startWiFi(): ...done. IP: 192.168.0.57, WiFi RSSI: -55.
- 10:12:28.118 > [ 3700][I][util.h:25] initTime(): Synchronizing time.
|
->10:12:34.025 > [ 11572][I][util.h:37] initTime(): UTC time: 2023-09-19 08:12:34.
10:12:34.037 > [ 11572][I][util.h:60] setTimezone(): Setting timezone to 'CET-1CEST,M3.5.0,M10.5.0/3'.
10:12:34.042 > [ 11574][I][main.cpp:175] syncTime(): Current local time: 2023-09-19 10:12:34
...
В приведенном выше примере для подтверждения "действительного" потребовалось ~6 с. временная метка, которая станет доступной.
@Marcel Stör, 👍0
Обсуждение1 ответ
Лучший ответ:
Судя по формулировке вопроса, похоже, что вы часто запрашиваете событие NTP повторной синхронизации. Возможно, как можно чаще. Учтите, что большинство проектов Arduino запрашивают событие повторной синхронизации NTP один раз, чтобы установить локальное RTC. Затем, возможно, один раз в день, чтобы проверить точность RTC.
Имейте в виду, что многие NTP-серверы защищаются от атак, ограничивая обслуживание IP-адресов, которые используют их чрезмерно. Эта цитата:
NTP-сервер может ограничивать трафик, особенно для клиентов, выполняющих частые запросы.
... взято с этого веб-сайта.
Если вы не знаете, если время важно для вашего проекта Arduino , рассмотрите возможность добавления оборудования RTC. Можно установить местное время сразу после повторной синхронизации NTP. С этого момента местный RTC может предоставить время. Позже может оказаться целесообразным сверить местное RTC со временем, сообщаемым NTP. Но для подавляющего большинства проектов Arduino в этом обычно нет необходимости в течение нескольких дней.
Очень правдоподобное объяснение, спасибо! Работая над новым скетчом, я часто прохожу цикл компиляции-загрузки-перезагрузки (далеко). Поскольку мой initTime()
запускается из setup()
, запросы с моего IP-адреса очень часто попадают на серверы NTP. Думаю, мне следует рассмотреть возможность запуска собственного NTP-сервера (например, Docker-контейнера cturra/ntp) и перемонтировать мои скетчи, чтобы он соответствовал этому., @Marcel Stör
Спасибо. Мне интересно. Если вы не делаете запрос NTP, скажем, в течение 24 часов. Видите ли вы улучшение времени ответа NTP?, @st2000
Похоже, что это действительно была основная причина. Отсутствие работы над скетчами на пару дней решило проблему., @Marcel Stör
- Документация ESP32 для "time.h"
- ESP32 секунды от эпохи
- Установить время настенных часов или изменить смещение GMT без ntp-сервера?
- Как установить RTC в ES32 с помощью NTP-сервера?
- Ошибка при передаче `time_t` и `struct tm`, ESP32
- Обратная связь ESP32 от NTP
- Не удалось преобразовать time_T из прошлого в структуру tm
- Размер структуры tm (datetime) отличается в ESP32 от linux64x
1) Вы пробовали другой NTP-сервер? 2) Почему важно синхронизировать местные часы как можно быстрее?, @st2000
Попробуйте заменить
pool.ntp.org
(одним из) его IP-адресов, например.159.196.3.239
, @Nick Gammon@st2000 st2000 Я пробовал разные серверы, но пока все по имени (т.е. неявно используя DNS). Я хочу, чтобы это было сделано как можно быстрее, поскольку это часть последовательности
setup()
. Скетч должен выполняться только при точно синхронизированных часах., @Marcel Stör@NickGammon спасибо, еще не пробовал., @Marcel Stör
он должен подключаться к серверу только один раз при загрузке, а затем время от времени, что является четвертым аргументом конструктора NPTClient (время обновления в мс). На ESP32 каждые 15 минут вполне достаточно, чтобы поддерживать дрейф в пределах 1 с, что в любом случае является разрешением интерфейса., @dandavis
попробуйте
sntp_set_sync_mode(SNTP_SYNC_MODE_IMMED);
, @Juraj