crauler
24.11.2025, 17:40
Добрый вечер. Много однотипных устройств, с которыми надо работать по модбасу, хотелось бы сделать свой класс объекта. Библиотека в целом для меня новая (без ООП пользовался стандартными возможностями среды), так столкнулся с тем, что внутри класса ФБ TCP request ведет себя нестандартно. Блок объявляю внутри класса (не ввод, не вывод).
Из самого очевидного, при 0 на входе xExecute, блок выдает постоянную единицу на выход xDone. В тесте одиночного ФБ xDone дает 0 как только я подаю 0 на xExecute.
trigger.CLK:=tcp_request.xDone;
testvar:=tcp_request.xDone;
requestcheck:=trigger.Q;
CASE iconnection_stage OF
0: //подключение к устройству
tcp_client (
xEnable:=TRUE,
tTimeout:=T#5000MS,
sIpaddr:=sIpaddress,
uiport:=502
);
IF tcp_client.xActive=TRUE
THEN iconnection_stage:=1; //если соединение установлено то переходим дальше
END_IF
IF tcp_client.xError=TRUE
THEN tcp_client.xEnable:=FALSE;
END_IF
1: //проверка устройства
tcp_request ( //проверяем состояние линий
xExecute:=TRUE,
tTimeout:=T#1000MS,
usiretry:=3,
hconnection:=tcp_client.hConnection,
xIsRtuOverTcpMode:=FALSE,
eFuncCode:=16#1,
uiDataAddr:=20009,
uiDataCount:=5,
pData:=ADR(linecheck),
szsize:=SIZEOF(linecheck)
);
IF requestcheck=TRUE //добавить какую-то реакцию на невыполнение операции
THEN
tcp_request.xExecute:=FALSE;
IF linecheck=0
THEN iconnection_stage:=3;//если на линиях ничего нет, то можно работать с оповещением
ELSE currentaddress:=20009;
iconnection_stage:=2;//если на линиях что-то записано надо сначала это стереть
END_IF
ELSE tcp_request.xExecute:=FALSE;//пока просто попробовать сначала если не получилось
END_IF
IF tcp_client.xError=TRUE OR tcp_client.xDone //если ошибка или закрытие соединения то начать сначала
THEN tcp_client.xEnable:=FALSE;
iconnection_stage:=0;
END_IF
До этого пробовал без триггера, но там также были свои проблемы (программа пролетала все проверки xDone без выполнения фактических команд записи). Успешно выполняется только команда чтения.
Из самого очевидного, при 0 на входе xExecute, блок выдает постоянную единицу на выход xDone. В тесте одиночного ФБ xDone дает 0 как только я подаю 0 на xExecute.
trigger.CLK:=tcp_request.xDone;
testvar:=tcp_request.xDone;
requestcheck:=trigger.Q;
CASE iconnection_stage OF
0: //подключение к устройству
tcp_client (
xEnable:=TRUE,
tTimeout:=T#5000MS,
sIpaddr:=sIpaddress,
uiport:=502
);
IF tcp_client.xActive=TRUE
THEN iconnection_stage:=1; //если соединение установлено то переходим дальше
END_IF
IF tcp_client.xError=TRUE
THEN tcp_client.xEnable:=FALSE;
END_IF
1: //проверка устройства
tcp_request ( //проверяем состояние линий
xExecute:=TRUE,
tTimeout:=T#1000MS,
usiretry:=3,
hconnection:=tcp_client.hConnection,
xIsRtuOverTcpMode:=FALSE,
eFuncCode:=16#1,
uiDataAddr:=20009,
uiDataCount:=5,
pData:=ADR(linecheck),
szsize:=SIZEOF(linecheck)
);
IF requestcheck=TRUE //добавить какую-то реакцию на невыполнение операции
THEN
tcp_request.xExecute:=FALSE;
IF linecheck=0
THEN iconnection_stage:=3;//если на линиях ничего нет, то можно работать с оповещением
ELSE currentaddress:=20009;
iconnection_stage:=2;//если на линиях что-то записано надо сначала это стереть
END_IF
ELSE tcp_request.xExecute:=FALSE;//пока просто попробовать сначала если не получилось
END_IF
IF tcp_client.xError=TRUE OR tcp_client.xDone //если ошибка или закрытие соединения то начать сначала
THEN tcp_client.xEnable:=FALSE;
iconnection_stage:=0;
END_IF
До этого пробовал без триггера, но там также были свои проблемы (программа пролетала все проверки xDone без выполнения фактических команд записи). Успешно выполняется только команда чтения.