PDA

Просмотр полной версии : СПК110 [М01] + PersistantVars - некорректное восстановление значений при перезапуске.



rch
05.06.2023, 15:30
Добрый день, столкнулся со странным поведением при работе с PersistantVars.
Задача следующая, СПК110 должен работать как Slave по Modbus RTU и Modbus TCP. По обоим каналам могут приходить новые значения для уставок. Также уставки могут меняться с сенсорной панели.
Уставки сохраняются в PersistantVars.


(*Уставки для ШП1.*)
SpAT1_MaxFillTm: TIME (*:= T#9M*); (*Допустимое время набора давления в ресивере.*)
SpAT1_MaxFillUpTm: TIME(*:= T#1M30S*); (*Допустимое время набора давления в ресивере.*)
SpAT1_DrainPeriod: TIME(*:= T#6H*); (*Периодичность сброса конденсата.*)
SpAT1_DrainTm: TIME(*:= T#7S*); (*Длительность открытия клапана сброса конденсата.*)

SpL11_PurgePeriod: TIME(*:= T#2H*); (*Периодичность продувки*)
SpL11_ML_MaxPurgeTm: TIME(*:= T#10M*); (*Макс. длительность продувки «-» линии*)
SpL11_PL_MaxPurgeTm: TIME(*:= T#10M*); (*Макс. длительность продувки «+» линии*)
SpL11_ML_AlmDirtyTm: TIME(*:= T#9M30S*); (*Время формирования предупреждения «Сильно забита «-» линия».*)
SpL11_PL_AlmDirtyTm: TIME(*:= T#9M30S*); (*Время формирования предупреждения «Сильно забита «+» линия».*)
SpL11_UDL_PurgeDelay: TIME(*:= T#5S*); (*Пауза между началом продувки сверху и снизу.*)

(*Уставки для ШП2.*)
SpAT2_MaxFillTm: TIME(*:= T#9M*); (*Допустимое время набора давления в ресивере.*)
SpAT2_MaxFillUpTm: TIME(*:= T#1M30S*); (*Допустимое время набора давления в ресивере.*)
SpAT2_DrainPeriod: TIME(*:= T#6H*); (*Периодичность сброса конденсата.*)
SpAT2_DrainTm: TIME(*:= T#7S*); (*Длительность открытия клапана сброса конденсата.*)

SpL21_PurgePeriod: TIME(*:= T#2H*); (*Периодичность продувки*)
SpL21_ML_MaxPurgeTm: TIME(*:= T#10M*); (*Макс. длительность продувки «-» линии*)
SpL21_PL_MaxPurgeTm: TIME(*:= T#10M*); (*Макс. длительность продувки «+» линии*)
SpL21_ML_AlmDirtyTm: TIME(*:= T#9M30S*); (*Время формирования предупреждения «Сильно забита «-» линия».*)
SpL21_PL_AlmDirtyTm: TIME(*:= T#9M30S*); (*Время формирования предупреждения «Сильно забита «+» линия».*)
SpL21_UDL_PurgeDelay: TIME(*:= T#5S*); (*Пауза между началом продувки сверху и снизу.*)


Для проверки уставок сделано три POU:
ModbusRtuData
ModbusTcpData
PLC_PRG
Все три POU выполняются последовательно в одной задаче.


Пример кода проверки:

IF SpL11_PurgePeriod.tmVal <> PersistentVars.SpL11_PurgePeriod THEN // Если значение пришедшее по Modbus не совпадает с сохранённым в СПК, то проеряем.
IF (SpL11_PurgePeriod.tmVal>=GVL.PurgePeriod_MIN) AND (SpL11_PurgePeriod.tmVal<=GVL.PurgePeriod_MAX) THEN // Проверка пределов.
PersistentVars.SpL11_PurgePeriod:= SpL11_PurgePeriod.tmVal; // Если новое значение подходит, то сохраняем в Persistant
ELSE
SpL11_PurgePeriod.tmVal:= PersistentVars.SpL11_PurgePeriod; // Если новое значение НЕ подходит, то в Modbus-регистр пишем старое значение.
END_IF
PLC_PRG.SpL11_PurgePeriod:= PersistentVars.SpL11_PurgePeriod; // Обновляем значения уставок в POU для проверки значений введённых с сенсорной панели, чтобы в данном POU не проводилась повторная проверка.
ModbusTcpData.SpL11_PurgePeriod.tmVal:= PersistentVars.SpL11_PurgePeriod; // Обновляем значения уставок в POU для проверки значений пришедших по каналу Modbus TCP, чтобы в данном POU не проводилась повторная проверка.
END_IF



Проблема возникает при отключении питания СПК и повторном включении. Все уставки кроме одной сохраняются и восстанавливаются корректно. Значение уставки SpL11_PurgePeriod: TIME, если в переменной перед выключением СПК сохранили значение T#2H (0x006D DD00), после перезагрузки СПК принимает значение T#1H 59M 03S 424MS (0x006D 0000). Если сохраняли значение T#4H (0x00DB BA00), после перезагрузки СПК принимает значение T#3H 59M 12S 384MS (0x00DB 0000). Т.е. в PersistantVars при сохранении значения сохраняется только старший значащий регистр, а вместо младшего регистра записывается ноль.

Если закомментировать строку
PLC_PRG.SpL11_PurgePeriod:= PersistentVars.SpL11_PurgePeriod;, то проблема уходит, но она необходима, для того чтобы исключить повторную проверку уставки.
Переменная PLC_PRG.SpL11_PurgePeriod объявлена в секции VAR_INPUT.

Подскажите в чём может быть проблема, если сталкивались?

Евгений Кислов
05.06.2023, 17:40
Добрый день.

Мы еще не сталкивались с такой проблемой.

Выложите, пожалуйста, простейший проект с минимумом переменных, в котором получится воспроизвести эту проблему.

rch
06.06.2023, 10:42
Выложил архив проекта по ссылке https://disk.yandex.ru/d/RXxnxZULYI6Xjw
Информация о СПК:
68172

Для воспроизведения проблемы необходимо:
- загрузить проект в СПК;
- нажать кнопку "Вернуть настройки по умолчанию" (данный шаг возможно не обязателен, т.к. на "чистой" панели изначально будут верные значения);
- выключить СПК снятием питания, а затем включить.
После включения СПК на индикаторах в верхней строке "Периодичность продувки" будут некорректные значения, как описано в первом сообщении темы.

Евгений Кислов
06.06.2023, 10:53
С моим СПК и вашим проектом это не воспроизвелось - после перезагрузки по питанию в строке "Периодичность продувки" отображается "0 дн 02:00:00".
Попробуйте перепрошить контроллер на ту же версию прошивки, что у вас сейчас, со сбросом настроек.

rch
06.06.2023, 10:56
С моим СПК и вашим проектом это не воспроизвелось - после перезагрузки по питанию в строке "Периодичность продувки" отображается "0 дн 02:00:00".
Попробуйте перепрошить контроллер на ту же версию прошивки, что у вас сейчас, со сбросом настроек.
Подскажите, СПК перезагрузили один раз? Если один, то попробуйте перезагрузить СПК ещё раз.

Евгений Кислов
06.06.2023, 11:12
Подскажите, СПК перезагрузили один раз? Если один, то попробуйте перезагрузить СПК ещё раз.

Перезагрузил СПК по питанию 5 раз подряд. Проблема не проявилась.

rch
06.06.2023, 12:10
С моим СПК и вашим проектом это не воспроизвелось - после перезагрузки по питанию в строке "Периодичность продувки" отображается "0 дн 02:00:00".
Попробуйте перепрошить контроллер на ту же версию прошивки, что у вас сейчас, со сбросом настроек.

Перепрошил через Web-интерфейс со сбросом пользовательских данных. Использовалась прошивка 2.4.0923.1000, файл tanowrt-image-owen-codesys-swu-spk1xxm01.swu.
К сожалению проблема осталась. Подскажите на вашем СПК хотфиксы дополнительно установлены?
68175

Евгений Кислов
06.06.2023, 12:17
Перепрошил через Web-интерфейс со сбросом пользовательских данных. Использовалась прошивка 2.4.0923.1000, файл tanowrt-image-owen-codesys-swu-spk1xxm01.swu.
К сожалению проблема осталась. Подскажите на вашем СПК хотфиксы дополнительно установлены?
68175

Да, хотфикс установлен, но он не должен никак влиять на ситуацию.
Вы проводите тест с тем проектом, который выложили выше?

rch
06.06.2023, 12:25
Да, хотфикс установлен, но он не должен никак влиять на ситуацию.
Вы проводите тест с тем проектом, который выложили выше?

Да, тест именно с тем проектом, который выложен.
Хотфикс установлен этот swu-www-patch-spk.hotfix.swu?

Евгений Кислов
06.06.2023, 12:38
Да, тест именно с тем проектом, который выложен.
Хотфикс установлен этот swu-www-patch-spk.hotfix.swu?

Да, именно этот.
Вы можете со мной через telegram связаться?

capzap
06.06.2023, 12:46
Если закомментировать строку
PLC_PRG.SpL11_PurgePeriod:= PersistentVars.SpL11_PurgePeriod;, то проблема уходит, но она необходима, для того чтобы исключить повторную проверку уставки.

а где комментировали? Во всех трех местах или в какой то одной программе, которая считаете выполняется когда, первой последней ...
в PRG создавать область ввода это как то не профессионально
приоритета выполнения тоже нет, каждый раз может запустится в любой последовательности
в основном в эту переменную идет запись внутри условия, значит условие это выполняется может стоит обратить внимание на смежную переменную

rch
07.06.2023, 09:52
в PRG создавать область ввода это как то не профессионально
В CS3.5 я вообще могу убрать/переименовать PLC_PRG, это всего лишь имя POU. Ну и в общем не профессиональность в этой теме обсуждаем...


приоритета выполнения тоже нет, каждый раз может запустится в любой последовательности
Все POU в одной задаче, выполняются последовательно, приоритет не влияет, последовательность выполнения POU всегда одна и та же.


а где комментировали? Во всех трех местах или в какой то одной программе, которая считаете выполняется когда, первой последней ...
в основном в эту переменную идет запись внутри условия, значит условие это выполняется может стоит обратить внимание на смежную переменную
Проверено неоднократно в разных комбинациях. В ходе тестов выяснилось, что проблема уходит при отключении стандартного компонента Modbus RTU Slave, при этом ничего не закомментировано.
Делаю вывод, что проблема в нём. Как это происходит - вопрос к разработчикам компонента.

capzap
07.06.2023, 10:22
В CS3.5 я вообще могу убрать/переименовать PLC_PRG, это всего лишь имя POU.

я акцентирую не на имя PLC_PRG, а на тип PRG, область входных переменных используется в функциональных блоках и функциях


Все POU в одной задаче, выполняются последовательно, приоритет не влияет, последовательность выполнения POU всегда одна и та же
ну а как же тогда предложение перегружать несколько раз, у кого то вот и на пятый раз проблем нет, значит случайность, значит под вопросом как ПОУ запускаются в одной задаче

запустите все свои ПОУ в одном PLC_PRG это ни чем не будет отличатся от того что на данный момент, зато конкретно будет ясна последовательность выполнения и как бы Вы не говорили что не поднимать тему об навыках и умениях, но по несколько раз писать одно и тоже только в разных ПОУ это дичь, кто Вас такому научил, это даже на подстраховку не похоже

rch
07.06.2023, 13:18
я акцентирую не на имя PLC_PRG, а на тип PRG, область входных переменных используется в функциональных блоках и функциях
Не запрещается использовать VAR_INPUT в POU типа PROGRAM, хотя может и не является типичным. Если вы почитаете справку на CODESYS, то увидите это:https://help.codesys.com/webapp/_cds_obj_program;product=codesys;version=3.5.17.0


ну а как же тогда предложение перегружать несколько раз, у кого то вот и на пятый раз проблем нет, значит случайность, значит под вопросом как ПОУ запускаются в одной задаче
Это предложение просто для повторяемости результата. По факту у меня всегда с первого раза некорректно восстанавливаются значения. И для размышления, у Евгения Кислова, который отвечал выше, на СПК данная проблема на выложенном мной выше проекте вообще не проявляется, но у него СПК выпущен до октября 2022г.


запустите все свои ПОУ в одном PLC_PRG это ни чем не будет отличатся от того что на данный момент, зато конкретно будет ясна последовательность выполнения и как бы Вы не говорили что не поднимать тему об навыках и умениях, но по несколько раз писать одно и тоже только в разных ПОУ это дичь, кто Вас такому научил, это даже на подстраховку не похоже
Во-первых, в разные POU код проверки разнесён для удобочитаемости, чтобы не было многокилометровых листингов в одном файле (что как раз и есть дичь).
Во-вторых, эти POU обрабатывают разные входные данные и код в них разный, и речь вовсе не о подстраховке.
В-третьих, перенос всего этого кода в один POU не изменяет порядок выполнения никак, т.к. POU в задаче выполняются последовательно в том порядке, в котором они указаны в настройках задачи. Чтобы не быть голословным, сделал вариант (как вы предлагаете), где всё в одном POU (PRG без VAR_INPUT), и как ни странно дичь при восстановлении значений PersistentVars осталась.

capzap
07.06.2023, 14:37
Во-первых, в разные POU код проверки разнесён для удобочитаемости, чтобы не было многокилометровых листингов в одном файле (что как раз и есть дичь).
68208эта конструкция и эта 68209 не имеют отличий и не нарушают Вашу концепцию непринятия портянок

Во-вторых, эти POU обрабатывают разные входные данные и код в них разный, и речь вовсе не о подстраховке.
68207выделенные строки не имеют отличий

В-третьих ...а я ни где не утверждал что именно это поможет. Я просто не вижу потребности делать вещи лишенные смысла, такие как входные переменные выполняют свою задачу, они потому и входные что их менять нельзя, только читать, зачем в этом проекте PERSISTENT, инициализация VAR foo : BOOL := TRUE END_VAR вполне себе заменяет ПОУ с IF NOT xFlag THEN foo := TRUE; xFlag := TRUE; END_IF и т.д.и т.п.

rch
07.06.2023, 16:12
68208эта конструкция и эта 68209 не имеют отличий и не нарушают Вашу концепцию непринятия портянок
О том Вам и говорил в предыдущих постах.



68207выделенные строки не имеют отличий
Этот код:

IF SpL11_PurgePeriod.tmVal <> PersistentVars.SpL11_PurgePeriod THEN
IF (SpL11_PurgePeriod.tmVal>=GVL.PurgePeriod_MIN) AND (SpL11_PurgePeriod.tmVal<=GVL.PurgePeriod_MAX) THEN
PersistentVars.SpL11_PurgePeriod:= SpL11_PurgePeriod.tmVal;
ELSE
SpL11_PurgePeriod.tmVal:= PersistentVars.SpL11_PurgePeriod;
END_IF
PLC_PRG.SpL11_PurgePeriod:= PersistentVars.SpL11_PurgePeriod;
ModbusTcpData.SpL11_PurgePeriod.tmVal:= PersistentVars.SpL11_PurgePeriod;
END_IF
отличается от этого:

IF SpL11_PurgePeriod.tmVal <> PersistentVars.SpL11_PurgePeriod THEN
IF (SpL11_PurgePeriod.tmVal>=GVL.PurgePeriod_MIN) AND (SpL11_PurgePeriod.tmVal<=GVL.PurgePeriod_MAX) THEN
PersistentVars.SpL11_PurgePeriod:= SpL11_PurgePeriod.tmVal;
ELSE
SpL11_PurgePeriod.tmVal:= PersistentVars.SpL11_PurgePeriod;
END_IF
PLC_PRG.SpL11_PurgePeriod:= PersistentVars.SpL11_PurgePeriod;
ModbusRtuData.SpL11_PurgePeriod.tmVal:= PersistentVars.SpL11_PurgePeriod;
END_IF
Смысл в проверке разных входных данных. Выделенный код одинаков просто для того, чтобы во всех входных данных были одни и те же значения.


а я ни где не утверждал что именно это поможет.
Я собственно и не ожидаю чудесного решения проблемы.

[CODE]Я просто не вижу потребности делать вещи лишенные смысла, такие как входные переменные выполняют свою задачу, они потому и входные что их менять нельзя, только читать, зачем в этом проекте PERSISTENT, инициализация VAR foo : BOOL := TRUE END_VAR вполне себе заменяет ПОУ с IF NOT xFlag THEN foo := TRUE; xFlag := TRUE; END_IF и т.д.и т.п.[/QUOTE]
Соглашусь с замечанием. Хотя технически входные переменные на время выполнения POU являются для него локальными переменными, и изменение их возможно из кода POU. Проблема в том, что изначально эти переменные не были VAR_INPUT. Но так как понадобилось изменять их из смежных POU - появилось такое неизящное решение. Сами входные переменные привязаны в соотнесении входов Modbus RTU/TCP Slave. А т.к. мне необходимо, чтобы при неверном значении, полученном по Modbus, в регистр писалось верное значение (для последующего чтения извне), то понадобилась возможность изменять внутреннюю переменную POU привязанную к регистру Modbus. Собственно так они и стали VAR_INPUT. Можно сделать их глобальными и замечание снимется. Но как писал выше, изменение кода в таком ключе основной проблемы не снимает.

По ссылке проект без VAR_INPUT и весь код полностью в одном POU https://disk.yandex.ru/d/4UUg_wj09z8FyA