используем для сбора данных L-783M (WindowsXP SP3), сбор данных проходил и проходит без вопросов. Для дальнейшей обработки "сырых данных" и наведения "глянца" используем Matlab 2009 LINUX. Поэтому для нас стандартной процедурой было чтение (внутри локальной сети) записанной связки PAR-DAT файлов удаленными LINUX машинами. До версии 2.26 включительно, тот формат PAR файла который был описан в "lgraph2_help.pdf" соответствовал самим файлам. С объявлением версии 2.30 с ее новыми возможностями (особенно экспорт в
Matlab) мы обновили эту программу до версии 2.31. Как было сказано сам сбор данных остался прежним (без нареканий).
Но я был удивлен, что формат PAR файла перестал соответствовать, тому что был указан в "lgraph2_help.pdf" (вер.2.30). стр.80-82.
!!================== lgraph2_help.pdf стр. 80
6.3 ФОРМАТЫ ФАЙЛОВ ПРОГРАММЫ LGRAPH2.
Файл "*.dat" содержит последовательность собранных отсчетов (покадрово) в бинарном виде.
Каждый отсчет имеет размер short 16 бит, double 32 бит (для модулей LTR) или float (для Е-124).
Формат файла "*.par" имеет следующий вид (Borland Builder 4.0):
#pragma pack(1)
struct PARS_OF_WRITE_FILE
{
char Code[20]; // 20 байт - "3571090,7859525 "
char PlataName[17]; // 17 байт - название платы
char TimeString[26]; // 26 байт - число и время завершения ввода данных
...
!!================== lgraph2_help.pdf
Чтение Code[20] и PlataName[17] происходит без ошибок, как и в предыдущих версиях, чтение параметра TimeString[26] приводит к выдачи
пустого string/char. Я обнаружил, что TimeString[26] параметр был передвинут от начала файла на 22500 байт, поэтому корректное отображение штампа "дата - время" происходит путем принудительной прокрутки PAR файла вперед. После чтения TimeString приходиться откручивать файл обратно и читать его с начала, причем при чтении необходимо учитывать "ошибочное" место TimeString[26], чтобы не было дальнейшей сдвижки
% ====================== matlab script
fseek(fid01, 22500, -1);
TimeString = fread(fid01, 26, //'uint8=>char//'); % read TimeString from PAR
TimeString = TimeString//';
% =======================================
Все это ничего, и в принципе не было больших неудобств, если бы еще не было обнаружено, что параметр:
bool ActiveAdcChannelArray[32],
!!================== lgraph2_help.pdf стр. 80
...
bool ActiveAdcChannelArray[32]; // 1байт*32 - массив, каждый элемент
// которого равен нулю или единице,
// единичное значение соответствует
// тому, что данный вход активен
...
!!================== lgraph2_help.pdf
который является логическим (для Matlab это LOGICAL) не соответствует в экспортируемом матлаб-скрипте
% ====================== matlab script
% matlab script генерированный LGRAPH v.2.31 модулем "Экспорт в MatLab"
clc
clear all
close all
format long
DataFileName=//'Data_ver230.dat//'; % Имя файла данных (dat)
ShowInfo = 1; %% Показывать информацию о файле данных
%
module_name = //'L-783//'; % название платы
time_string = //' 22-03-2010 16:16:42//'; % число и время начала ввода данных
chan_max = 32; % общее число каналов для выбранной платы
RealChannelsQuantity = 32; % число введенных (активных) каналов
RealKadrsQuantity = 4807; % число собранных кадров в формате //'int//' ( < 2.147.483.648)
RealSamplesQuantity = 153824; % число собранных отсчетов в формате //'int//' (<2.147.483.648)
TotalTime = 0.099986; % время ввода в cекундах
AdcRate = 48076.923077; % частота АЦП в Гц
InterkadrDelay = 0.000300; % межкадровая задержка в мс
!!!!!!!!!!!! ОШИБКА ???? - не BOOL
ActiveAdcChannelArray = [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
19 20 21 22 23 24 25 26 27 28 29 30 31 ]; % массив с номерами введенных
каналов (с нуля)
!!!!!!!!!!!!!!
AdcGainMax = [2000.000000 2000.000000 2000.000000 2000.000000
2000.000000 2000.000000 2000.000000 2000.000000 2000.000000 2000.000000
2000.000000 2000.000000 2000.000000 2000.000000 2000.000000 2000.000000
2000.000000 2000.000000 2000.000000 2000.000000 2000.000000 2000.000000
2000.000000 2000.000000 2000.000000 2000.000000 2000.000000 2000.000000
2000.000000 2000.000000 2000.000000 2000.000000 ]; % массив с верхним
диапазоном каналов АЦП
AdcGainMin = [-2000.000000 -2000.000000 -2000.000000 -2000.000000
-2000.000000 -2000.000000 -2000.000000 -2000.000000 -2000.000000
-2000.000000 -2000.000000 -2000.000000 -2000.000000 -2000.000000
-2000.000000 -2000.000000 -2000.000000 -2000.000000 -2000.000000
-2000.000000 -2000.000000 -2000.000000 -2000.000000 -2000.000000
-2000.000000 -2000.000000 -2000.000000 -2000.000000 -2000.000000
-2000.000000 -2000.000000 -2000.000000 ]; % массив с нижним диапазоном
каналов АЦП
CalibrScale = [1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 1.000000 ]; % массив с калибровочными коэффициентами масштаба
CalibrOffset = [0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 ]; % массив с калибровочными коэффициентами смещения
нуля
UserCalibrScale = [1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 1.000000 ]; % массив с пользовательскими калибровочными
коэффициентами масштаба
UserCalibrOffset = [0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 ]; % массив с пользовательскими
калибровочными коэффициентами смещения нуля
DataCalibrScale = [0.002500 0.002500 0.002500 0.002500 0.002500 0.002500
0.002500 0.002500 0.002500 0.002500 0.002500 0.002500 0.002500 0.002500
0.002500 0.002500 0.002500 0.002500 0.002500 0.002500 0.002500 0.002500
0.002500 0.002500 0.002500 0.002500 0.002500 0.002500 0.002500 0.002500
0.002500 0.002500 ]; % массив с преобразованием шкалы
DataCalibrOffset = [0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 ]; % массив с преобразованием смещения нуля
DataCalibrZeroK = [0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 ]; %% массив со смещением нуля
if ShowInfo == 1 %% Показывать информацию о файле
format short
disp(//'-------------------------//')
disp(//'Параметры формата данных://')
disp([//' Название модуля : //' module_name]);
disp([//' Число и время ввода данных: //' time_string]);
disp([//' Число активных каналов : //' num2str(RealChannelsQuantity)]);
disp([//' Число собранных кадров : //' num2str(RealKadrsQuantity, 9)]);
disp([//' Число собранных отсчетов : //' num2str(RealSamplesQuantity,
9)]);
disp([//' Время ввода : //' num2str(TotalTime, 9) //' c//']);
disp([//' Частота АЦП : //' num2str(AdcRate, 9) //' Гц//']);
disp([//' Межкадровая задержка : //' num2str(InterkadrDelay, 9) //'
мс//']);
disp(//'-------------------------//')
end
fid = fopen(DataFileName, //'r//');
fseek(fid, 0, -1);
[y NSamples] = fread(fid, //'int16//');
y = reshape(y, RealChannelsQuantity, RealKadrsQuantity);
fclose(fid);
for i = 1:RealChannelsQuantity;
t = linspace(0,TotalTime,RealKadrsQuantity);
y(i,:) =
(y(i,:)+DataCalibrZeroK(i))*DataCalibrScale(i)+DataCalibrOffset(i);
figure(i),plot(t,y(i,:),//'r-//'),grid on;
xlabel(//'t,sec//');
ylabel(//'U, V//');
end;
% ======================================
Как видно, ActiveAdcChannelArray имеет тип INT (integer), но не как не BOOL или LOGICAL
% =======================================
ActiveAdcChannelArray = [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
19 20 21 22 23 24 25 26 27 28 29 30 31 ]; % массив с номерами введенных
каналов (с нуля)
% =========================================
Мое предположение о причине ошибки следующее:
В описании lgraph2_help.pdf (вер.2.30), стр. 80 просто дан старый формат *.par файла.
Поэтому дальнейшее правильное чтение PAR файла без соответствующего описания невозможно.
Если возможно хотелось, чтобы генерация матлаб-скрипта была напрямую с чтением PAR файла, а не представлением считанных массивов в самом теле
матлаб-скрипта. Это необходимо для удаленного чтения экспериментальных данных на LINUX машинах.