Ещё конкретнее. Прямо совсем конкретно. Температура там, скорость.Чтобы отправить новое значение слейву. Если использовать только одну переменную, то значение, которое получим от слейва, может затереть то значение, которое ввёл оператор.С СПК110 я работал.У вас панели оператора или СПК? В панелях оператора, с которыми я работал, эта сихронизация выполняется на системном уровне. СПК -- это не панель оператора.Тут я немного сдамся. Дело в том, что я избегаю таких элементов на главных экранах. Любые реальные действия — только через диалоги. На экранах только навигация и вызов диалогов. Ну, подробнее так подробнее...А вот с этим поподробнее, пожалуйста! Как отследить завершение ввода нового значения с помощью Slider'а, Checkbox'а, Potentiometr'a и т.п. Я ведь не зря написал "В общем случае". Даже поймать закрытие диалога недостаточно, если обмен выполняется в параллельной задаче.
Вот экранчик на СПК110 в конструкторе и при исполнении:
desginer.png manual_overview2.png
Там есть вот эти поля:
input.png
Это температурная уставка. Её текущее значение всегда и постоянно берётся со слейва (ПЛК110) без дополнительных условий. Переменная heaterSetpoint это просто результат разбора содержимого регистров слейва:
heaterSetpoint.png
В событиях этого поля ввода творится следующее:
ondialogclosed.png
То есть при вызове диалога запоминается команда «Установить температуру». При закрытии диалога эта команда передаётся на ПЛК вместе с уставкой. Ну то есть как передаётся... У меня первые три регистра отведены под команду: соответственно, код команды, аргумент 1 и аргумент 2. Остальные регистры отведены на передачу показаний с контроллера-слейва на панели. Тут тоже ничего хитрого — контроллер натыкается на команду «установить температуру», меняет какие-то свои внутренние переменные и заодно выставляет новое значение регистра, из которого СПК показывает значение уставки.
А главная хитрость в том, что значение из диалога пишется не в ту переменную, которая идёт от слейва, а в другую:
another_var.png
То есть результат ввода запоминается для отправки, потом отправляется вместе с так же запомненной командой и в считанные миллисекунды актуальное значение оказывается в переменной heaterSetpoint обеих панелей.
SendPlcCmd вот:
CMD_CTRL вот:Код:FUNCTION SendPlcCmd : BOOL VAR_INPUT Cmd: SCommand; Arg0, Arg1: WORD; END_VAR IF CMD_CTRL.cmdCount < 51 THEN CMD_CTRL.cmdQueue[CMD_CTRL.cmdCount][0] := Cmd; CMD_CTRL.cmdQueue[CMD_CTRL.cmdCount][1] := Arg0; CMD_CTRL.cmdQueue[CMD_CTRL.cmdCount][2] := Arg1; CMD_CTRL.cmdCount := CMD_CTRL.cmdCount + 1; END_IF
В конфигурации ничего хитрого:Код:PROGRAM CMD_CTRL (* Sends commands to the PLC *) VAR_INPUT Cmd, Arg0, Arg1: WORD; cmdQueue: ARRAY[0..50] OF ARRAY [0..2] OF WORD; cmdCount: INT; END_VAR VAR Checksum: WORD; Pulse: TON := (PT := T#300MS); tx: BOOL; cmdIdx: INT; edge: R_TRIG; END_VAR (* Command conveyor, up to 50 commands in queue *) tx := FALSE; edge(CLK := cmdCount > 0); Pulse(IN := NOT Pulse.Q AND cmdCount > 0); IF (Pulse.Q OR edge.Q) AND cmdIdx < cmdCount THEN Cmd := cmdQueue[cmdIdx][0]; Arg0 := cmdQueue[cmdIdx][1]; Arg1 := cmdQueue[cmdIdx][2]; Checksum := Cmd + Arg0 + Arg1; tx := TRUE; cmdIdx := cmdIdx + 1; ELSIF Pulse.Q THEN Cmd := 0; cmdIdx := cmdCount := 0; END_IF
cmd0.png cmd1.png




Ответить с цитированием