No BSD License  

Highlights from
Tune And Listen

from Tune And Listen by Matt
This application allows the user to capture an AM or FM signal, demodulate it and play it out the

[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

Contact us at files@mathworks.com