Contact an Expert

Thread: Basic MATLAB script to connect to Agilent Scope


Permlink Replies: 5 - Pages: 1 - Last Post: May 15, 2012 10:45 AM Last Post By: algoss Threads: [ Previous | Next ]
algoss


Posts: 602
Registered: 11/03/06
Basic MATLAB script to connect to Agilent Scope
Posted: May 11, 2011 11:16 AM
Click to report abuse...   Click to reply to this thread Reply
I write a lot of scripts to talk to Agilent Infiniium Oscilloscopes. I find that the primary 'Acquisition' part of the scripts is all about the same. Here is what I tend to use, as a minimum, to set up the scope, capture data, and move it into MATLAB. It's not perfect, or maybe the best, but I think it's understandable. There may be errors, since I cut-and-pasted from a much larger script. Feel free to use it as you please.

function SetupandRun(visaAddress, Depth, Sample_Rate, Sig_Ch_Num)
% Connect to the instrument and set the buffer size and instrument timeout
inst = visa('agilent', visaAddress);

inst.InputBufferSize = 10000000; % This may need to be adjusted (depth * 2) + 1 should be enough
inst.Timeout = 10;
inst.ByteOrder = 'littleEndian';

fopen(inst);

Sig_Ch = ;

% Set the initial instrument parameters
fprintf(inst, '*RST');
fprintf(inst, ':stop;:cdis');
fprintf(inst, '*OPC?'); Junk = str2double(fscanf(inst));
fprintf(inst, );
fprintf(inst, '*OPC?'); Junk = str2double(fscanf(inst));
fprintf(inst, );
fprintf(inst, );
fprintf(inst, ':TRIGGER:EDGE:SLOPE POSITIVE');
fprintf(inst, );
fprintf(inst, ':ACQUIRE:MODE RTIME');
fprintf(inst, );
fprintf(inst, '*OPC?'); Junk = str2double(fscanf(inst));

% Get some data.
fwrite(inst, '*cls');
fwrite(inst, ':single');
% Wait for a trigger
ter = 0;
while(ter ~= 1)
fwrite(inst, ':ter?');
stringTer = fscanf(inst, '%s');
ter = str2double(stringTer);
end

