| [y,samplePeriod]=saAcquisition(hnd, fc, bw, time, range, verbose, fptr, param1)
|
function [y,samplePeriod]=saAcquisition(hnd, fc, bw, time, range, verbose, fptr, param1)
% [Y,SAMPLEPERIOD]=SAACQUISITION(HND, FC, BW, TIME, RANGE, VERBOSE)
% hnd is a handle to a psa or mxa
% fc is the center frequency (Hz) you want to listen
% bw is the bandwidth (Hz)
% time is the amount of time (seconds) data you want
% range is power range of the analyzer use <=-100 to autorange
% verbose controls verbosity of the app
%% Check the variables for good results
if ~isobject(hnd),
Error('hnd must be a instrument handle.');
end
if nargin == 6,
fptr = @(dummy, str) disp(str);
param1 = 1;
elseif nargin == 7,
error('you must pass in at least one parameter with your print function.');
elseif nargin < 6,
error('must have at 6 inputs.');
elseif nargin > 8,
error('too many inputs.');
end
%% setup handle
%setup the handle
fclose(hnd); %close it just in case its open
%MATLAB doesn't like it when
%properties are manipulated with the handle open
bufferSize = 2^10;
set(hnd,'InputBufferSize',bufferSize,...
'TimerPeriod', 1.0, ...
'ByteOrder', 'bigEndian', ...
'Timeout', 30);
fopen(hnd);
%
%% check to see if analyzer is a good one
idn = query(hnd,'*idn?');
s1=strfind(idn,',');
model = strtrim(idn(s1(1)+1:s1(2)-1));
clear s1;
if ~(strcmp(model, 'N9020A') || ...
strcmp(model, 'E4440A') ||...
strcmp(model, 'N9010A')),
error('The instrument is not an MXA, PSA or EXA.');
end
%% Figure out some ranging equations
if range > 30,
warning('SALISTEN:paramOutOfBounds','Analyzer maybe damaged by a signal stronger than 30 dBm');
end
targetPower = -24; % dBm
% it appears the 1 dB compression points for both the PSA
% and MXA are largely the same. <= 3 dB. Since the IF Gain
% has a larger range than this number, and in the interest
% of keeping the software simple, we will set a
% conservative number and let the IF Gain make up the
% difference in the both the analyzers
% TODO: Check the EXA spec sheet for 1 dB compression pt.
if range < targetPower,
% we might need the preamp
% see if the analyzer has a preamp
opt = query(hnd,'*opt?');
if strcmp(model ,'E4440A'),
preAmpAvailable = ~isempty(strfind(opt,'1DS')) && fc <= 3.05e9;
preAmpGain = 28;
else
preAmpAvailable = (~isempty(strfind(opt,'P03')) && fc <= 3.6e9) || ...
(~isempty(strfind(opt,'P08')) && fc <= 8.4e9) || ...
(~isempty(strfind(opt,'P13')) && fc <= 13.6e9) || ...
(~isempty(strfind(opt,'P26')) && fc <= 26.5e9);
preAmpGain = 30;
end
end
if range <= -100,
autoRange = 1;
else
autoRange = 0;
att = min(70,2*ceil((range-targetPower)/2));
if (att < 0) && preAmpAvailable,
preAmp = 1;
att = att + preAmpGain;
else
preAmp = 0;
end
att = max(att,0);
end
%% setup acquisition
if verbose,
fptr(param1, 'setup acquisition');
end
setupStr = [':INST:NSEL 8' ';:FORM:DATA REAL,32' ...
';:INIT:CONT OFF'];
if strcmp(model,'E4440A'),
setupStr = [ setupStr ';:WAV:BAND:TYPE FLAT'];
else
setupStr = [ setupStr ';:WAV:BAND:SHAP FLAT'];
end
fprintf(hnd, setupStr);
setupStr=sprintf([':FREQ:CENT %f;:WAV:BAND %f;' ...
':WAV:SWE:TIME %f'], ...
fc, ...
bw, ...
time);
fprintf(hnd,setupStr);
if strcmp(model,'E4440A'),
if autoRange,
setupStr=':POW:RANGE:AUTO 1;:DIAG:PAMP 0';
else
setupStr=sprintf(':POW:ATT %5f;:DIAG:PAMP %d',att,preAmp);
end
else
if autoRange,
setupStr=':POW:GAIN 0;:POW:RANGE:OPT:ATT COMB';
else
setupStr = sprintf(':POW:ATT %5f;:POW:GAIN:BAND FULL;:POW:GAIN %d',att,preAmp);
end
end
fprintf(hnd,setupStr);
fprintf(hnd,'INIT:IMM;*WAI');
fcr=query(hnd,'FREQ:CENT?','%s\n','%f');
bwr=query(hnd,'WAV:BAND?','%s\n','%f');
%timr=query(hnd,'WAV:SWE:TIME?','%s\n','%f');
% it appears this scpi command is just a place holder
if abs(fcr-fc)>0.01*bw,
warning('SALISTEN:paramOutOfBounds','Analyzer using a different center frequency. Using %f Hz',fcr);
end
if abs((bwr-bw)/bw)>.01,
warning('SALISTEN:paramOutOfBounds','Analyzer using a diffent bandwidth. Using %f Hz',bwr);
end
if verbose,
fptr(param1, 'querying sample period');
end
fprintf(hnd,'READ:WAV1?');
buffer=binblockread(hnd,'float');
fread(hnd,1,'uchar');
samplePeriod = buffer(1);
numData = 2*buffer(4); % number of data samples
dataBytes = 4*numData;
reqBufferSize = dataBytes + 20; % convert to bytes being returned
timr = buffer(4)*buffer(1);
if abs((timr-time)/time) > .01,
warning('SALISTEN:paramOutOfBounds','Analyzer using a different time length. Using %f seconds.',timr);
end
numDataUpperLimit = 65536;
numDataThreshold = 262144;
dataCount = min(round(0.1 * numData), numDataUpperLimit);
%% reAdjust the handle properties based upon current acquisition
fclose(hnd);
if reqBufferSize > bufferSize,
bufferSize = reqBufferSize;
set(hnd,'InputBufferSize',bufferSize);
end
fopen(hnd);
%% read data
if verbose,
fptr(param1, 'reading data');
end
fprintf(hnd,':READ:WAV0?');
%
a=char(fread(hnd,1)); % read the '#' character
numChars = str2double(char(fread(hnd,1))); % read number of characters
dataBytes = str2double(char(fread(hnd,numChars))); % read in number of bytes
numData = floor(dataBytes / 4);
if numData > numDataThreshold,
buffer=zeros(numData,1);
start = 1;
while start < numData,
stop = min(start + dataCount - 1, numData);
buffer(start:stop) = fread(hnd, stop - start + 1, 'single');
start = stop + 1;
if verbose,
fptr(param1, sprintf('read %3.0f%% of the acquisition.',stop/numData * 100));
end
end
else
buffer=fread(hnd, numData, 'single');
if verbose,
fptr(param1, 'read 100% of the acquisition.');
end
end
fread(hnd,1);
if verbose,
fptr(param1,'acquisition completed.');
end
y=buffer(1:2:end)+j*buffer(2:2:end);
function readData(hInstr,event)
% disp('readData entered');
% disp(event.Type);
% disp(event.Data);
bytesAvailable = get(hInstr,'BytesAvailable');
numData = floor(bytesAvailable / 4);
if numData > 0,
props = get(hInstr,'UserData');
start = props.StartIndex;
stop = start + numData - 1;
props.Buffer(start:stop) = fread(hInstr, numData, 'single');
if props.Verbose,
disp(sprintf('read %3.0f%%', stop/length(props.Buffer)*100));
end
props.StartIndex = stop + 1;
props.DataBytes = props.DataBytes - bytesAvailable;
if props.DataBytes < props.FcnCount,
bytesAvailable = props.DataBytes;
numData = floor(bytesAvailable / 4);
if numData > 0,
start = props.StartIndex;
stop = start + numData - 1;
props.Buffer(start:stop) = fread( hInstr, numData, 'single');
if props.Verbose,
disp(sprintf('read %3.0f%%', stop/length(props.Buffer)*100));
end
else
fread(hInstr, numData);
end
props.DataBytes = 0;
end
set(hInstr,'UserData',props);
end
|
|