Полезные советы

Материал из WebHMI Wiki
Версия от 21:40, 10 ноября 2016; Evgeniy.mozoliak (обсуждение | вклад) (ПИД - регулятор)

Перейти к: навигация, поиск

Запуск скрипта по фронта или срезу дискретного сигнала

Скрипт нужно вызываеть по изменению регистра. Внутри скрипта нужно сделать проверку текущего состояния этого регистра и выполнять соответветсующие действия либо по фронту (текущее состояние =1), либо по срезу (=0). Пример скрипта:

Rising edge.png

Создание переключателя

Элемент слайдер можно использовать для управления типа открыть- закрыть, вкл.-выкл. и т.п. Для этого нужно "привязать" его к битовому регистру и указать опцию "user can change value" на дешборде. Также такой слайдер наглядно может отобразить положение переключателя (ручн. - акт., местное - дистанционное управение), заслонки , шибера и т.д.

Реализация таймера - задержки включения (TON)

Таймер TON начинает отчет пока вход = 1, по истечении времени задержки выход тоже устанавливается в "1".

TIMER_DELAY = 20; -- задержка таймера 20 сек. 
tmr = false; -- начальное состояние - отсчет времени не идет  
tmrStartTime = 0; -- время начала работы таймера 
-- 
function main (userId)
  -- переменные 
  local in_value = (GetReg(212) == 1); -- Просто бит (D301@WebHMI)
  local now = GetReg(28); -- Текущее время (T0@WebHMI)
-- ПРОВЕРЯЕМ УСЛОВИЕ - СОСТОЯНИЕ ВХОДА ----------
if in_value then
    if not tmr then
        tmr = true;
        tmrStartTime = now; -- запомнить время начала отсчета
    else 
        if ( now - tmrStartTime ) > TIMER_DELAY then 
            -- действие по истечении таймера 
            WriteReg("TON_out", 1); -- сигнал таймера , битовый регистр с псевдонимом "TON_out"
        end
    end    
else 
tmr = false;
tmrStartTime = 0;
WriteReg("TON_out", 0); -- сигнал таймера 
end
-- КОНЕЦ  
end

Звуковая (релейная) сигнализация об ошибках связи

В WebHMI имеются buzzer для подачи звукового сигнала, и выходные реле 2 шт. , которыми можно управлять для сигнализации (выдать на сигнальную колонну либо в ПЛК сигнал о проблеме). Алгоритм подачи сигнализации может быть такой:

  • анализировать регистр С0 (внутренний регистр - см. описание здесь ) на неравенство 0 в течении заданного интервала , например 30 секунд, используя таймер - скрипт lua.
  • после установки сигнала от таймера, можно выдавать сигналы на встроенный динамик через регистр B0, либо включать реле через внутр. регистры DO0,DO1, отправить смс или сообщение в messenger telegram .

ПИД - регулятор

Пример реализации ПИД регулятора в WebHMI:

-- глобальные переменные, сохраняются между вызовами скрипта
Kp = 1; -- пропорциональная составляющая
Ti = 0.9; -- инт. составляющая
Td = 1;  -- дифф. составляющая
SampleTime = 10 ; -- время цикла ПИД
TimeStamp = 0; -- метка для запоминания времения последнего вызова
Limit = 100; -- ограничение выхода регулятора
Int_sum = 0; -- интегральный накопитель
--
function main (userId)
  -- локальные переменные 
  local now = GetReg("SysTime"); -- Время 
  local PV = GetReg("PID_PV"); -- PV (D14@Тест) обратная связь 
  local Sp = GetReg("PID_Sp"); -- Sp (D10@Тест) задание 
  local prevErr = 0.0; -- предыдущая ошибка для вычисления дифф. составляющей
--
  if (TimeStamp == 0) then 
        TimeStamp = now; -- запомнить время входа в цикл
        --
        local  Err =  PV - Sp; -- вычисляем ошибку 
        local dErr = Err - prevErr; -- вычисляем производную ошибки 
            -- проверяем интегральное насыщение 
        local iSum_Limit = Limit * Ti / (Kp);
        if (Int_sum <= iSum_Limit) and (Int_sum >= 0.0) then
            Int_sum = Int_sum + Err; -- накапливаем интеграл ошибки 
        elseif Int_sum < 0 then
            Int_sum = 0;
        else
            Int_sum = iSum_Limit; -- ограничиваем интегральную составляющую
        end;
        -- ПИД - регулятор 
        G = Kp * (Err + (1/Ti)*Int_sum + Td*dErr);
        -- проверка выхода за диапазон 
        if G < 0 then
            G = 0;    
        end
        if G > Limit then
            G = Limit;
        end
        prevErr = Err; -- запомнить предыдущую ошибку для след. скана
        WriteReg("PID_out", G); -- Выход ПИД (D0@Тест) записать в регистр
  else
      if (now - TimeStamp > SampleTime ) then -- проверка начала цикла работы 
          TimeStamp = 0; 
      end 
  end
end

Данный алгоритм является типовым для применения в ПЛК. Поскольку регулятор выполняется через равные интервалы времени, т.е. дифф. и инт. составляющие всегда вычисляются в одном мастштабе времени, поэтому делить и умножать их на время для получения производной и интеграла необязательно, можно подбирать постоянные времени Ti, Td. В данном алгоритме Ti является обратной величиной (чем больше ее величина, тем меньше вклад интегральной ошибки)

Счетчик моточасов

Счетчик моточасов удобен для автоматической генерации сообщения о необходимости регламенных работ для узла оборудования, смены ведущего насоса в насосной группе для выравнивания наработки и т.п.

Пример реализации счетчика моточасов на Lua в WebHMI:

-- глобальные переменные, сохраняются между вызовами скрипта
run_state = false; -- для запоминания текущего состояния 
function main (userId)
  local check_mask = tonumber("0000100000000000",2); -- маска для проверки бита вращения в частотном приводе FC 51 Danfoss
  local run_status = (bit.band(GetReg(109),check_mask) ~= 0); -- результат проверка как переменная типа bool 
  local now = os.time(); -- текущее время системы 
  local time_diff = 0; -- разница во времени между текущим временем и временем последнего вызова

  -- ловим фронт события включения механизма для инициализации
  if (not run_state) and run_status then 
      WriteReg("P43StartTime", now); -- Время старта привода №П43

  -- считаем время 
 if run_state then 
     time_diff = (now - GetReg("P43StartTime")); -- посчитать разницу времени
     WriteReg("P43RunTime", GetReg("P43RunTime")+time_diff); -- увеличить счетчик моточасов
     WriteReg("P43StartTime", now); -- переписать начальную точку времени 
 end 
 run_state = run_status; 
end

Регистры хранения моточасов и метки времени нужно делать энергонезависимыми.