No BSD License  

Highlights from
Tune And Listen

Tune And Listen

by

 

01 Feb 2008 (Updated )

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