Оптимизация кода программы (+перенос на Овен ПЛК+СП270)
Дано: проект реализованный на Wago+Weintek (200 т.р.)
Задача: перенос проекта на Овен ПЛК100+СП270 (60 т.р.)
(вообще, хотелось сделать перенос быстрым и безболезненным, но после недели чтения форума ясно, что не получится. А раз придется кроить, то можно и кардинально пересмотреть/оптимизировать.)
Особенности реализации:
1.1) Передача данных между функциональными блоками и программой осуществлялась через переменные VAR_INPUT. Они доступны по записи и из программы и из ФБ.
VAR_IN_OUT вообще не использовались. 1.2) Функциональные блоки в которых требовались уставки или настройки (разные, для каждого экземпляра ФБ), имели конфигурационные переменные типа:
V:
PHP код:
U_PRED_N AT %M*:REAL; (*Уставка предупреждения низкого значения*) T_PRED_N_PT AT %M*:TIME:=T#10s; (*Время задержки предупреждения низкого значения*)
И в VAR_CONFIG им вручную были присвоены адреса.
V:
PHP код:
PLC_PRG.P_para.U_PRED_N AT %MD126:REAL; (* 12541 Давление пара Уставка предупреждения низкого значения*) PLC_PRG.P_para.T_PRED_N_PT AT %MD120:TIME; (* 12529 Давление пара Время задержки предупреждения низкого значения*) PLC_PRG.P_razr.U_PRED_N AT %MD156:REAL; (* 12601 Разрежение Уставка предупреждения низкого значения*) PLC_PRG.P_razr.T_PRED_N_PT AT %MD150:TIME; (* 12589 Разрежение Время задержки предупреждения низкого значения*)
1.3) Вся конфигурация переменных входов, выходов, обмена, энергонезависимых, делалась в текстовом виде, а не в окне "Конфигурация ПЛК".
1.4)Переменные AT %M* являются и энергонезависимыми, и регистрами Modbus TCP, доступны для чтения/записи и из программы и из сети.
Как выяснилось ниже эта штука была очень удобна
1.5) Переменные, которые не используются в конкретном экземпляре ФБ (т.к. ФБ унифицированы), размешались по одному адресу (для экономии памяти):
V:
PHP код:
PLC_PRG.NAU_vody.F_AVAR_0 AT %MX700.0:BOOL; PLC_PRG.VAU_vody.F_AVAR_0 AT %MX700.0:BOOL; PLC_PRG.P_gaza_dk.UST AT %MD700:REAL; PLC_PRG.P_gaza_dk.U_SNIZ AT %MD700:REAL;
1.6) Энергонезависимость реализованна так: после поступления сигнала о потере питания вся область памяти AT %M* скидывается в микросхемку EEPROM (или хз какая там), на это дело хватает заряда конденсатора.
1.7) Преременные объявленные Retain, но не расположенные в М памяти скидываются в файл retain.bin (точно не уверен, но файл такой есть и переменные там явно не все, что используются)
Проблемы переноса:
2.1) Переменные Modbus Slave имеют адреса AT %Q*. Если они объявлены в программе то читаются и пишутся отовсюду. Если в VAR_INPUT фнкционального блока, то по модбасу читаются, но не пишутся. 2.2) Чтобы объявить переменную в Modbus Slave по адресу AT %QW10.100.0 надо в окне "Конфигурация ПЛК" 100 раз натыкать "Добавить подэлемент"->"2 byte...", т.к. Codesys не дает возможности объявить переменную, которой нет в окне "Конфигурация ПЛК"! Ctrl+V работает в конфигурации плк без лишних вопросов
В ваге я имел дело с адресным пространством, которое разбивал на блоки и пустые места между ними, и безболезнено добавлял/убирал переменные.
Сейчас же, если мне надо добавить переменную в середину списка в окне "Конфигурация ПЛК", то адреса переменных которые ниже вставляемой, поплывут.
+ массивы структур как размещать, тоже натыкивать. 2.3) Конфигурационные переменные объявленные внутри функционального блока как VAR_INPUT AT %Q* и сконфигурированные в VAR_CONFIG с допиской RETAIN не сохраняются. 2.4) Переменные объявленные в программе VAR_INPUT RETAIN сохраняются, но не всегда. ПЛК110-60:
При выключении питания и включении, пока диод "Работа" еще моргает - переменные обнулились, после чего я выключил питание на 10 минут, включил, и переменные были восстановлены, но с предыдущего успешного сохранения, т.е. те нули, которые появились не были сохранены.
Если представить что "родной" Retein работает нормально (на других ПЛК110-60, не на моем), то пользоваться им однин хрен нельзя. 2-3 года и аккумулятор умрет, и придется ехать все восстанавливать, паять акк., а я уже все забыл, потерял и уволился.
Варианты решения проблем переноса:
3.1) Для конфигурационных переменных использовать левый модбас слейв и в каждом цикле из него копировать в реальный, а в начале цикла - обратно. Приемущества: относительно легко, если память левого слейва копировать в рабочий через указатель, да и в файл сохранять легко... Недостатки: памяти занимает в 2 раза больше, копирование туда/сюда примерно 300 переменных вкаждом цикле. 3.2) Борьба с окном "Конфигурация ПЛК". Если в слейве создать одну переменную 4 байта, получить ее адрес, и по нему положить массив структур, или просто массив DWORD-ов, размером 500-1000 кБ.(скока ж там памяти?)
Вопрос только - будет ли эта махинация читаться/писаться по модбасу? Писаться не будет. Если ПЛК мастер/Панель слейв - то работает Приемущества: не плывут адреса. Недостатки: преобразование типов, один хрен копировать туда обратно переменные. 3.2.a) Самописный модбас слейв: вариант пока не рассматриваю. 3.3) Борьба с Retain-ном. Ну, на форуме пишут: регулярно и/или по событиям, писать все что нужно в файлы с названием переменной, или один файл с одним большим массивом. В первом цикле это все восстанавливать. Приемущества: когда пишем, знаем точно что записали, и ничего не пропало в неизвестном направлении. Недостатки: ну, если лишние телодвижения отнести к недостаткам то они есть . И если стоит запись по событию пропажи питания и акк-ру здец, то - вариантов нет. И если часто регулярно писать - здец флешу (50 000 гдето читал).
Еще, наверное можно, писать в файл все что лежит по адресам начиная с первой переменной модбас слейва и до последней. Это если все переменные которые надо сохранить размещены по адресам слейва (и если панель не ИП320 ).
Варианты оптимизации:
4.1) Сейчас, для обработки данных полученных с аналоговых входов используется 1 универсальный ФБ со всеми что можно преобразованиями в физические величины, уставками, задержками и формирователями флагов аварий.(Для дискретных свой ФБ с задержками, фронтами, и формированием аварий по прошествии задержек).
Удобно то, что все параметры для каждого датчика доступны через точку: датчик.параметр
Каждая манипуляция выделена в свое "Действие", т.е. избыточный код, не нужный для конкретной величины, не выполняется.
Уставки для каждого экземпляра ФБ хранятся в М-памяти модбаса, и все переменные блока не помещаютя в retain, как при объявлении retain внутри ФБ.
Единственный недостаток это занятие оперативной памяти избыточными переменными. Чего думается:
Вынести все данные из ФБ в структуры, код из действий ФБ вынести в отдельные функции, и передавать по ссылке структуру в функции.
Чего хорошего: структуру легче сохранить в файл, при условии что все данные в ней надо сохранять, а это не так. Тогда надо 2 структуры на 1 датчик: сохраняемую и не сохраняемую. неудобно. Интересно структура структур возможна?
Структуру, наверное, было бы удобно сунуть по ссылке в память слейва, но будет отсутствовать выравнивание размерностей под модбас. Тогда надо еще разбивать на структуры по размерностям переменных....
вобщем, что-то я ничего толкового придумать не могу...
может кто-нибудь знает как оптимальнее организовать все это безобразие с удобством, сохранением и передачей... ?
P.S. Общая картина бедствия:
Последний раз редактировалось gtfox; 21.04.2014 в 09:09.