read binary waveform file created by a LeCroy Oscilloscope matlab

%QQ53192794

% ReadLeCroyBinaryWaveform -  read binary waveform file created by a LeCroy Oscilloscope
%     waveform = LeCroyBinaryWaveform(FILENAME) loads the waveform file into the workspace variable W.
%     FILENAME can either be a variable or a string constant enclosed by quotes.
%
%     The return value "waveform" is a record containing four elements:
%     waveform.INFO   Waveform information, in readable formats. For example Oscilloscope ID, sampling time and settings
%     waveform.DESC   Waveform information used for further calculations. For example Sampling rate
%     waveform.Y      Values sampled by the oscilloscope
%     waveform.X      Array of time values corresponding to waveform.Y. Time '0' marks the trigger event
%
%     The routine was tested with files generated by a WavePro7300 and WaveRunner64Xi, Template LECROY_2_3
%
% See also LCPLOT LCPLOTEXT
%
%------------------------------------------------------
% Original version (c)2001 Hochschule f�r Technik+Architektur Luzern
% Fachstelle Elektronik
% 6048 Horw, Switzerland
% Slightly modified by Alan Blankman, LeCroy Corporation, 2006
% July 2007; added decoding of TrigTime_array so that sequence mode waveforms decode correctly
% Slightly modified by Jean-Daniel Desch�nes, Universite Laval, 2010
% Added support for sequence mode, even if RECORD_TYPE says "single_sweep"
% (seen on a WavePro 7 Zi).  Output will be a MxN matrix, where M is the
% number of points in each segment, and N is the number of segments.  X
% vector also update to include offset of each trigger.
function wave=ReadLeCroyBinaryWaveform(fn)
%%
%---------------------------------------------------------------------------------------
% Open File
%---------------------------------------------------------------------------------------
fid=fopen(fn,'r');
if fid==-1 
   disp (sprintf('ERROR: file not found: %s', fn));
   return
