| Сторожевой таймер USB WatchDog ARU-P2 (uLua) Наш самый функциональный сторожевой таймер: встроенный язык программирования uLua позволяет модифицировать логику под самые разные задачи. |
Когда вы захотите расширить функционал, вам понадобится
-- Watchdog-like "~X" protocol parser.
-- Implemented:
-- ~U -> ~A, green blink, timer reset, escalation reset
-- ~I -> firmware/version text
local TIMER_MAX = 300000
local TIMER_MAX_RED_SCALE = 3000
local TIMER_DELTA = 50
local RESET_TIME = 200
local POWER_OFF_T1 = 5000
local POWER_OFF_DELAY = 3000
local POWER_OFF_T2 = 200
local RESET_PIN = hw.p6
local POWER_PIN = hw.p2
local GREEN_BLINK_MS = 120
local RED_BLINK_ON_MS = 120
local RED_STEADY_MS = 400
local VERSION_TEXT = "ARU-P2 watchdog uLua 1.0.0"
local STAGE_RESET = 0
local STAGE_POWER = 1
local PARSE_IDLE = 0
local PARSE_AFTER_TILDE = 1
function write_error()
hw.cdc_write("~E")
end
function pulse(pin, ms)
hw.gpio_set(pin, 0)
hw.delay_ms(ms)
hw.gpio_set(pin, 1)
end
hw.gpio_init(RESET_PIN, hw.out)
hw.gpio_init(POWER_PIN, hw.out)
hw.gpio_set(RESET_PIN, 1)
hw.gpio_set(POWER_PIN, 1)
hw.gled(false)
hw.rled(false)
local escalation_stage = STAGE_RESET
local timer_ms = TIMER_MAX
local green_ms = 0
local red_phase_ms = RED_BLINK_ON_MS
local parse_state = PARSE_IDLE
while true do
while hw.cdc_available() > 0 do
local b = hw.cdc_read()
if parse_state == PARSE_AFTER_TILDE then
parse_state = PARSE_IDLE
if b == 85 then
escalation_stage = STAGE_RESET
timer_ms = TIMER_MAX
red_phase_ms = RED_BLINK_ON_MS
green_ms = GREEN_BLINK_MS
hw.rled(false)
hw.gled(true)
hw.cdc_write("~A")
elseif b == 73 then
hw.cdc_write("~I" .. VERSION_TEXT)
else
write_error()
end
else
if b == 126 then
parse_state = PARSE_AFTER_TILDE
end
end
end
if green_ms > 0 then
green_ms = green_ms - TIMER_DELTA
if green_ms <= 0 then
green_ms = 0
hw.gled(false)
end
end
local red_interval = 0
if green_ms > 0 then
red_interval = -1
elseif timer_ms > RED_STEADY_MS then
red_interval = 300 + (27 * timer_ms) / TIMER_MAX_RED_SCALE
end
if red_interval < 0 then
hw.rled(false)
elseif red_interval == 0 then
hw.rled(true)
else
red_phase_ms = red_phase_ms + TIMER_DELTA
if red_phase_ms >= red_interval then
red_phase_ms = 0
end
if red_phase_ms < RED_BLINK_ON_MS then
hw.rled(true)
else
hw.rled(false)
end
end
hw.delay_ms(TIMER_DELTA)
timer_ms = timer_ms - TIMER_DELTA
if timer_ms <= 0 then
hw.rled(true)
if escalation_stage == STAGE_RESET then
pulse(RESET_PIN, RESET_TIME)
escalation_stage = STAGE_POWER
else
pulse(POWER_PIN, POWER_OFF_T1)
hw.delay_ms(POWER_OFF_DELAY)
pulse(POWER_PIN, POWER_OFF_T2)
escalation_stage = STAGE_RESET
end
timer_ms = TIMER_MAX
red_phase_ms = RED_BLINK_ON_MS
hw.rled(false)
end
end
hw.gpio_init(pin, mode)
Устанавливает режим hw.inp, hw.out, hw.pwm, hw.adc, hw.capture и т.д.
hw.gpio_init(hw.p1, hw.out)
hw.gpio_set(pin, value)
Устанавливает логический уровень 0 или 1.
hw.gpio_set(hw.p1, 1)
hw.gpio_get(pin) -> int
Читает уровень 0 или 1.
local level = hw.gpio_get(hw.p1) hw.gpio_init(hw.p5, hw.adc)
local v = hw.adc_read(hw.p5)
hw.pwm_init(pin, frequency_hz)
Инициализирует PWM на заданной частоте.
hw.pwm_set(pin, duty_percent)
Устанавливает duty cycle 0..100.
Пример:
hw.gpio_init(hw.p3, hw.pwm)
hw.pwm_init(hw.p3, 1000)
hw.pwm_set(hw.p3, 50) DHT22
hw.dht_temp(pin) -> int
Температура в десятых долях градуса Цельсия.
hw.dht_hum(pin) -> int
Влажность в десятых долях процента.
hw.gpio_init(hw.p1, hw.dht22)
local t = hw.dht_temp(hw.p1)
local h = hw.dht_hum(hw.p1) hw.delay_ms(ms)
Задержка в миллисекундах.
hw.uptime() -> int
Секунды с момента старта устройства.
hw.now() -> int
Миллисекунды с момента старта устройства.
hw.timer_after(ms, func[, arg1[, arg2]]) -> int
Однократный запуск таймера через ms.
hw.timer_every(ms, func[, arg1[, arg2]]) -> int
Периодический запуск таймера через ms.
hw.timer_cancel(timer_id)
Отмена таймера. hw.rled(on)
Управляет красным светодиодом.
hw.gled(on)
Управляет зелёным светодиодом.
Пример:
hw.rled(true)
hw.gled(false)