Сообщение от
drvlas
Так что ждите объявлений
Их есть у меня!
Общая организация. Во ФЛЕШ-памяти ПЛК(100) созданы 2 файла:
- ringfile.csv (кольцевой файл-журнал)
- filepos.bin (указатель текущей позиции записи в кольцевой файл-журнал)
Программа ПЛК работает себе, работает, когда вдруг бац! - событие. По нему формируется запись, то есть одна строка будущего csv-файла. Строка имеет строго фиксированную длину. Вот пример строки-события:
100001; 24/01/14 12:14; 0,00; 10,00; 8275,79; ;;
(1) (2) (3) (4) (5) (6) (7) (8)
1 — номер события;
2 — дата та 3 — время события;
4, 5, 6 — те или иные данные, которые нужно журналировать;
7 та 8 — пустые поля, которые можно и не делать. Первое из них изменяет длину, компенсируя разную длину предыдущих полей. Но на 55-й и 56-й позиции всегда стоит <cr><lf>
Чтобы не слишком расточительно тратить ресурс ФЛЕШ-памяти ПЛК, события накапливаются в массиве строк, размер взят 200 строк. Возможное увеличение до 500-1000 строк не проверялось, мне хватит, если 200 строк будут надежно записываться в кольцевой файл-журнал.
Как только весь массив заполнится, вызывается функция bSaveLog записи массива строк в кольцевой файл-журнал. После этого массив событий начинает заполняться снова.
При выключении питания модуль статистики ПЛК гасит флаг bPower_OK (я так назвал), по этому сигналу немедленно вызывается та же bSaveLog с указанием реального количества событий в массиве (он же не полный). Она и записывает сколько нужно строк в буфер.
Осталось рассмотреть функцию bSaveLog, а также работу с ПЛК со стороны ПК.
Итак, bSaveLog. Ее задача: вставить в кольцо информации (записей длиной 56 байт) фрагмент от 1 до 200 записей. При этом начальное положение эта функция берет из вспомогательного файла filepos.bin, куда после всех трудов своих тяжких запихивает новое значение указателя.
Вот примерный вид этой функции (выброшены некоторые мои прихоти, типа модифицируемого имени файлов, что, в общем-то, не нужно):
Код:
FileHandle := SysFileOpen( 'posfile.bin', 'r');
IF FileHandle = 0 THEN
dwFilePos := 0; (* Первый раз так и будет... *)
ELSE
SysFileRead(FileHandle, ADR(dwFilePos), SIZEOF(dwFilePos));
SysFileClose( FileHandle); (* Побоялся оставить файл открытым *)
END_IF (* ..хотя скоро будет нужен *)
FileHandle := SysFileOpen( 'ringfile.csv', 'w');
IF dwFilePos > MAX_POS THEN dwFilePos := 0; END_IF (* Заворачивание *)
SysFileSetPos( FileHandle, dwFilePos);
FOR wi := 0 TO Imax DO
SysFileWrite( FileHandle, ADR(aProtocol[wi]), LEN(aProtocol[wi]));
dwFilePos := dwFilePos + LEN(aProtocol[wi]);
END_FOR
SysFileClose( FileHandle);
FileHandle := SysFileOpen( 'posfile.bin', 'w');
SysFileWrite( FileHandle, ADR(dwFilePos), SIZEOF(dwFilePos));
SysFileClose( FileHandle);
Как видим, здесь открывается файл с указателем позиции, в цикле прописывается указанное число Imax строк, с наглядным наращиванием указателя, после чего в файл указателя записывается новое значение.
Если к началу цикла записи событий окажется, что указатель больше MAX_POS (у меня 10000), то он обнуляется и кольцевой буфер начинает заполняться с начала.
Наконец, как работать потом со стороны ПК с имеющимся на борту ПЛК файлом-журналом. Да очень просто, если есть хороший парень Yegor. Взять его программу, запустить ее например, с вот такой командной строкой
Код:
LogParser /TCP192.168.1.111 /get "ringfile.csv"
и вуаля! Она сама запустит овенскую plc_io.exe с указанноми параметрами, подхватит файл, принятый из компа и любезно предоставит пользователю выбрать часовые рамки. Указал рамки, нажал "Сохранить как..." - и получил файл, в котором содержатся только те строки-события, которые в указанные рамки попадают.
"Ну а дальше клиент попадает ко мне в руки и..." (с) Бриллиантовая рука
</lf></cr>