end;
%---------------------------------------------------------------------------------------
% Seek offset in the header block
%---------------------------------------------------------------------------------------
data=fread(fid,50);
WAVEDESC=findstr('WAVEDESC', char(data(1:50)'))-1; 
   % subtract 1 because: 
   %        - 1st byte in the File = Index [0]
   %        - 1st byte in the Matlab-Array = Index[1]
   
%---------------------------------------------------------------------------------------
% Define the addresses of the various informations in the file
% These addresses are valid for the template LECROY_2_3 and are subject to change in
% future revisions of the LeCroy firmware. Testing to this template version
% has been disabled to facilitate decoding of waveforms from scopes
% utilizing version 2_2 of the template.
%---------------------------------------------------------------------------------------
TESTED_TEMPLATE = 'LECROY_2_3';
%Addresses (WAVEDESC + address as stated in the LECROY template)
aTEMPLATE_NAME        = WAVEDESC+ 16;
aCOMM_TYPE            = WAVEDESC+ 32;
aCOMM_ORDER            = WAVEDESC+ 34;
aWAVE_DESCRIPTOR    = WAVEDESC+ 36;    % length of the descriptor block
aUSER_TEXT            = WAVEDESC+ 40;    % length of the usertext block
aTRIGTIME_ARRAY     = WAVEDESC+ 48;
aWAVE_ARRAY_1        = WAVEDESC+ 60;    % length (in Byte) of the sample array
aINSTRUMENT_NAME    = WAVEDESC+ 76;
aINSTRUMENT_NUMBER  = WAVEDESC+ 92;
aTRACE_LABEL        = WAVEDESC+ 96;
aWAVE_ARRAY_COUNT    = WAVEDESC+ 116;
aSUBARRAY_COUNT     = WAVEDESC+ 144;
aVERTICAL_GAIN        = WAVEDESC+ 156;
aVERTICAL_OFFSET    = WAVEDESC+ 160;
aNOMINAL_BITS        = WAVEDESC+ 172;
aHORIZ_INTERVAL     = WAVEDESC+ 176;
aHORIZ_OFFSET        = WAVEDESC+ 180;
aVERTUNIT            = WAVEDESC+ 196;
aHORUNIT            = WAVEDESC+ 244;
aTRIGGER_TIME        = WAVEDESC+ 296;
aRECORD_TYPE        = WAVEDESC+ 316;
aPROCESSING_DONE    = WAVEDESC+ 318;
aTIMEBASE            = WAVEDESC+ 324;
aVERT_COUPLING        = WAVEDESC+ 326;
aPROBE_ATT            = WAVEDESC+ 328;
aFIXED_VERT_GAIN    = WAVEDESC+ 332;
aBANDWIDTH_LIMIT    = WAVEDESC+ 334;
aVERTICAL_VERNIER    = WAVEDESC+ 336;
aACQ_VERT_OFFSET    = WAVEDESC+ 340;
aWAVE_SOURCE        = WAVEDESC+ 344;
%---------------------------------------------------------------------------------------
% determine the number storage format HIFIRST / LOFIRST     (big endian / little endian)
%---------------------------------------------------------------------------------------
fseek(fid,aCOMM_ORDER,'bof');
COMM_ORDER=fread(fid,1,'int16');
fclose(fid);
% reopen the data file using the correct HIFIRST/LOFIRST format
if COMM_ORDER==0    
   fid=fopen(fn,'r','ieee-be');        % HIFIRST
else 
   fid=fopen(fn,'r','ieee-le');        % LOFIRST
end;
%---------------------------------------------------------------------------------------
% Get the waveform information
%---------------------------------------------------------------------------------------
% Check the template revision  (Commented out to facilitate decoding of 2_2
% files
TEMPLATE_NAME        = ReadString(fid, aTEMPLATE_NAME);
if ~strcmp( deblank(TEMPLATE_NAME), TESTED_TEMPLATE)
  disp (sprintf ('WARNING!\n %s %s %s\n %s %s %s',...
            'This function has been written for the LeCroy-Template',...
            TESTED_TEMPLATE, '.',...
            'The current file contains information created with the template',...
            TEMPLATE_NAME, '.'));
end
% Instrument
wave.info.INSTRUMENT_NAME    = ReadString(fid, aINSTRUMENT_NAME);
wave.info.INSTRUMENT_NUMBER    = ReadLong    (fid, aINSTRUMENT_NUMBER);
wave.info.Filename            = fn;
% Channel
wave.info.TRIGGER_TIME        = ReadTimestamp(fid, aTRIGGER_TIME);
tmp=['channel 1';'channel 2';'channel 3';'channel 4';'unknown  '];
wave.info.WAVE_SOURCE            = tmp (1+ ReadWord(fid, aWAVE_SOURCE),:);
tmp=['DC_50_Ohms'; 'ground    ';'DC 1MOhm  ';'ground    ';'AC 1MOhm  '];
wave.info.VERT_COUPLING        = deblank (tmp (1+ ReadWord(fid, aVERT_COUPLING),:));
tmp=['off'; 'on '];
wave.info.BANDWIDTH_LIMIT    = deblank (tmp (1+ ReadWord(fid, aBANDWIDTH_LIMIT),:));
tmp=[
   'single_sweep      ';    'interleaved       '; 'histogram         ';
   'graph             ';    'filter_coefficient'; 'complex           ';
   'extrema           ';    'sequence_obsolete '; 'centered_RIS      ';    
   'peak_detect       '];
wave.info.RECORD_TYPE        = deblank (tmp (1+ ReadWord(fid, aRECORD_TYPE),:));
tmp=[
   'no_processing';   'fir_filter   '; 'interpolated ';   'sparsed      ';
   'autoscaled   ';   'no_result    '; 'rolling      ';   'cumulative   '];
wave.info.PROCESSING_DONE        = deblank (tmp (1+ ReadWord(fid, aPROCESSING_DONE),:));
% Vertical settings
FIXED_VERT_GAIN            = ReadFixed_vert_gain(fid, aFIXED_VERT_GAIN);
PROBE_ATT                = ReadFloat (fid, aPROBE_ATT);
VERTICAL_GAIN            = ReadFloat    (fid, aVERTICAL_GAIN);
VERTICAL_OFFSET            = ReadFloat    (fid, aVERTICAL_OFFSET);
wave.info.NOMINAL_BITS    = ReadWord    (fid, aNOMINAL_BITS);
wave.info.Gain_with_Probe = strcat (Float_to_Eng(FIXED_VERT_GAIN*PROBE_ATT), 'V/div');
% Horizontal settings
HORIZ_INTERVAL            = ReadFloat(fid, aHORIZ_INTERVAL);
HORIZ_OFFSET            = ReadDouble(fid, aHORIZ_OFFSET);
wave.info.TIMEBASE    = strcat (Float_to_Eng (ReadTimebase(fid,aTIMEBASE)), 's/div');
wave.info.SampleRate    = strcat (Float_to_Eng(1/HORIZ_INTERVAL) , 'S/sec');
wave.desc.Ts            = HORIZ_INTERVAL;
wave.desc.fs            = 1/HORIZ_INTERVAL;
%---------------------------------------------------------------------------------------
% Read samples array (Plain binary ADC values)
%---------------------------------------------------------------------------------------
COMM_TYPE            = ReadWord(fid, aCOMM_TYPE);
WAVE_DESCRIPTOR     = ReadLong(fid, aWAVE_DESCRIPTOR);
USER_TEXT            = ReadLong(fid, aUSER_TEXT);
WAVE_ARRAY_1        = ReadLong(fid, aWAVE_ARRAY_1);
WAVE_ARRAY_COUNT    = ReadLong(fid, aWAVE_ARRAY_COUNT);
TRIGTIME_ARRAY      = ReadLong(fid, aTRIGTIME_ARRAY);
% returns number of segments in acquisition
wave.info.nbSegments      = ReadLong(fid, aSUBARRAY_COUNT);
if wave.info.nbSegments > 1
    % for sequence mode only
    
    %---------------------------------------------------------------------------------------
    % Read contents of TRIGTIME_ARRAY, which is an interleaved array
    %---------------------------------------------------------------------------------------
    % Take from X-Stream oscilloscopes remote control manual, appendix II:
    % <  0>          TRIGGER_TIME: double     ; for sequence acquisitions, 
    %                                         ; time in seconds from first 
    %                                         ; trigger to this one 
    % <  8>          TRIGGER_OFFSET: double   ; the trigger offset is in seconds 
    %                                         ; from trigger to zeroth data point
    fseek(fid, WAVEDESC + WAVE_DESCRIPTOR + USER_TEXT, 'bof');
    trigtime_array_temp = fread(fid, 2*wave.info.nbSegments, 'double');
    % We need to de-interleave the trigger_time and trigger_offset data.
    wave.trigger_time = trigtime_array_temp(1:2:end);
    wave.trigger_offset = trigtime_array_temp(2:2:end);
    
    if WAVE_ARRAY_1/wave.info.nbSegments ~= WAVE_ARRAY_1/wave.info.nbSegments
        % if this condition happens, MATLAB will pad the rest of the output
        % matrix with zeros, so the file is still readable, but this could
        % signify another error (in this m-file?)
        warning('While reading segment file: Total number of points is not a multiple of the number of segments');
    end
    
    %---------------------------------------------------------------------------------------
    % Read the ADC values into a matrix
    %---------------------------------------------------------------------------------------
    % since this is a sequence acquisition, we will return a
    % (WAVE_ARRAY_COUNT/nbSegments)x(nbSegments) matrix, where each column is one segment.
    fseek(fid, WAVEDESC + WAVE_DESCRIPTOR + USER_TEXT + TRIGTIME_ARRAY, 'bof');
    if COMM_TYPE == 0  % byte
       wave.y = fread(fid, [WAVE_ARRAY_COUNT/wave.info.nbSegments wave.info.nbSegments], 'int8');
    else    %    word
       wave.y = fread(fid, [WAVE_ARRAY_COUNT/wave.info.nbSegments wave.info.nbSegments], 'int16');
    end;
    
    %---------------------------------------------------------------------------------------
    % Create corresponding matrix of time, with correction for each trigger time
    %---------------------------------------------------------------------------------------
    wave.x = repmat(wave.trigger_time.', WAVE_ARRAY_COUNT/wave.info.nbSegments, 1) + repmat((0:WAVE_ARRAY_COUNT/wave.info.nbSegments-1)'*HORIZ_INTERVAL + HORIZ_OFFSET, 1, wave.info.nbSegments);
    
else
    fseek(fid, WAVEDESC + WAVE_DESCRIPTOR + USER_TEXT + TRIGTIME_ARRAY, 'bof');
    if COMM_TYPE == 0  % byte
       wave.y=fread(fid,WAVE_ARRAY_1, 'int8');
    else    %    word
       wave.y=fread(fid,WAVE_ARRAY_1, 'int16');
    end;
    %---------------------------------------------------------------------------------------
    % Create corresponding array of time
    %---------------------------------------------------------------------------------------
    wave.x = (0:WAVE_ARRAY_COUNT-1)'*HORIZ_INTERVAL + HORIZ_OFFSET;
end
%---------------------------------------------------------------------------------------
% Transform the ADC values to voltages
%---------------------------------------------------------------------------------------
wave.y = VERTICAL_GAIN * wave.y - VERTICAL_OFFSET;
%---------------------------------------------------------------------------------------
% close the waveform file
%---------------------------------------------------------------------------------------
fclose(fid);
%=======================================================================================
% Support functions
%=======================================================================================
%---------------------------------------------------------------------------------------
% Read 8Bit signed Byte (not used)
%---------------------------------------------------------------------------------------
function b=ReadByte(fid, Addr)
    fseek(fid,Addr,'bof');
    b=fread(fid,1,'int8');
   
%---------------------------------------------------------------------------------------
% Read 16Bit signed Word 
%---------------------------------------------------------------------------------------
function w=ReadWord(fid, Addr)
    fseek(fid,Addr,'bof');
    w=fread(fid,1,'int16');
    
%---------------------------------------------------------------------------------------
% Read 32Bit signed Long
%---------------------------------------------------------------------------------------
function l=ReadLong(fid, Addr)
    fseek(fid,Addr,'bof');
    l=fread(fid,1,'int32');
   
%---------------------------------------------------------------------------------------
% Read 32Bit IEEE Float
%---------------------------------------------------------------------------------------
function f=ReadFloat(fid, Addr)
    fseek(fid,Addr,'bof');
    f=fread(fid,1,'float32');
   
%---------------------------------------------------------------------------------------
% Read 64Bit IEEE Double
%---------------------------------------------------------------------------------------
function d=ReadDouble(fid, Addr)
    fseek(fid,Addr,'bof');
    d=fread(fid,1,'float64');
   
%---------------------------------------------------------------------------------------
% Read string (up to 16 characters)
%---------------------------------------------------------------------------------------
function s=ReadString(fid, Addr)
    fseek(fid,Addr,'bof');
    s=fgets(fid,16);
%---------------------------------------------------------------------------------------
% Read timestamp
%---------------------------------------------------------------------------------------
function t=ReadTimestamp(fid, Addr)
    fseek(fid,Addr,'bof');
    seconds    = fread(fid,1,'float64');
   minutes    = fread(fid,1,'int8');
   hours        = fread(fid,1,'int8');
   days        = fread(fid,1,'int8');
   months    = fread(fid,1,'int8');
   year        = fread(fid,1,'int16');
   
   t=sprintf('%i.%i.%i, %i:%i:%2.0f', days, months, year, hours, minutes, seconds);
%---------------------------------------------------------------------------------------
% Timebase aus dem File lesen
%---------------------------------------------------------------------------------------
function t=ReadTimebase(fid, Addr)
    fseek(fid,Addr,'bof');
    e=fread(fid,1,'int16');
   
   tmp=[1 2 5];
   mant = tmp( 1+ mod(e,3));
   ex  = floor (e / 3)-12;
   
   t=mant*10^ex;   
%---------------------------------------------------------------------------------------
% fixed Vertical Gain aus dem File lesen
%---------------------------------------------------------------------------------------
function t=ReadFixed_vert_gain(fid, Addr)
    fseek(fid,Addr,'bof');
    e=fread(fid,1,'int16');
   
   tmp=[1 2 5];
   mant = tmp( 1+ mod(e,3));
   ex  = floor (e / 3)-6;
   
   t= mant*10^ex;   
%---------------------------------------------------------------------------------------
% Transform a Float to the Engineering-Format (returns a string)
%---------------------------------------------------------------------------------------
function s=Float_to_Eng (f)
   ex= floor(log10(f)); 
    exeng=ex-mod(ex,3);
   if exeng<-18; exeng=-18; end
   if exeng>18; exeng=18; end;
   mant=f/10^exeng;
   
   prefix=('afpnum kMGPE');    %prefixes (u=micro, m=milli, k=kilo, ...)
   s=sprintf('%g%s',mant, prefix( (exeng+18)/3 +1));

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值