плк110-60[М2], среда codesys2.3.Опрашиваю модули МВ210-101. Если модуль отключен, то "Адресс последнего опрошенного Slave-устройства" = 0. как мне узнать, что опрос не был выполнен и модуль отключен?
*с RS485 адрес возвращается всегда.
ниже моя реализация. ФБ взял с этого форума. как реализовать непринципиально.
цель - знать, что какой-то модуль перестал работать и какой именно
VAR
*Контроль связи с модулями*)
MC:ModbusErrorsControl;
(*Ethernet, адреса ..101-103*)
wLA_Eth AT %QD7.0: DWORD; (* Адресс последнего опрошенного Slave-устройства - из конфигурации плк *)
i_ip_delta: DWORD:=100;(*для вычисления индекса по последней цифре ip адреса *)
wLE_Eth AT %QW7.1:WORD;(* Номер последней ошибки - из конфигурации плк *)
wLE_Eth_ :WORD;(*дублер*)
(*RS485, адреса 1..6*)
wLA_RS AT %QD8.0: DWORD; (* Адресс modbus последнего опрошенного Slave-устройства - из конфигурации плк *)
wLE_RS AT %QW8.1:WORD;(* Номер последней ошибки - из конфигурации плк *)
i_E: ARRAY[2..10] OF UDINT:=0,0,0,0,0,0,0,0,0;(* Счетчик ошибок связи *в схеме модули А2-А10, поэтому и массив такой для удобства*)
i_T: ARRAY[2..10] OF UDINT:=1,1,1,1,1,1,1,1,1;(* Счетчик успехов связи *)
x_I:ARRAY[2..10] OF BOOL:=TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE;(* Признак ошибки связи *)
k_E:ARRAY[2..10] OF REAL;
i_adr: DWORD;
END_VAR
(*ошибки связи*)
(**)
i_adr:=wLA_Eth AND 16#FF - i_ip_delta+1;wLE_Eth_:=wLE_Eth;
MC(uiAddrNeedToControl:=i_adr,
wLastModbusAddr:=i_adr,
wLastModbusError:=wLE_Eth_,
i_E_in:=i_E[i_adr],
i_T_in:=i_T[i_adr],
iModbusErrorsCount=>i_E[i_adr],
xIsModbusError=>x_I[i_adr],
i_T=>i_T[i_adr] );
(**)
MC(uiAddrNeedToControl:=wLA_RS,
wLastModbusAddr:=wLA_RS,
wLastModbusError:=wLE_RS,
i_E_in:=i_E[wLA_RS+4],
i_T_in:=i_T[wLA_RS+4],
iModbusErrorsCount=>i_E[wLA_RS+4],
xIsModbusError=>x_I[wLA_RS+4],
i_T=>i_T[wLA_RS+4] );
FOR i:=2 TO 10 DO
k_E[i]:=UDINT_TO_REAL(i_E[i])/UDINT_TO_REAL((i_T[i]+i_E[i]));
END_FOR
(* ФБ для индикации и подсчтеа ошибок Modbus для указанного Slave-устройства *)
(* В момент, когда номер последнего опрошенного Slave-устройства совпадет с
uiAddrNeedToControl ФБ проверит наличие ошибки связи "wLastModbusError > 0".
Если ошибка связи с этим устройством есть: установится признак наличия ошибки
связи xModbusError до следующего цикла связи с этим устройством, счетчик
ошибок связи с заданным Slave-устройством iModbusErrorsCount увеличиться на 1.
По команде xReset счетчик ошибок iModbusErrorsCount обнулиться, xIsModbusError
сбросится в FALSE *)
FUNCTION_BLOCK ModbusErrorsControl
VAR_INPUT
(* Адрес Slave-устройства с которым мониторится связь *)
uiAddrNeedToControl : DWORD;
(* Адресс последнего опрошенного Slave-устройства - из конфигурации плк *)
wLastModbusAddr : DWORD;
(* Номер последней ошибки - из конфигурации плк *)
wLastModbusError : WORD;
(* Команда на сброс блока *)
xReset : BOOL;
i_E_in:UDINT;
i_T_in:UDINT;
END_VAR
VAR_OUTPUT
(* Счетчик ошибок связи *)
iModbusErrorsCount : UDINT;
(* Признак ошибки связи *)
xIsModbusError : BOOL;
i_T:UDINT;
END_VAR
VAR
m_fbResetDetector : R_TRIG;
END_VAR
(* Фиксирование переднего фронта импульса команды Reset *)
m_fbResetDetector.CLK := xReset;
m_fbResetDetector ();
xIsModbusError := TRUE;(*при ошибке tcp вместо адреса возвр 0*)
iModbusErrorsCount:=i_E_in;
i_T:=i_T_in;
IF uiAddrNeedToControl = wLastModbusAddr THEN
IF wLastModbusError > 0 THEN
iModbusErrorsCount := i_E_in +1;
xIsModbusError := TRUE;
ELSE
xIsModbusError := FALSE;
i_T:=i_T_in+1;
END_IF
END_IF
(* Сброс блока *)
IF m_fbResetDetector.Q THEN
iModbusErrorsCount := 0;
xIsModbusError := FALSE;
END_IF
Безымянный.png