ESP8266 NodeMCU timer, rtc, SNTP, cron
Розглянемо роботу таймерів, лічильників, Watchdog, годинника реального часу, синхронізацію часу з Інтернетом, та cron. Словом все, що має відношення до часу. У NodeMCU можна використовувати 7 таймерів, за допомогою яких запускати потрібні функції через певний час. Роботу таймерів забезпечує модуль tmr.
Ініціалізація таймерів виконується функцією tmr.register([id/ref], interval_ms, mode, func())
[id/ref] - id таймера (0-6), або объект таймера створеного за допомогою функції tmr.create() interval_ms - інтервал у мілісекундах. Максимальне значення 6870947 mode - режим таймера:
- tmr.ALARM_SINGLE - спрацьовує лише один раз. Не треба викликати tmr.unregister()
- tmr.ALARM_SEMI - спрацьовує один раз. Для повтору треба викликати tmr.start()
- tmr.ALARM_AUTO - циклічний перезапуск таймера
func(timer) - функція зворотного виклику, яка викликається з об`єктом таймера в якості аргументу.
Функція може бути описана окремо (як це зроблено у прикладі для таймеру 0), або описана у функції tmr.register() (як це зроблено у прикладі для таймеру 1).
Приклад ініціалізація таймерів:
function timer_do()
print(`timer 0`)
end
-- Start timer
tmr.register(0, 1000, tmr.ALARM_AUTO, timer_do)
tmr.start(0)
-- Start timer
tmr.register(1, 3000, tmr.ALARM_AUTO, function() print("timer 1") end)
tmr.start(1)
-- tmr.register + tmr.start = tmr.alarm
-- Just once
tmr.alarm(2, 5000, tmr.ALARM_SINGLE, function() print("timer 2") end)
-- Just once. Repeat manually by tmr.start(3)
tmr.alarm(3, 1000, tmr.ALARM_SEMI, function() print("timer 3") end)
Функція tmr.alarm поєднує у собі tmr.register та tmr.start. Тобто, вона виконує ініціалізацію і запуск таймера.
Зупинити таймер можна командою tmr.stop([id/ref]) [id/ref] - id таймера (0-6), або об’єкт таймера створеного за допомогою функції tmr.create()
Приклад створення і використання таймеру як об`єкту:
-- Creates a dynamic timer object
local mytimer = tmr.create()
-- oo calling
mytimer:register(5000, tmr.ALARM_SINGLE, function (t) print("expired"); t:unregister() end)
mytimer:start()
Або:
-- Creates a dynamic timer object
local mytimer = tmr.create()
-- with self parameter
tmr.register(mytimer, 5000, tmr.ALARM_SINGLE, function (t) print("expired"); tmr.unregister(t) end)
tmr.start(mytimer)
Затримка
Якщо у програмі потрібно використати затримку, Вам допоможе функція tmr.delay(us) us - мікросекунди
Приклад затримки на 2 секунди:
print(`Begin`)
-- 2sec delay
tmr.delay(2000000)
print(`End`)
Системний лічильник
Після старту NodeMCU запускає системний лічильник. Він лічить мікросекунди і має розрядність 31-біт. Приклад зчитування системного лічильника:
--return system counter, which counts in microseconds. (31-bit)
print(tmr.now())
Дізнатися Uptime можна наступною командою:
--Print uptime
print("Uptime (probably):", tmr.time())
Watchdog
Модуль tmr також забезпечує роботу програмного watchdog. Задача watchdog перезавантажити систему при зависанні або під час збоїв у програмі. watchdog-у задається час, через який він має перезавантажити систему, і якщо за цей час watchdog не вимкнути, тоді відбудеться перезавантаження. Зазвичай роблять так. Перед операціями, які можуть визвати зависання, вмикають watchdog, а по завершенню вимикають. Якщо операція не закінчилася за вказаний watchdog-у час, вважається що процес завис і watchdog викликає перезавантаження системи.
Час watchdog-у задається функцією tmr.softwd(s) у секундах. Після чого watchdog відразу починає роботу. Щоб вимкнути watchdog, треба виконати команду tmr.softwd(-1)
Приклад:
-- Wait 2 seconds. If the watchdog is not disabled, then reboot.
tmr.softwd(2)
print("Soft watchdog enabled!")
-- It`s OK (1 sec)
tmr.register(0, 1000, tmr.ALARM_SINGLE, function() tmr.softwd(-1) print("Soft watchdog disabled!") end)
tmr.start(0)
-- It`s NOT OK. Watchdog reboots system before it`s will disabled
--tmr.register(0, 3000, tmr.ALARM_SINGLE, function() tmr.softwd(-1) print("Soft watchdog disabled!") end)
--tmr.start(0)
У прикладі відключення watchdog-а виконується по таймеру. Це зроблено виключно для демонстрації.
Годинник реального часу
За роботу годинника реального часу відповідає модуль rtctime. Дізнатися поточний час можна наступним чином:
tm = rtctime.epoch2cal(rtctime.get())
print(string.format("%04d/%02d/%02d %02d:%02d:%02d", tm["year"], tm["mon"], tm["day"], tm["hour"], tm["min"], tm["sec"]))
Відразу після старту NodeMCU, годинник стоїть. Щоб годинник почав працювати слід задати йому час у секундах від 1970 року. Приклад:
-- Set time to 2015 July 9, 18:29:49
rtctime.set(1436430589, 0)
-- Set time to 2017 Jan 11, 00:00:00
rtctime.set(1484092800, 0)
SNTP - синхронізація часу через інтернет
Якщо Ваш NodeMCU підключений до WiFi і має доступ до Інтернет, тоді можна синхронізувати час за допомогою протоколу SNTP. За реалізацію цього протоколу відповідає модуль sntp.
Можна просто запустити команду:
sntp.sync()
Синхронізація запуститься з використання NTP серверів, які зазначені у NodeMCU. Приклад скрипта, який виводить результат синхронізації:
-- Use the nodemcu specific pool servers
sntp.sync(nil,
function(sec, usec, server, info)
print(`sync`, sec, usec, server)
tm = rtctime.epoch2cal(rtctime.get())
print(string.format("%04d/%02d/%02d %02d:%02d:%02d", tm["year"], tm["mon"], tm["day"], tm["hour"], tm["min"], tm["sec"]))
end,
function()
print(`failed!`)
end
)
Коли у локальній мережі існує власний NTP сервер, наприклад з адресою 192.168.1.1, можна вказати її для синхронізації:
-- Single shot sync time with a server on the local network.
sntp.sync(`192.168.1.1`,
function(sec, usec, server, info)
print(`sync`, sec, usec, server)
tm = rtctime.epoch2cal(rtctime.get())
print(string.format("%04d/%02d/%02d %02d:%02d:%02d", tm["year"], tm["mon"], tm["day"], tm["hour"], tm["min"], tm["sec"]))
end,
function()
print(`failed!`)
end
)
Cron (scheduler)
Існують задачі, які потрібно запускати періодично і синхронно з реальним часом. Наприклад, вмикати будильника кожен день о 7:00, кормити рибок кожні 6 годин. Через день у вечері поливати помідорчики, і так далі.
Для цього звичайні таймери не підходять. За допомогою модуля cron, разом з модулем rtctime, можна організувати планувальник задач (scheduler).
Приклад:
function my_schedule()
tm = rtctime.epoch2cal(rtctime.get())
print("It`s Cron.")
print(string.format("%04d/%02d/%02d %02d:%02d:%02d", tm["year"], tm["mon"], tm["day"], tm["hour"], tm["min"], tm["sec"]))
end
-- Cron. Every minute
cron.schedule("* * * * *", my_schedule)
У прикладі функція my_schedule викликається кожну хвилину. Тобто, у момент коли на годинниках реального часу починається нова хвилина. Маска пишеться так само як і в crontab.
Приклади:
cron.schedule("*/5 * * * *", function(e)
print("Every 5 minutes")
end)
cron.schedule("0 * * * *", function(e)
print("Every hours")
end)
cron.schedule("0 */2 * * *", function(e)
print("Every 2 hours")
end)
cron.schedule("0 0 * * *", function(e)
print("Every midnight")
end)
cron.schedule("0 7 * * *", function(e)
print("Every day at 7 o`clock")
end)
cron.schedule("0 0 1 * *", function(e)
print("Every midnight of first day of month")
end)
Бажаю успіхів.
P.S. Нагадаю, що зібрати NodeMCU з потрібними модулями можна на сайті https://nodemcu-build.com/
Дивись також:
- ESP8266 NodeMCU Перше знайомство. Робимо WiFi розетку
- ESP8266 NodeMCU. PWM
- ESP8266 NodeMCU. ADC
- ESP8266 NodeMCU. timer, rtc, SNTP, cron
- ESP8266 NodeMCU. файлова система, SD Card
- ESP8266 NodeMCU. UART
- GPS-трекер на базі ESP8266
- GPS-трекер + Дисплей SSD1306
- ESP8266 NodeMCU. SSD1306. U8G
- ESP-01 (ESP8266) upgrade flash memory to 4MB
- ESP8266 NodeMCU. I2C. BME280/
- Метеостанція на ESP8266
Добрый день! Можете предоставить, пожалуйста, тестовый вариант программы sntp (синхронизация времени)? Я добавил в код подключение к WI-FI, однако программа не заработала :( Спасибо!
Tags
bme280 bmp280 gps mpu-6050 options stm32 ssd1331 ssd1306 eb-500 3d-printer soldering tim mpu-9250 dma watchdog piezo exti web raspberry-pi docker ngnix solar bluetooth foc html css brushless flask dc-dc capture gpio avr rs-232 mpx4115a atmega mongodb st-link barometer pwm nvic git java-script programmator dht11 hih-4000 pmsm encoder max1674 smd sensors rtc adc lcd motor timer meteo examples i2c usb flash sms rfid python esp8266 servo books bldc remap eeprom bkp battery ethernet uart usart displays led websocket nodemcu wifi
Архіви