разобрался....
Вид для печати
Доброго дня,продолжу задавать глупые вопросы ...Код PLC_PRG:
IF GVL.Read THEN //кнопка для чтения ,устанавливается в визуализации в TRUE
MB_Fan_Read_1 (
Ip_DataConv:='192.168.0.7',
Start_Adress:=StartAdresRead);
GVL.Read:=FALSE; //сброс кнопки после чтения...
Смысл кода: при нажатии на кнопку выполнить MB_Fan_Read_1 и после чтения сбросить кнопку в FALSE....почемуто данные не читаются....
если сделать вот так :
MB_Fan_Read_1 (
Ip_DataConv:='192.168.0.7',
Start_Adress:=128);
без каких либо условий ,то все работает прекрасно...
понимаю что что то делаю не правильно но не могу понять что....Прошу помощи знатоков..
Да пока писал сам об этом и подумал....тоесть стоит перенести все это PLC_PRG...? или как можно вынести куски кода которые будут вызываться часто в отдельные файлы?
где бы про это почитать подробнее ...или можете пример привести как это оформить?
FUNCTION_BLOCK INTERNAL MB_Fan_Read
VAR_INPUT
Ip_DataConv: STRING;
Start_Adress: UINT;
END_VAR
VAR_OUTPUT
TcpClientError: BOOL ;
END_VAR
VAR
fbTcpClient: OCL.TCP_Client;
fbReadRequest: OCL.MB_TcpRequest;
awReadData: ARRAY [0..32] OF WORD;
eState: STATE_MB;
fbTon: TON;
xWriteToSlave: BOOL;
END_VAR
CASE eState OF
STATE_MB.CONNECTING:
fbTon (IN :=TRUE, PT := T#5S);
fbTcpClient
(
xEnable := TRUE ,
tTimeout := T#5S,
sIpAddr := Ip_DataConv,
uiPort :=502
);
IF fbTcpClient.xActive THEN
eState := STATE_MB.READ;
END_IF
IF fbTcpClient.xError OR fbTon.q THEN
fbTcpClient(xEnable :=FALSE);
fbTon(IN :=FALSE);
TcpClientError :=TRUE;
END_IF
STATE_MB.READ:
fbReadRequest
(
xExecute :=TRUE,
tTimeout :=T#50MS,
usiRetry :=3,
hConnection := fbTcpClient.hConnection,
xIsRtuOverTcpMode :=FALSE,
usiUnitId :=1,
eFuncCode :=OCL.MB_FC.READ_INPUT_REGISTERS,
uiDataAddr:=Start_Adress, // Начальный регистр
uiDataCount:=32,// колво регистров в запросе
pData:=ADR (awReadData),
szSize:=SIZEOF (awReadData)
);
IF fbReadRequest.xDone OR fbReadRequest.xError THEN
fbReadRequest(xExecute := FALSE);
ELSE
eState := STATE_MB.CONNECTING;
END_IF
END_CASE
GVL.Read:=FALSE;
Добрый день.
Не могу победить переменную TOD...
ПЛК200, весь софт актуализирован.
Код (эмуляция часов, для отладки перехода в следующие сутки). Это один из кусков эмулятора.
VAR
dtime_FD: BOOL;
t_w_on_FD: TOD := TOD#22:00:00;
c_time_TOD: TOD := TOD#00:00:00;
Timer_FD: TON;
cnt: WORD:=0;
END_VAR
Timer_FD(IN:=TRUE,PT:=T#200MS);
IF Timer_FD.Q THEN
c_time_TOD:=c_time_TOD +T#10M;
Timer_FD(IN:=FALSE);
END_IF
IF t_w_on_FD <= c_time_TOD THEN
dtime_FD := TRUE;
cnt := cnt+1;
END_IF
Вроде как TOD не может быть больше 23:59:59, следовательно - должны получить кольцо 00:00:00 / 23:59:59.
НО, условие: t_w_on_FD <= c_time_TOD выполняется только один раз. После первого перехода через ноль часов c_time_TOD всегда больше t_w_on_FD.
Если добавить:
IF c_time_TOD >= TOD#23:59:59 THEN
c_time_TOD := (c_time_TOD - T#23H59M59S);
END_IF
то все начинает работать.
Это проявляется (естественно) и при добавлении к TOD#22:00:00 допустим T#4H00M.
Полученные TOD#02:00:00 всегда больше (при сравнении) исходных TOD#22:00:00
Такое ощущение, что существует признак переполнения, и он учитывается компилятором....
Если использовать TIME, добавленный день виден и убирается, когда надо. Но везде в коде использовал TOD.
Когда понадобилось в алгоритмы добавить работу оборудования по таймеру с переходом через сутки, ничего не заработало...
Чего скажете, это косяк софта или я чего-то недопонимаю?
Можно как-то сбросить это суточное переполнение в TOD (без всяких сравнений) или проще перелопатить свой код под TIME?
Вложение 55385
Когда TOD в вашем случае равен 1h то внутри там на самом деле уже 25h. На самом деле если код немного по другому написать то компилятор будет отчаянно ругаться на операции сложения TOD и TOD например если сумма больше 24h.