PDA

Просмотр полной версии : Приложение для выгрузки трендов с СП-270



erfinder
03.01.2018, 04:25
Доброго времени суток!
Наверно уже все уважающие себя господа перешли на СП-300+, ну а мы тут займемся некрофилией с СП-270 (думаю, от них еще далеко не все избавились).

Появилась необходимость выгружать тренды с СП-270, но так как "по хорошему" эта возможность там не реализована, пришлось пилить костыль.
В то время, когда к порту PLC подключены модули, к порту Download подключаемся кабелем, распаянным под RS-232, и обязательно перемыкаем контакты 6 и 5 между собой, это переключит СП-270 в режим отдачи информации, более того, переключит только после перезагрузки панельки. И порт Download должен быть в режиме Slave по ModBus RTU, иметь какой-то адрес. Обратная процедура аналогична, если хотим прошить панель, то придется ее снова перезагрузить.

С помощью преобразователя RS232-USB подключаемся к компьютеру. Открываем приложение (которое приложено в виде исходников, надо лишь скомпилировать и запустить), настраиваем параметры ModBus как на панельке, открываем порт. Тут важно раскрыть один камень преткновения.

На СП-270 доступно записывать тренды в совокупности до 1000000 точек. Тренды пишутся в память PFW, и на каждую точку тренда приходится 7 регистров: первые 6 (год,месяц,день,час,минута,секунда), а далее идет значение самой точки. Если на графике более одного тренда, то к 6 регистрам прибавляем N, где N - кол-во трендов в графике. Итого минимум 7000000 регистров доступно в памяти для чтения. НО! Протокол ModBus не предусматривает адресацию больше 65536 регистров! Следовательно нужно сделать на панели для каждого тренда кнопку, которая при нажатии будет копировать тренд в участок памяти до 65536 регистров. Она у нас чисто для скачивания трендов. Более того, тренды могут быть длиннее и не влезут в данный участок памяти, так что копирование и скачивание надо делать по частям (у меня это всё реализовано).

Такие дела. Неудобно конечно, но зато тренд скачается.
Приложение скачивает циклично точку за точкой и в конце переводит полученный массив в CSV файл, в виде столбца времени и значений тренда, что удобно для дальнейшего построения в виде графика в екселе.

Приложение выполнено на основе простой программы для передачи регистра по ModBus, в среде Visual Studio 2012 на языке C#. Почти все моменты закомментированы, буду рад, если кому-то облегчу жизнь данным костылем.

Скрипт для кнопок в СП-270 приведу ниже

erfinder
03.01.2018, 05:08
При нажатии на кнопку "скопировать тренд" в СП-270, запись останавливается, происходит копирование тренда, далее тренд выгружается на компьютер и предоставляется возможность либо продолжить запись трендов, либо скачать следующую часть.

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

Первый регистр для доступной для скачивания памяти выбрал 1030, но надо помнить, что по протоколу он доступен под 1030+10000 = 11030, и так для всех.
Скрипт кнопки представлен ниже. Каждому графику своя кнопка. Еще отдельно кнопка "Старт", для возобновления записи. Можно дописать, что при обнаружении незаконченного тренда, выводится сообщение, что есть следующая часть.


int FirstPnt = 126065; // первый регистр тренда (смотреть в св-вах)
int LengthTrnd = 6000; // длина тренда в точках
int iw = 1030; // первый регистр памяти для копирования
int readed; // буферная переменная
int cnt = 1; // индексы
int startAddress;
int IterOfCopy;
int Ntrnds = 1; // количество трендов в графике (рассм только 1 или 2)
int ix;

ResetPSB(503); // остановить запись трендов, потом отдельно кнопкой старт вернуть
Delay(100); // подождем на всякий случай

Read(HMI_LOCAL_MCH, 0, TYPE_PSW, 1001, 0, TYPE_WORD, &IterOfCopy); // смотрим какая часть по счету (по умолч = 0)

if (Ntrnds == 1){ix = 7;}else if (Ntrnds == 2) {ix = 8;} // множитель зависящий от кол-ва трендов

if (LengthTrnd > 6500)
{
startAddress = FirstPnt + (6500*ix*IterOfCopy); // если длина превысила 6500, то делим на части
} else {startAddress = FirstPnt;}

cnt = 1;
iw = 1030 + (6500*ix*IterOfCopy); // первый регистр для записи зависит от текущей части

while ((cnt <= LengthTrnd*ix) && (cnt <=52000)) //пока не превысит длину или допустимую область
{
Read(HMI_LOCAL_MCH, 0, TYPE_PFW, startAddress, 0, TYPE_WORD, &readed);
Write(HMI_LOCAL_MCH, 0, TYPE_PFW, iw, 0, TYPE_WORD, readed);

iw++;
cnt++;
startAddress++;
}

IterOfCopy++;
Write(HMI_LOCAL_MCH, 0, TYPE_PFW, 1001, 0, TYPE_WORD, IterOfCopy); // записываем, что первая часть скачана

Решение довольно сыровато, конечно, но тестировалось и работает.