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, однако программа не заработала :( Спасибо!
Недавні записи
- Text to speech. Українська мова
- LCD Display ST7567S (IIC)
- Розпізнавання мови (Speech recognition)
- Selenium
- Комп'ютерний зір (Computer Vision)
- Деякі думки про точність вимірювань в електроприводі
- Датчики Холла 120/60 градусів
- Модуль драйверів напівмосту IGBT транзисторів
- Драйвер IGBT транзисторів на A316J
- AS5600. Варіант встановлення на BLDC мотор
Tags
docker sensors rtc led timer wifi remap sms css websocket mongodb bme280 rfid bluetooth esp8266 nodemcu bkp piezo bmp280 i2c mpu-6050 encoder examples avr brushless ngnix nvic displays bldc java-script pmsm barometer pwm lcd ethernet stm32 raspberry-pi capture usart gpio exti atmega meteo solar smd dma adc eeprom eb-500 flask python ssd1306 uart options flash mpx4115a html gps st-link 3d-printer servo dc-dc foc git books battery hih-4000 watchdog dht11 web tim programmator ssd1331 mpu-9250 usb rs-232 motor max1674 soldering
Архіви