% Now unload the ScopeData
fprintf(inst, ['WAV:SOURCE ', Sig_Ch);
fprintf(inst, 'WAV:FORMAT WORD');
fprintf(inst, 'WAVEFORM:BYTEORDER LSBFirst');
preambleBlock = query(inst,':WAVEFORM:PREAMBLE?');
fprintf(inst, '*OPC?'); Junk = str2double(fscanf(inst));
fprintf(inst,':WAV:DATA?');
ScopeData.RawData = binblockread(inst,'int16');
Junk = fread(inst,1,'schar'); % Read the EOF character
maxVal = 2^16;
preambleBlock = regexp(preambleBlock,',','split');
ScopeData.Format = str2double(preambleBlock{1}); % This should be 1, since we're specifying INT16 output
ScopeData.Type = str2double(preambleBlock{2});
ScopeData.Points = str2double(preambleBlock{3});
ScopeData.Count = str2double(preambleBlock{4}); % This is always 1
ScopeData.XIncrement = str2double(preambleBlock{5}); % in Time
ScopeData.XOrigin = str2double(preambleBlock{6}); % in Time
ScopeData.XReference = str2double(preambleBlock{7});
ScopeData.YIncrement = str2double(preambleBlock{8}); % Voltage
ScopeData.YOrigin = str2double(preambleBlock{9});
ScopeData.YReference = str2double(preambleBlock{10});
ScopeData.VoltsPerDiv = (maxVal * ScopeData.YIncrement /8); % V
ScopeData.Offset = ((maxVal/2 - ScopeData.YReference) * ScopeData.YIncrement + ScopeData.YOrigin); % V
ScopeData.SecPerDiv = ScopeData.Points * ScopeData.XIncrement/10 ; % seconds
ScopeData.Delay = ((ScopeData.Points/2 - ScopeData.XReference) * ScopeData.XIncrement + ScopeData.XOrigin); % seconds

% Scale the ScopeData
ScopeData.Time = (ScopeData.XIncrement.(1:length(ScopeData.RawData))) - ScopeData.XIncrement;
ScopeData.Volt = (ScopeData.RawData - ScopeData.YReference) .
ScopeData.YIncrement + ScopeData.YOrigin;

fclose(inst);
delete(inst);
rajsodhi

Posts: 22
Registered: 01/05/07
Re: Basic MATLAB script to connect to Agilent Scope
Posted: Jul 19, 2011 1:42 PM   in response to: algoss in response to: algoss
Click to report abuse...   Click to reply to this thread Reply
This is great! Thanks for posting this. I wanted a subroutine that would simply read in the data without presetting the instrument, so I edited your code as follows.

Yours,

Raj


function ScopeData = scope_read_data_algoss(inst, Sig_Ch_Num)
% function ScopeData = scope_read_data_algoss(inst, Sig_Ch_Num)
% This function assumes an instrument handle has already been created.
% Connect to the instrument and set the buffer size and instrument timeout
% inst = visa('agilent', visaAddress);

inst.InputBufferSize = 10000000; % This may need to be adjusted (depth * 2) + 1 should be enough
inst.Timeout = 10;
inst.ByteOrder = 'littleEndian';

% fopen(inst);

Sig_Ch = ['CHAN',num2str(Sig_Ch_Num)];

% Set the initial instrument parameters
% fprintf(inst, '*RST');
fprintf(inst, ':stop;:cdis');
fprintf(inst, '*OPC?'); Junk = str2double(fscanf(inst));
fprintf(inst, [':', Sig_Ch, ':DISPLAY ON']);
fprintf(inst, '*OPC?'); Junk = str2double(fscanf(inst));

% Get some data.
fprintf(inst, '*cls');
fprintf(inst, ':single');
% Wait for a trigger
ter = 0;
while(ter ~= 1)
ter = str2double(query(inst, ':ter?'));
end

% Now unload the ScopeData
fprintf(inst, ['WAV:SOURCE ', Sig_Ch]);
fprintf(inst, 'WAV:FORMAT WORD');
fprintf(inst, 'WAVEFORM:BYTEORDER LSBFirst');
preambleBlock = query(inst,':WAVEFORM:PREAMBLE?');
fprintf(inst, '*OPC?'); Junk = str2double(fscanf(inst));
fprintf(inst,':WAV:DATA?');
ScopeData.RawData = binblockread(inst,'int16');
Junk = fread(inst,1,'schar'); % Read the EOF character
maxVal = 2^16;
preambleBlock = regexp(preambleBlock,',','split');
ScopeData.Format = str2double(preambleBlock{1}); % This should be 1, since we're specifying INT16 output
ScopeData.Type = str2double(preambleBlock{2});
ScopeData.Points = str2double(preambleBlock{3});
ScopeData.Count = str2double(preambleBlock{4}); % This is always 1
ScopeData.XIncrement = str2double(preambleBlock{5}); % in Time
ScopeData.XOrigin = str2double(preambleBlock{6}); % in Time
ScopeData.XReference = str2double(preambleBlock{7});
ScopeData.YIncrement = str2double(preambleBlock{8}); % Voltage
ScopeData.YOrigin = str2double(preambleBlock{9});
ScopeData.YReference = str2double(preambleBlock{10});
ScopeData.VoltsPerDiv = (maxVal * ScopeData.YIncrement /8); % V
ScopeData.Offset = ((maxVal/2 - ScopeData.YReference) * ScopeData.YIncrement + ScopeData.YOrigin); % V
ScopeData.SecPerDiv = ScopeData.Points * ScopeData.XIncrement/10 ; % seconds
ScopeData.Delay = ((ScopeData.Points/2 - ScopeData.XReference) * ScopeData.XIncrement + ScopeData.XOrigin); % seconds

% Scale the ScopeData
ScopeData.Time = (ScopeData.XIncrement.(1:length(ScopeData.RawData))') - ScopeData.XIncrement;
ScopeData.Volt = (ScopeData.RawData - ScopeData.YReference) .
ScopeData.YIncrement + ScopeData.YOrigin;
FloJ

Posts: 9
Registered: 05/14/12
Re: Basic MATLAB script to connect to Agilent Scope
Posted: May 15, 2012 12:10 AM   in response to: algoss in response to: algoss
Click to report abuse...   Click to reply to this thread Reply
@algoss
Why do you use sometimes fprintf, sometimes fwrite. Why sometimes query aswell as scanf and binblockread?
FloJ

Posts: 9
Registered: 05/14/12
Re: Basic MATLAB script to connect to Agilent Scope
Posted: May 15, 2012 2:39 AM   in response to: FloJ in response to: FloJ
Click to report abuse...   Click to reply to this thread Reply
what is the :cdis command for? (fprintf(inst, ':stop;:cdis');). I can not find it in the manual or elsewhere.

And what about these commands fprintf(inst, ); ? Is it a delay?

Why is there a second line with fprintf(inst, '*OPC?'); Junk = str2double(fscanf(inst)) ?

In your example an int16 is used for the rawdata (ScopeData.RawData = binblockread(inst,'int16');). I guess this is right, but why does the example on mathworks use uint16?

Greetings
Flo
algoss


Posts: 602
Registered: 11/03/06
Re: Basic MATLAB script to connect to Agilent Scope
Posted: May 15, 2012 10:39 AM   in response to: FloJ in response to: FloJ
Click to report abuse...   Click to reply to this thread Reply
Why do you use sometimes fprintf, sometimes fwrite. Why sometimes query aswell as scanf and binblockread?

It's programming style, or maybe lack thereof. I pulled some pieces of the code from different places, and wasn't careful about how I pulled them together.

IIRC, there are also issues with building a formatted string on the fly.

Al
algoss


Posts: 602
Registered: 11/03/06
Re: Basic MATLAB script to connect to Agilent Scope
Posted: May 15, 2012 10:45 AM   in response to: FloJ in response to: FloJ
Click to report abuse...   Click to reply to this thread Reply
what is the :cdis command for? (fprintf(inst, ':stop;:cdis');). I can not find it in the manual or elsewhere.

"CDIS" is an Infiniium command, this example was written before the X3000 scopes existed.

And what about these commands fprintf(inst, ); ? Is it a delay?

Why is there a second line with fprintf(inst, '*OPC?'); Junk = str2double(fscanf(inst)) ?

I pulled out some non-essential commands, and didn't fully clean everything up.

In your example an int16 is used for the rawdata (ScopeData.RawData = binblockread(inst,'int16');). I guess this is right, but why does the example on mathworks use uint16?

Some scopes return uint16, and some return int16. On at least one of the examples on the MATLAB site, Vinod added a comment about that.

The intent was to show, approximately, the minimum necessary to use the scope in MATLAB, with enough detail to make it easier for someone else to not have to go through the pushups that I needed to, to get the first set of data into MATLAB.

Al

Point your RSS reader here for a feed of the latest messages in all forums