Сообщение от
Easy_Enemy
Как ни странно, приведя в пример шлюз дайкин - из 50+ устройств исключительно с ним больше всего приключений. В данный момент - не хочет опрашиваться в цикле. В чем суть - есть 5 регистров на чтение, 5 на запись. 7 файнкойлов. Каждый последующий койл хранит для себя данные, начиная от первого и +6 регистров. То есть, фактически, сводится к написанию 10 циклов For с параметром регистра StartRegister1 + ((CurrentCon-1)*6). Но, по каким-то причинам, данный шлюз так опрашиваться не хотит.. То есть, если мы пишем следующую конструкцию, то все данные у нас - нулевые. При этом - ошибок нет. В буфере мы видим наши данные, ошибки не копятся, ибо модуль ответил и все ок.
IF Mdl.ExecStep = 1 THEN
FOR CurrentCon:=1 TO 7 DO
Mdl.pDisp^.GetInputRegs(Enable:= NOT Mdl.pDisp^.GetInputRegs.Read,
Mode:= MB_RTU,
DevAddr:= Mdl.Base.Adress,
FirstAddr:= StartRegister1 + ((CurrentCon-1)*6),
Quantity:= RegisterCount,
ComHandle:= Mdl.pDisp^.Settings.Port,
TimeOut:= Mdl.Base.TimeOut,
Buffer:= Mdl.pDisp^.ReciveBuffer);
IF Mdl.pDisp^.GetInputRegs.Complete THEN
tmpReadError := Mdl.pDisp^.GetInputRegs.Exception;
IF tmpReadError = 0 THEN
pData := ADR(Mdl.dwDaikinRegisterRead); (*просто переменная, типа Слово, для текущего значения текущего кондея*)
pData^ := Mdl.pDisp^.ReciveBuffer[1];
pData := pData + 1;
pData^ := Mdl.pDisp^.ReciveBuffer[0];
Mdl.RCurTemp[CurrentCon]:=Mdl.dwDaikinRegisterRead; (* Пихаем полученные данные в объявленный массив из интов *)
ELSE
fcModuleAddAttempt(MdlBase := Mdl.Base);
IF Mdl.Base.CurrentAttempt > Mdl.Base.MaxAttempts THEN
Mdl.ExecStep := CompleteExecStep;
END_IF;
END_IF;
END_IF;
END_FOR;
Mdl.ExecStep:=Mdl.ExecStep+1;
END_IF;
Однако, если мы убираем цикл, опрашивая один регистр, на примере:
CurrentCon:=1;
IF Mdl.ExecStep = 1 THEN
Mdl.pDisp^.GetInputRegs(Enable:= NOT Mdl.pDisp^.GetInputRegs.Read,
Mode:= MB_RTU,
DevAddr:= Mdl.Base.Adress,
FirstAddr:= StartRegister1 + ((CurrentCon-1)*6),
Quantity:= RegisterCount,
ComHandle:= Mdl.pDisp^.Settings.Port,
TimeOut:= Mdl.Base.TimeOut,
Buffer:= Mdl.pDisp^.ReciveBuffer);
IF Mdl.pDisp^.GetInputRegs.Complete THEN
tmpReadError := Mdl.pDisp^.GetInputRegs.Exception;
IF tmpReadError = 0 THEN
pData := ADR(Mdl.dwDaikinRegisterRead);
pData^ := Mdl.pDisp^.ReciveBuffer[1];
pData := pData + 1;
pData^ := Mdl.pDisp^.ReciveBuffer[0];
Mdl.RCurTemp[CurrentCon]:=Mdl.dwDaikinRegisterRead;
CurrentCon:=CurrentCon+1;
Mdl.ExecStep:=Mdl.ExecStep+1;
ELSE
fcModuleAddAttempt(MdlBase := Mdl.Base);
IF Mdl.Base.CurrentAttempt > Mdl.Base.MaxAttempts THEN
Mdl.ExecStep := CompleteExecStep;
END_IF;
END_IF;
END_IF;
END_FOR;
END_IF;
(*Далее опрос следующего кондиционера на те же данные *)
IF Mdl.ExecStep = 1 THEN
CurrentCon:=2;
...
То после этого начинает все отличнейше работать. И можно было бы забить на циклы в целом, и на каждый регистр скопировать данный блок, но, исходя из того, что, в общей сложности 10 регистров * 7 койлов получается 70 блоков. Да и неаккуратно как-то.. Ткните, пожалуйста носом, что не так..