USB WatchDog ARU-P2 (uLua)
Наш самый функциональный сторожевой таймер: встроенный язык программирования uLua позволяет модифицировать логику под самые разные задачи.
Зачем нужны сторожевые таймеры?
Сторожевой таймер используется для контроля ПК и обеспечения его бесперебойной работы в случаях, когда встроенные средства не спасают.

Типовые примеры применения:
  • Обеспечение бесперебойной работы терминала.
  • Автономный компьютер выполняет работу без присмотра персонала.
  • Увеличение надёжности промышленного ПК.
  • GPU-майнер работает нестабильно, а программные средства не помогают.
Как это работает?
Сторожевой таймер подключается через USB интерфейс к ПК. Проводом он напрямую соединяется с контактами Reset или Power материнской платы.
Программа-монитор запускается на ПК и переодически передает сигнал устройству. Если компьютер завис, то зависает и программа: watchdog перестаёт получать сигнал. Через заданное время USB WatchDog автоматически подает сигнал на контакт Reset материнской платы, чтобы перезагрузить систему.
Если Reset не сработал, активируется канал Power, который выключает и снова включает компьютер.
Чем отличается от WatchDog Pro2
Благодаря встроенному языку программирования пользователь может изменять алгоритм работы в очень широких пределах. Пример программы устройства приведён в нижней части страницы.
Установка USB WatchDog ARU-P2
Это краткая инструкция, полную версию можно посмотреть на примере USB WatchDog Pro2. Открыть.

1. Перед установкой необходимо выключить ПК.
2. Так как устройство бескорпусное, будьте с ним предельно острожны - не допускайте касания металлических поверхностей. Это может привести к порче устройства!
3. Провода Reset и Power необходимо подключить вместо кнопок от системного блока.
4. Как подключать PBD10

Для при установке устройства в материнскую плату убедитесь, что вы подключаете именно к разъему USB. Некоторые интерфейсы (например ieee1394 или COM-порт) имеют на плате такие же 10-выводные разъемы.

Подключение к интерфейсу, отличному от USB, приведет к порче устройства
(возможно с дымом и запахом)!


  • На плате с PBD10 разъемом на плате имеется точка. При подключении к материнской плате ПК она должна быть совмещена со стороной разъема где отсутствует 1 металлический контакт
5. Сами кнопки можно подключить к сторожевому таймеру, чтобы ими тоже можно было пользоваться.
WatchDog Pro2 PBD10
Осн.1 и Доп.1. - параллельно соединённые контакты канала 1. По-умолчанию, подключаются к контактам Reset: например, Осн.1 - на reset мат.платы и Доп.1 - на кнопку reset.
Осн.2 и Доп.2. - параллельно соединённые контакты канала 2. По-умолчанию, подключаются к контактам Power: например, Осн.2 - на power мат.платы и Доп.2-
на кнопку power.
Пример подключения к материнской плате
Драйвер
Работа в ОС ниже Windows7 не поддерживается.
В Windows7 понадобится установить драйвер CDC.
В Windows 8, Windows 10, Linux, macOS установка драйвера не требуется.
Если в Windows8 не заработал системный драйвер CDC, воспользуйтесь инструкцией.
wdtmon3
Программа, которая работает с USB WatchDog Pro2, Lite.

В ARU-P2 поддержан следующий функционал программы:
1. Контроль зависания, процесса, сетевого ресурса.
2. Информация об устройстве;
3. Температура
4. Пауза
5. Тестовый Reset и Power.
6. Отключение светодиода.

Прим.: wdtmon3 не изменяет настроек USB WatchDog ARU-P2, это нужно делать из кода программы.

Скачать Win/Lin/OSX
Страница подробной инструкции по программе доступна по ссылке.
Почему Lua ?

Хотя Lua далеко не самый распространенный язык, он имеет ряд больших преимуществ:
  • предназначен для пользователей, не являющихся профессиональными программистами, вследствие чего большое внимание уделено простоте дизайна и лёгкости обучения;
  • простой паскалеподобный синтаксис, известный многим еще со школы;
  • минимум синтаксиса (а в нашей версии еще меньше);
Реализация UnitX Lua
Не смотря на то, что Lua и так очень маленький язык, в такой микроконтроллер его не поместить, а иметь возможность удобно управлять логикой работы очень хочется.
Поэтому мы сделали свою упрощенную реализацию. Получился хороший компромисс для встраиваемых систем, где критичны размер кода и скорость выполнения.
Поддерживается

  • local переменные (int32);
  • арифметика и битовые операции;
  • if, while, repeat, for, break;
  • функции;
  • строки;
  • готовые функции для работы с периферией: io, pwm, adc, cc, ws2812 и т.д.
Не поддерживается

  • таблицы
  • GC
  • замыкания
  • типы данных, кроме строк и int32
  • динамический runtime с `require` и общими Lua-механиками


Когда вы захотите расширить функционал, вам понадобится

Руководство программиста
  • Подключите контроллер к компьютеру по USB
  • Откройте онлайн IDE, нажмите "Подключиться" и выберите порт устройства.
Код устройства
Код, который зашит по-умолчанию. Базовый функционал сторожевого таймера.
-- 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
  • Ваш контроллер уже с программой, поэтому нужно нажать "Остановить", потом "Скомпилировать".
  • Если ошибок нет, то далее можно "Загрузить", если хотите просто запустить код, либо "Сохранить", если хотите, чтобы он остался в устройстве.
Шпаргалка по языку
Подробное описание языка и доступные библиотеки доступны по ссылке.
Работа с GPIO
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)
Работа с PWM
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)
Работа с датчиком температуры-влажности DTH22
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)
Дополнительные ресурсы

  • Большая инструкция USB WatchDog
    В прошивке по-умолчанию устройство частично повторяет поведение USB WatchDog Pro2, поэтому инструкция, ПО и скрипты подходят к обоим типам устройств. Открыть.
  • Описание uLua
    Полное описание возможностей находится по ссылке.