Таймер ESP8266 для запуска действий (проблема с логикой)

Итак, у меня есть приложение, в котором есть 2 конкретных времени (например, 9 утра и 18 часов вечера), когда переменная curPos обновляется. Все конвертируется в мс с 00:00 (9 утра = 32400000, 18:00 = 64800000). Теперь действия (обновления curPos) должны запускаться каждый день в это время. Чтобы получить текущее время в реальном времени (всегда в мс), я отправляю http-запрос на веб-сайт. Это делается только один раз в setup().

Идея состоит в том, что мне нужно каким-то образом (http-запрос) получить доступ к текущему реальному времени, чтобы определить, когда в моем ESP8266 9 утра и 6 вечера с момента запуска скетча. Текущее реальное время необходимо только один раз в начале (на случай, если возникнет проблема и скетч перезапустится). Тогда я смогу вычислить разницу между текущим реальным временем и таймерами.

Следующим шагом будет преобразование значений в 24-часовой цикл, начиная со времени запуска/сброса, чтобы он мог повторяться без необходимости повторного запроса реального времени.

Я теряюсь в логике того, как с этим справиться, и в том, как с помощью millis() проверить, когда пора запускать одно из действий.

Это то, что я сейчас делаю с полезной нагрузкой HTTP GET в setup() (я могу успешно получить 3 значения в мс из ответа GET)

      String payload = http.getString();

      int commaIndex = payload.indexOf(',');
      int secondCommaIndex = payload.indexOf(',', commaIndex + 1); //Ищем следующую запятую сразу после первой

      mainTime = payload.substring(0, commaIndex).toInt(); //текущее реальное время в мс
      timers[0] = payload.substring(commaIndex + 1, secondCommaIndex).toInt(); //9 утра в мс
      timers[1] = payload.substring(secondCommaIndex + 1).toInt()); //6 вечера в мс

      timers[0] = abs(mainTime - timers[0]); //разница во времени до достижения первого таймера (в мс)
      timers[1] = abs(mainTime - timers[1]); //разница во времени до достижения второго таймера (в мс)

      // моя попытка превратить разницу во времени в 24-часовое «местное» (в скетче) время
      //dayMs — 24 часа в мс (86400000)
      if(timers[0] < 0)
        timers[0] = dayMs - timers[0];

      if(timers[1] < 0)
        timers[1] = dayMs - timers[1];

и в цикле мне понадобится сравнение (я думаю), но я просто в этом растерялся

//Я думаю, что милли нужно сбросить через 24 часа с момента начала скетча?

if(millis() == timers[0]){ 
      curPos = 1; //истек первого таймера, затем триггер
  }else if(millis() == timers[1]){
      curPos = 7; //истек второй таймер, затем триггер
  }

Спасибо!

, 👍0

Обсуждение

вы думаете, что уловили именно ту миллисекунду, которая вызывает событие?, @Juraj

было бы лучше установить время в TimeLib, а затем проверить, сейчас 9 утра или 18 вечера., @Juraj

Действительно. Вы также можете использовать NTP, чтобы получить текущее время из Интернета и передать его в TimeLib., @Majenko

настройте переменную tick... увеличивайте ее внутри цикла() каждую секунду или каждую минуту (даже каждый час... как вам удобно).... затем просто отслеживайте значение tick, @jsotola

спасибо, так что: - Я не думаю, что смогу уловить точную мс, чтобы вызвать событие, и я ищу предложения, как это сделать. - Я попробовал NTP, и возникли проблемы с часовым поясом, поэтому http-запрос является хорошей заменой. - Хорошо для переменной галочки, но я все еще немного не понимаю, как повернуть все за 24 часа (с исходного времени). - Я проверю TimeLib (я полагаю, это библиотека?), @SF1


2 ответа


0

Я описываю, как я это делаю в своем проекте. Я использую библиотеку времени, также известную как TimeLib. Я установил время, полученное не по NTP, а по Modbus с устройства, которое является источником других данных в моем проекте. В вашем случае у вас есть http-запрос.

Ввод для установки времени в TimeLib — это эпоха UNIX. Эпоха — это секунды от 1 января 1970 года. Если вы установите только секунды текущего дня, дата останется 1970-01-01.

И тогда у меня есть, например, эта функция

boolean restHours() {

  const int BEGIN_HOUR = 9;
  const int END_HOUR = 22;

  int hourNow = hour(now());

  if (hourNow >= BEGIN_HOUR && hourNow < END_HOUR) {
    if (state == RegulatorState::REST) {
      state = RegulatorState::MONITORING;
    }
    return false;
  }
  if (state == RegulatorState::MONITORING) {
    state = RegulatorState::REST;
    clearData();
  }
  return true;
}

now() возвращает время «эпохи». hour(now()) возвращает текущий час.

или в другой функции я проверяю, должна ли она выполняться. он позволяет выполнять остальную часть функции только в интервале с 9:00 до 10:00

void susCalibLoop() {

  const byte SUSCALIB_HOUR = 9;
  static boolean done = false;

  int hourNow = hour(now());

  if (hourNow != SUSCALIB_HOUR) {
    if (done) {
      done = false;
    }
    return;
  }
  if (done)
    return;
...
,

1

При долгосрочном учете времени вы столкнетесь с дрейфом часов и отклонениями от отслеживания тиков. Возможно, вам лучше использовать часы реального времени (RTC), например DS1307. Этот и подобные ему RTC часто доступны в коммутационных платах со встроенным держателем батарейки типа «таблетка».

Вы по-прежнему будете получать время из источника HTTP или NTP, но RTC будет намного лучше поддерживать «правильное» время, как вы ожидаете от наручных или настольных часов, по сравнению с использованием MCU для подсчета миллисекунд.

Вы можете использовать Ticks или millis(), чтобы настроить периодическое чтение RTC каждую секунду или каждые 10 секунд и т. д. Избегайте использования часов MCU для длительного хранения реального времени. .

,