How does binblockread work? How can I modify it to read multiple binary blocks simultaneously?

13 次查看(过去 30 天)
I am trying to read the binary output of 4-channels from a Keysight N6705C power analyzer. In order to do this I query all 4 channels simultaneously with "writeline" using SCPI commands.
writeline(visaObj, ['FETC:ELOG? ' num2str(maxNumberDataPoints) ',(@1,2)']);
data = readbinblock(visaObj);
However, when I read the response with "readbinblock" I recieve the following error.
Format error detected during binblockread.binblock data must be in the format:#[N][D][A],
where '#' is the token marking the start of the binblock.'N' specifies the number of digits
in D that follow. 'D' specifies the number of data bytes in A that follow. A is the data
I get this error when I try to read more than one channel at a time. If I only read one channel I have no problems.
I believe what may be happening is that the power analyzer is sending 4 binary blocks at the same time which "readbinblock" does not like. So, think the best solution is to read the raw data unformated. However, when I try to read the binary blocks with "readline" something goes wrong and I seem to lose data. So, my question is how can I replicate the functionality of "readbinblock" but allow it to read multiple binary blocks simultaneously? How does "readbinblock" work?
Things I've Tried
  1. I have tried to look at the "readbinblock" code but it is protected.
  2. If tried looping the above code for each channel but that does not work because of previous lines of code that enable logging of multiple channels simultaneously.

采纳的回答

