Сообщение от
viktor__
Всем доброго времени суток!
Задача следующая:
1. При недостоверном сигнале (обрыв линии например...) нужно замораживать последнее достоверное значение и сигнализировать в HMI;
2. Необходимо иметь возможность изменять масштабирование и фильтры во время исполнения;
Поэтому я пишу свой функциональный блок для аналогового канала. В редакторе модуля отключаю все обработку (кроме Peack Filtr). Масштаб дефалт (0-20000.0), затем в блоке уже привожу его к физическому масштабу. В РП ПЛК160 сказано, что при неисправности сигнала\канала в старший байт результата записывается специальное значение (0x F1, 0x F6...). Непонятно, что происходит с остальными 3-мя байтами результата. Вопрос: как можно выяснить значение 1, 2, 3, либо 4 байта переменной типа REAL, есть ли для этого специальные функции, или нужно это делать вручную.
Можно-ли из приложения читать\писать значения Min FV и Max FV для аналогового канала?
При возникновении ошибки, в старших четырех битах выставляются единицы, в следующих 4-х битах следует код ошибки
Остальные три байта заполняются незначащей информацией.
Для декодирования ошибок измерения в библиотеке ОВЕН есть ФБ DECODE_FLOAT, но он лично меня не устраивает
-не работает в эмуляции
-при наличии ошибок измерения на выходе будет заранее предопределенное значение
По этому
Я вместо DECODE_FLOAT использую собственный ФБ аналогичного назначения
Код:
FUNCTION_BLOCK DECODE_AI
VAR_INPUT
ai: REAL; (*Датчик*)
END_VAR
VAR_OUTPUT
Rezultat: REAL; (*Результат*)
Cod_Err: BYTE; (*Код ошибки измерения*)
Err: BOOL; (*Наличее ошибки измерения*)
END_VAR
VAR
pt:POINTER TO DWORD;
bar:BYTE;
TMP:REAL; (*Значение до ошибки*)
END_VAR
Err:=TRUE; (*Установить ошибку измерений*)
pt:=ADR(ai);
bar:=DWORD_TO_BYTE(SHR(pt^,24));
CASE bar OF
16#F1: Cod_Err:=bar-240; (*1 Результаты измерения не верны*)
16#F6: Cod_Err:=bar-240; (*6 Результаты измерения не готовы*)
16#F7: Cod_Err:=bar-240; (*7 Канал отключен в конфигурации*)
16#F8: Cod_Err:=bar-240; (*8 *)
16#F9: Cod_Err:=bar-240; (*9 *)
16#FA: Cod_Err:=bar-240; (*10 Сигнал на входе больше возможного*)
16#FB: Cod_Err:=bar-240; (*11 Сигнал на входе меньше возможного*)
16#FC: Cod_Err:=bar-240; (*12 Перегрузка в канале измерения тока*)
16#FD: Cod_Err:=bar-240; (*13 Обрыв датчика*)
16#FE: Cod_Err:=bar-240; (*14 *)
16#FF: Cod_Err:=bar-240; (*15 *)
ELSE
Err:=FALSE;
Cod_Err:=0; (*Нет ошибок измерений*)
END_CASE
IF NOT Err THEN TMP:=ai;
END_IF
Rezultat:=TMP;
Отличия от DECODE_FLOAT
- работает в эмуляции;
- в момент ошибки измерения на выходе имеет последнее правильное значение, а не фиксированное значение. Т.е. по Вашему замораживает последнее достоверное значение
Последнее отличие позволяет игнорировать одиночные ошибки измерения, не "мельтешить" цифрами на HMI и не бросать PID в крайние положения. Ну а факт действительного отказа можно сделать через разумную задержку сигнала "Err" на выходе данного ФБ.
Код ошибки "Cod_Err" у меня идет на панель для динамического текста и там дешифруется
Текст 1 - "Результаты измерения не верны"
Текст 6 - "Результаты измерения не готовы"
Текст 10 - "Сигнал на входе больше возможного"
Текст 11 - "Сигнал на входе меньше возможного"
Текст 12 - "Перегрузка в канале измерения тока"
Текст 13 - "Обрыв датчика"
У меня в конфигурации аналоговых входах MinFV=4,00 MaxFV=20.00 Т.е так, как приходит с датчика 4-20 мА. Масштабирование диапазона измерения в программе, а не в конфигурации. Можно это делать с помощью того же LIN_TRAFO.
Вместо "из приложения нечитать\писать значения Min FV и Max FV для аналогового канала" нужно будет программно менять менять для LIN_TRAFO значения OUT_MIN и OUT_MAX
ЗЫ. Для эмуляции ошибок измерения использую свою функцию
Код:
FUNCTION Em_Err : REAL
VAR_INPUT
ai: REAL;
n_ERR: WORD:=0;
END_VAR
VAR
pt:POINTER TO DWORD;
END_VAR
pt:=ADR(ai);
CASE n_ERR OF
1: pt^:=pt^ OR 16#F1000000;
2: pt^:=(pt^ AND 16#00FFFFFF) OR 16#F6000000;
3: pt^:=(pt^ AND 16#00FFFFFF) OR 16#F7000000;
4: pt^:=(pt^ AND 16#00FFFFFF) OR 16#FA000000;
5: pt^:=(pt^ AND 16#00FFFFFF) OR 16#FB000000;
6: pt^:=(pt^ AND 16#00FFFFFF) OR 16#FC000000;
7: pt^:=(pt^ AND 16#00FFFFFF) OR 16#FD000000;
END_CASE
Em_Err:=ai;
На вход "ai" подаю сигнал с выхода аналогового канала ПЛК
При отладке, например в визуализации КДС, на вход "n_ERR" подаю код ошибки или "0".
А выход функции использую в программе вместо выхода аналогового канала ПЛК.
Захват-1.png
UPD.
Для тех кто не умеет "копипастить", во вложении готовые файлы для импорта в проект.