Добрый вечер. Много однотипных устройств, с которыми надо работать по модбасу, хотелось бы сделать свой класс объекта. Библиотека в целом для меня новая (без ООП пользовался стандартными возможностями среды), так столкнулся с тем, что внутри класса ФБ 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 без выполнения фактических команд записи). Успешно выполняется только команда чтения.
24.11.2025, 17:55
Евгений Кислов
Добрый день.
Цитата:
tcp_request.xExecute:=FALSE;
Эта строка ни на что не влияет.
Нужно сделать так:
Цитата:
tcp_request(xExecute:=FALSE);
И в других аналогичных фрагментах - тоже.
Тогда "нестандартное" поведение должно прекратиться.
25.11.2025, 09:53
crauler
Смотрю помощь Кодесиса по функциональным блокам, два примера, в одном переменные блока вызываются через точку, во втором через скобки. https://content.helpme-codesys.com/e...ion_block.html
Не могли бы подсказать, для вызова ФБ всегда следует использовать скобки, а точку только для именных пространств (программа, лист переменных, еще что-то)?
25.11.2025, 10:48
МихаилГл
Цитата:
Сообщение от crauler
Смотрю помощь Кодесиса по функциональным блокам, два примера, в одном переменные блока вызываются через точку, во втором через скобки. https://content.helpme-codesys.com/e...ion_block.html
Не могли бы подсказать, для вызова ФБ всегда следует использовать скобки, а точку только для именных пространств (программа, лист переменных, еще что-то)?
Возможно из-за этого:
Цитата:
inst1.iVar1 := 33; (* Вызывается FB1 и переменной iVar1 присваивается значение 33 *) inst1(); (* вызывается FB1, это необходимо для последующего доступа к выходной переменной *)
ires := inst1.out1 (* считывается выходная переменная out1 FB1 *)
Т.е. вы присваиваете, но не вызываете этот ФБ (хотя вызываете, но...)...
А когда пишите:
Цитата:
CMD_TMR(IN := %IX5.1, PT := T#100MS);
то это уже вызов с присвоением...
Я так думаю... Ну и в вашей ссылке так написано, если я правильно понял...