Christopher Saltonstall
编辑:Christopher Saltonstall 2021-12-10
Solved in the attached script.
clear
close all
%% USER INPUTS
%voltage or current reading
voltcurr = 'VOLT';
%binary (real) or ascii data
dataType = 'REAL';
%integration time (see manual)
integrationTime = 102.4e-6;
%time between reads from buffer
readPeriod = 0.1;
%max number of bytes to read
nBytes = 1e4;
%maximum number of points to store/plot. Prevents RAM issues
maxPoints = 1e5;
%channel selection (logical)
channel1 = 1;
channel2 = 1;
channel3 = 1;
channel4 = 0;
%% CONNECT TO ANALYZER
% USB Address. This can be found in Keysight Bench VUE or Connection Expert
PSUAddr = 'USB0::0x2A8D::0x0F02::MY56005672::0::INSTR';
% connect to device. Make sure drivers are installed. Also make sure the
% appropriate visa implimentations are enabled as preferred implementations
% using VISA Conflict Manager in Keysight Connection Expert: Keysight VISA
% and Keysight VISA.NET
app.PowerAnalyzer.PSU = visadev(PSUAddr);
%initialize the error list
errorlist = {};
%clear any logged errors
writeline(app.PowerAnalyzer.PSU,"*CLS");
errorlist = readerror(errorlist,app.PowerAnalyzer.PSU); %1
writeline(app.PowerAnalyzer.PSU,"*IDN?")
readline(app.PowerAnalyzer.PSU)
errorlist = readerror(errorlist,app.PowerAnalyzer.PSU); %2
%% CREATE CHANNEL LIST STRING
channel = [];
if channel1
channel = [channel '1'];
end
if channel2
if isempty(channel)
channel = [channel '2'];
else
channel = [channel ',2'];
end
end
if channel3
if isempty(channel)
channel = [channel '3'];
else
channel = [channel ',3'];
end
end
if channel4
if isempty(channel)
channel = [channel '4'];
else
channel = [channel ',4'];
end
end
%number of channels selected
nChannels = length(split(channel,','));
%% INITIALIZE ELOG
%abort any running triggers
writeline(app.PowerAnalyzer.PSU, ['ABOR:TRAN (@' num2str(channel) ')']); %3
errorlist = readerror(errorlist,app.PowerAnalyzer.PSU);
%set the format to binary block or ASCII
writeline(app.PowerAnalyzer.PSU, ['FORM ' dataType]);
errorlist = readerror(errorlist,app.PowerAnalyzer.PSU); %4
%setup to read current
if strcmp(voltcurr,'CURR')
%Enable Elog Current Measurement
writeline(app.PowerAnalyzer.PSU, ['SENS:ELOG:FUNC:CURR ON,(@' channel ')']);
errorlist = readerror(errorlist,app.PowerAnalyzer.PSU); %5
%Disable Elog Current Min/Max Measurement
writeline(app.PowerAnalyzer.PSU, ['SENS:ELOG:FUNC:CURR:MINM OFF,(@' channel ')']);
errorlist = readerror(errorlist,app.PowerAnalyzer.PSU); %6
%Disable Elog Voltage Measurement
writeline(app.PowerAnalyzer.PSU, ['SENS:ELOG:FUNC:VOLT OFF,(@' channel ')']);
errorlist = readerror(errorlist,app.PowerAnalyzer.PSU); %7
%Disable Elog Voltage Min/Max Measurement
writeline(app.PowerAnalyzer.PSU, ['SENS:ELOG:FUNC:VOLT:MINM OFF,(@' channel ')']);
errorlist = readerror(errorlist,app.PowerAnalyzer.PSU); %8
app.UIAxes.YLabel.String = 'Current (A)';
%setup to read voltage
elseif strcmp(voltcurr,'VOLT')
%Disable Elog Current Measurement
writeline(app.PowerAnalyzer.PSU, ['SENS:ELOG:FUNC:CURR OFF,(@' channel ')']);
errorlist = readerror(errorlist,app.PowerAnalyzer.PSU); %5
%Disable Elog Current Min/Max Measurement
writeline(app.PowerAnalyzer.PSU, ['SENS:ELOG:FUNC:CURR:MINM OFF,(@' channel ')']);
errorlist = readerror(errorlist,app.PowerAnalyzer.PSU); %6
%Enable Elog Voltage Measurement
writeline(app.PowerAnalyzer.PSU, ['SENS:ELOG:FUNC:VOLT ON,(@' channel ')']);
errorlist = readerror(errorlist,app.PowerAnalyzer.PSU); %7
%Disable Elog Voltage Min/Max Measurement
writeline(app.PowerAnalyzer.PSU, ['SENS:ELOG:FUNC:VOLT:MINM OFF,(@' channel ')']);
errorlist = readerror(errorlist,app.PowerAnalyzer.PSU); %8
app.UIAxes.YLabel.String = 'Voltage (V)';
else
error('Unknown VOLT/CURR setting')
end
%set sampling rate (options, 20.48 or 40.96 us)
writeline(app.PowerAnalyzer.PSU,'SENS:SWE:TINT:RES RES20')
errorlist = readerror(errorlist,app.PowerAnalyzer.PSU); %9
%Set the elog integration period to 1ms (min = 102.4 us (9.8 kHz), max = 60 s)
writeline(app.PowerAnalyzer.PSU, ['SENS:ELOG:PER ' num2str(nChannels*integrationTime) ',(@' channel ')']);
errorlist = readerror(errorlist,app.PowerAnalyzer.PSU); %10
%Select trigger source - Bus
writeline(app.PowerAnalyzer.PSU, ['TRIG:TRAN:SOUR BUS,(@' channel ')']);
errorlist = readerror(errorlist,app.PowerAnalyzer.PSU); %11
%Initiate the elog
writeline(app.PowerAnalyzer.PSU, ['INIT:ELOG (@' channel ')']);
errorlist = readerror(errorlist,app.PowerAnalyzer.PSU); %12
%Trigger the Elog
writeline(app.PowerAnalyzer.PSU, ['TRIG:ELOG (@' channel ')']);
errorlist = readerror(errorlist,app.PowerAnalyzer.PSU); %13
%Retrive the ELOG data
try
%initialize numeric array
data = [];
%intialize figure for plotting data
h = figure(101);
plot(h,data);
xlim([0, inf])
%loop
for idx = 1:5
%wait
pause(readPeriod)
%query
if strcmp(dataType,'REAL')
data_num = [];
writeline(app.PowerAnalyzer.PSU, ['FETC:ELOG? ' num2str(nBytes) ',(@' channel ')']);
for iChannels = 1:nChannels
data_temp = readbinblock(app.PowerAnalyzer.PSU)';
%convert data from bytes to single floats
data_channel = swapbytes(typecast(uint8(data_temp),'single'));
data_num = [data_num, data_channel];
end
elseif strcmp(dataType,'ASCII')
error('ASCII read not setup.')
else
error('Data type not recognize.')
end
%append data
data = [data; data_num];
%create time vector
nData = length(data);
maxtime = nChannels*integrationTime*nData;
time = linspace(nChannels*integrationTime,maxtime,nData)';
%limit the number of points plotted to prevent RAM issues
if nData > maxPoints
data = data(end-maxPoints:end);
time = time(end-maxPoints:end);
end
%plot collected data
plot(time,data)
xlabel('Time (s)')
ylabel(voltcurr)
end
catch ME
%abort
writeline(app.PowerAnalyzer.PSU, ['ABOR:ELOG (@' channel ')']);
errorlist = readerror(errorlist,app.PowerAnalyzer.PSU); %14
disp('External Datalogger Aborted');
end
%stop logging
app.Acq_OnOff_Lamp.Color = [1,0,0];
writeline(app.PowerAnalyzer.PSU, ['ABOR:ELOG (@' channel ')']);
errorlist = readerror(errorlist,app.PowerAnalyzer.PSU); %14 or 15
%% read and log all error queries
function errorlist = readerror(errorlist,visaObj)
%errors are stored in the power analyzer buffer and read out one at a time,
%most recent first. Therefore, it is good practice to read the errors
%after each command.
response = writeread(visaObj, 'SYST:ERR?');
idx = length(errorlist) + 1;
errorlist{idx,1} = response;
end

更多回答(0 个)

产品


版本

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by