| USB WatchDog ARU-P2 (uLua) Наш самый функциональный сторожевой таймер: встроенный язык программирования uLua позволяет модифицировать логику под самые разные задачи. |
Когда вы захотите расширить функционал, вам понадобится
-- Watchdog-like "~X" protocol parser built on top of cmd.
-- Each incoming frame must be terminated by CR or LF because cmd is line-based.
--
-- Implemented subset:
-- ~U -> ~A, green blink, timer reset, escalation reset
-- ~I -> firmware/version text
-- ~G -> temperature reply in "~Gxxxx" format
--
local TIMER_MAX = 5000
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.pa3
local POWER_PIN = hw.pa2
local TEMP_PIN = hw.p9
local GREEN_BLINK_MS = 120
local RED_BLINK_ON_MS = 120
local RED_STEADY_MS = 400
local VERSION_TEXT = "ARU-P2 watchdog uLua"
local STAGE_RESET = 0
local STAGE_POWER = 1
function write_error()
cmd.write("~E\n")
end
function pulse(pin, ms)
hw.gpio_set(pin, 1)
hw.delay_ms(ms)
hw.gpio_set(pin, 0)
end
function fmt_dec4(value)
if value < 0 then
value = 0
elseif value > 9999 then
value = 9999
end
if value < 100 then
if value < 10 then
return "000" .. value
end
return "00" .. value
end
if value < 1000 then
return "0" .. value
end
return "" .. value
end
hw.gpio_init(RESET_PIN, hw.out)
hw.gpio_init(POWER_PIN, hw.out)
hw.gpio_set(RESET_PIN, 0)
hw.gpio_set(POWER_PIN, 0)
hw.gpio_init(TEMP_PIN, hw.dht22)
cmd.echo(false)
hw.gled(false)
hw.rled(false)
local escalation_stage = STAGE_RESET
local timer_ms = TIMER_MAX
local green_ms = 0
local red_phase_ms = 0
while true do
if cmd.begin() then
if cmd.word("~U") then
if cmd.done() then
escalation_stage = STAGE_RESET
timer_ms = TIMER_MAX
red_phase_ms = 0
green_ms = GREEN_BLINK_MS
hw.gled(true)
hw.rled(false)
cmd.write("~A\n")
else
write_error()
end
elseif cmd.word("~I") then
if cmd.done() then
cmd.write(VERSION_TEXT .. "\n")
else
write_error()
end
elseif cmd.word("~G") then
if cmd.done() then
local temp_x10 = hw.dht_temp(TEMP_PIN)
cmd.write("~G" .. fmt_dec4(temp_x10) .. "\n")
else
write_error()
end
else
cmd.done()
write_error()
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 timer_ms > RED_STEADY_MS then
red_interval = 300 + (2700 * timer_ms) / TIMER_MAX
end
if 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)
end
timer_ms = TIMER_MAX
red_phase_ms = 0
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)