Таймер 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; //истек второй таймер, затем триггер
}
Спасибо!
@SF1, 👍0
Обсуждение2 ответа
Я описываю, как я это делаю в своем проекте. Я использую библиотеку времени, также известную как 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;
...
При долгосрочном учете времени вы столкнетесь с дрейфом часов и отклонениями от отслеживания тиков. Возможно, вам лучше использовать часы реального времени (RTC), например DS1307. Этот и подобные ему RTC часто доступны в коммутационных платах со встроенным держателем батарейки типа «таблетка».
Вы по-прежнему будете получать время из источника HTTP или NTP, но RTC будет намного лучше поддерживать «правильное» время, как вы ожидаете от наручных или настольных часов, по сравнению с использованием MCU для подсчета миллисекунд.
Вы можете использовать Ticks или millis()
, чтобы настроить периодическое чтение RTC каждую секунду или каждые 10 секунд и т. д. Избегайте использования часов MCU для длительного хранения реального времени. .
- Как читать и записывать EEPROM в ESP8266
- Как сделать выводы Tx и Rx на ESP-8266-01 в выводах GPIO?
- Как навсегда изменить скорость передачи данных ESP8266 (12e)?
- Как заставить 5-вольтовое реле работать с NodeMCU
- Как исправить: Invalid conversion from 'const char*' to 'char*' [-fpermissive]
- ESP8266 не подключается к Wi-Fi
- AT-команда не отвечает на последовательный монитор
- Разница между этими двумя платами NodeMCU?
вы думаете, что уловили именно ту миллисекунду, которая вызывает событие?, @Juraj
было бы лучше установить время в TimeLib, а затем проверить, сейчас 9 утра или 18 вечера., @Juraj
Действительно. Вы также можете использовать NTP, чтобы получить текущее время из Интернета и передать его в TimeLib., @Majenko
настройте переменную
tick
... увеличивайте ее внутри цикла() каждую секунду или каждую минуту (даже каждый час... как вам удобно).... затем просто отслеживайте значениеtick
, @jsotolaспасибо, так что: - Я не думаю, что смогу уловить точную мс, чтобы вызвать событие, и я ищу предложения, как это сделать. - Я попробовал NTP, и возникли проблемы с часовым поясом, поэтому http-запрос является хорошей заменой. - Хорошо для переменной галочки, но я все еще немного не понимаю, как повернуть все за 24 часа (с исходного времени). - Я проверю TimeLib (я полагаю, это библиотека?), @SF1