function demod_demo
% MATLAB Demo for Agilent MXA Signal Analyzer
% Rev 1.00, 1-Aug-06, by Henrique Miranda
% Rev 1.01, 2-Oct-06, DE, Revised softkey mapping strings (changed by 1)
% Rev 1.02, 13-Nov-06, DE, Used brighter colors for traces & softkeys
% Re-ordered code for readability
% Changed color & weight of FM trace
% Added many comments
% Designed to run INSIDE the MXA, demonstrates how to build a GUI
% Creates softkeys menu, traps sofkey press events
% Also traps FREQ hard-key, displays active entry areas using num keys
% UP and DOWN arrows cause large steps in freq
% LEFT and RIGHT arrows cause small steps in freq
% Changes to SPAN are currently disabled
% Performs analog AM, FM, PM demodulation; vertical units NOT scaled
% Use MXG or ESG to create real RF signal, set up MANUALLY
% Make sure source and MXA center frequency match each other
% Recommend FM with 10-100 kHz deviation at 1-10 kHz rate, MOD ON
% RF OUT must be on, recommend amplitude at -15 dBm
% Delete old instrument object, if any
instrreset
clear all
oldobjs=instrfind;
if ~isempty(oldobjs)
disp('Cleaning up ...')
delete(oldobjs);
clear oldobjs;
end
% Initialize variables
period=0.1; % Display update period
am_demod=0;
fm_demod=1; % Start with only FM turned on
pm_demod=0;
axes_color = [.6 .6 .6];
am_demod_color = [.8 0 0];
fm_demod_color = [.6 .6 0];
pm_demod_color = [0 .8 0];
selected_param = 'freq';
seq_125 = [1 2 5];
decades = logspace(1,8,8);
span_val = seq_125'*decades;
span_val = span_val(:)';
% Connect to instrument, set up
nimitz = 'nimitzcpu142.soco.agilent.com';
localhost = 'localhost';
disp(' ')
disp('Connecting to MXA ...');
mxa=tcpip(localhost,5025);
set(mxa,'InputBufferSize',30000);
set(mxa,'Timeout',10);
fopen(mxa);
% Intrument salute to verify connection
% fprintf('Hello from %s', query(mxa,'*IDN?'));
% Set format to REAL,32
fprintf(mxa,'*CLS');
fprintf(mxa,':FORM:BORD SWAP');
fprintf(mxa,':INST:PRES');
fprintf(mxa,':INST:NSEL 8');
fprintf(mxa,':SYST:PRES');
fprintf(mxa,'FORM:DATA REAL,32');
%nr_points = str2double(query(mxa,'SWE:POIN?'));
nr_points=2728;
h_spect_estmethod = spectrum.welch;
spect_points = 256;
% ref = str2double(query(mxa,'DISP:WIND:TRAC:Y:RLEV?'));
span = str2double(query(mxa,'SPEC:FREQ:SPAN?'));
center = str2double(query(mxa,'FREQ:CENT?'));
% fprintf(mxa,':DISP:ENAB OFF');
% corder = get(0,'defaultAxesColorOrder');
% corder = flipud(corder(1:6,:));
% corder(1,:)=[1 1 0];
% set(0,'defaultAxesColorOrder',corder);
% Initialize and lay out display, background, graphs, display-lines, etc.
fh=figure(1);
clf;
set(fh,'Units','normalized',...
'Backingstore','off',...
'Color','k',...
'Name','MXA Analog Demodulator Demo',...
'NumberTitle','off',...
'Menubar','none',...
'Position',[0 0 1.0000 0.975],...
'DefaultAxesFontSize',12,...
'DefaultTextFontSize',14,...
'DefaultTextFontName','Agilent Century ITC TT',...
'DefaultTextColor', [1 1 1],...
'DefaultAxesColor','k',...
'DefaultAxesXColor', axes_color,...
'DefaultAxesYColor', axes_color,...
'DefaultAxesZColor', axes_color,...
'DefaultAxesUnits','pixels',...
'DefaultAxesBox','on',...
'KeyPressFcn',@keypress);
ah=axes('Units','Normalized',...
'Nextplot','add',...
'XGrid','on',...
'YGrid','on',...
'gridlinestyle','-',...
'FontName','Agilent Century ITC TT',...
'Position',[.05 .52 .36 .38],...
'XTickLabel',[],...
'XLim',[1 nr_points],...
'Xtick',(nr_points-1)/10:(nr_points-1)/10:nr_points-1);
ah2 = axes('Units','Normalized',...
'Nextplot','add',...
'XGrid','on',...
'YGrid','on',...
'gridlinestyle','-',...
'FontName','Agilent Century ITC TT',...
'Position',[.05 .11 .78 .35],...
'XTickLabel',[],...
'XLim',[1 nr_points],...
'Xtick',(nr_points-1)/10:(nr_points-1)/10:nr_points-1);
ah3 = axes('Units','Normalized',...
'Nextplot','add',...
'XGrid','on',...
'YGrid','on',...
'gridlinestyle','-',...
'FontName','Agilent Century ITC TT',...
'Position',[.47 .52 .36 .38],...
'XTickLabel',[],...
'XLim',[1 spect_points],...
'Xtick',(spect_points-1)/10:(spect_points-1)/10:spect_points-1);
title(ah,'IQ Waveform');
title(ah2,'Demodulated Signal');
title(ah3,'IQ Spectrum');
ph_i = plot(ah,zeros(1,nr_points),'Color','y');
ph_q = plot(ah,zeros(1,nr_points),'Color','c');
ph_iq_spect = plot(ah3,zeros(1,spect_points),'Color','g');
ph_am_demod = plot(ah2,zeros(1,nr_points),'Color',am_demod_color,'Visible','off');
ph_fm_demod = plot(ah2,zeros(1,nr_points),'Color',fm_demod_color,'LineWidth',3,'Visible','off');
ph_pm_demod = plot(ah2,zeros(1,nr_points),'Color',pm_demod_color,'Visible','off');
if am_demod
set(ph_am_demod,'Visible','on')
end
if fm_demod
set(ph_fm_demod,'Visible','on')
end
if pm_demod
set(ph_pm_demod,'Visible','on')
end
% Create display for center frequency of MXA
freq_text_h = uicontrol('Style','text',...
'Units', 'normalized',...
'FontWeight','bold',...
'FontSize',16,...
'Position', [.05 .05 .25 .04],...
'ForegroundColor','g',...
'BackgroundColor','k',...
'HorizontalAlignment','left',...
'String', '');
% Create max frequency deviation display line at bottom
dev_max_text_h = uicontrol('Style','text',...
'Units', 'normalized',...
'FontWeight','bold',...
'FontSize',14,...
'Position', [.5 .05 .33 .04],...
'ForegroundColor','b',...
'BackgroundColor','k',...
'HorizontalAlignment','left',...
'String', '');
% Create frequency-offset display line at bottom
freq_off_text_h = uicontrol('Style','text',...
'Units', 'normalized',...
'FontWeight','bold',...
'FontSize',14,...
'Position', [.5 .01 .33 .04],...
'ForegroundColor','b',...
'BackgroundColor','k',...
'HorizontalAlignment','left',...
'String', '');
% Create active-entry box for changing frequency
edit_h = uicontrol('Units', 'normalized',...
'Style','edit',...
'FontWeight','bold',...
'ForegroundColor','g',...
'BackgroundColor',[0 0 0],...
'FontSize',16,...
'Position', [.35 .92 .2 .05],...
'String','',...
'Visible','off');
update_plot;
set(fh,'DefaultUicontrolFontsize',16,...
'DefaultUicontrolFontName','Agilent Century ITC TT',...
'DefaultUicontrolKeyPressFcn',@keypress)
% Softkey pannel initialization
softkey1h = uicontrol('Position',[880 630 130 60]);
softkey2h = uicontrol('Position',[880 532 130 60]);
softkey3h = uicontrol('Position',[880 434 130 60]);
softkey4h = uicontrol('Position',[880 336 130 60]);
softkey5h = uicontrol('Position',[880 238 130 60]);
softkey6h = uicontrol('Position',[880 140 130 60]);
softkey7h = uicontrol('position',[880 42 130 60]);
th =timer('timerfcn',@update_plot,...
'ExecutionMode','fixedspacing',...
'Period',period);
main_softkeys;
start(th)
function main_softkeys % Build main softkey menu
set(softkey1h, 'style', 'pushbutton',...
'string', 'Cont',...
'callback', @cont_button_callback);
set(softkey2h, 'style', 'pushbutton',...
'string', 'Single',...
'callback', @single_button_callback);
set(softkey3h, 'style', 'togglebutton',...
'string', 'AM Demod',...
'callback', @am_demod_callback);
set(softkey4h, 'style', 'togglebutton',...
'string', 'FM Demod',...
'callback', @fm_demod_callback);
set(softkey5h, 'style', 'togglebutton',...
'string', 'PM Demod',...
'callback', @pm_demod_callback);
set(softkey6h, 'style', 'togglebutton',...
'string', '',...
'callback', '');
set(softkey7h, 'style', 'pushbutton',...
'string', 'Close',...
'callback', @close_button_callback);
if am_demod
set(softkey3h,'FontWeight','bold',...
'ForegroundColor',am_demod_color,...
'Value',1)
end
if fm_demod
set(softkey4h,'FontWeight','bold',...
'ForegroundColor',fm_demod_color,...
'Value',1)
end
if pm_demod
set(softkey5h,'FontWeight','bold',...
'ForegroundColor',pm_demod_color,...
'Value',1)
end
end
function freq_softkeys % Build softkeys for units terminators
set(softkey1h, 'style', 'pushbutton',...
'string', 'Hz',...
'callback', @freq_Hz_button_callback);
set(softkey2h, 'style', 'pushbutton',...
'string', 'kHz',...
'callback', @freq_kHz_button_callback);
set(softkey3h, 'style', 'togglebutton',...
'string', 'MHz',...
'callback', @freq_MHz_button_callback);
set(softkey4h, 'style', 'togglebutton',...
'string', 'GHz',...
'callback', @freq_GHz_button_callback);
set(softkey5h, 'style', 'pushbutton',...
'string', '',...
'Callback','');
set(softkey6h, 'style', 'pushbutton',...
'string', '',...
'callback', '');
set(softkey7h, 'style', 'pushbutton',...
'string', 'Return',...
'callback', @return_callback);
end
function return_callback(source,eventdata)
set(edit_h,'Visible','off')
main_softkeys
end
function freq_Hz_button_callback(source,eventdata)
set(softkey1h,'fontweight','bold')
pause(.1)
set(softkey1h,'fontweight','normal')
fprintf(mxa,[':FREQ:CENT ' get(edit_h,'String')])
set(edit_h,'String','',...
'Visible','off')
main_softkeys
end
function freq_kHz_button_callback(source,eventdata)
set(softkey2h,'fontweight','bold')
pause(.1)
set(softkey2h,'fontweight','normal')
fprintf(mxa,[':FREQ:CENT ' num2str(str2double(get(edit_h,'String'))*1e3)])
set(edit_h,'String','',...
'Visible','off')
main_softkeys
end
function freq_MHz_button_callback(source,eventdata)
set(softkey3h,'fontweight','bold')
pause(.1)
set(softkey3h,'fontweight','normal')
fprintf(mxa,[':FREQ:CENT ' num2str(str2double(get(edit_h,'String'))*1e6)])
set(edit_h,'String','',...
'Visible','off')
main_softkeys
end
function freq_GHz_button_callback(source,eventdata)
set(softkey4h,'fontweight','bold')
pause(.1)
set(softkey4h,'fontweight','normal')
fprintf(mxa,[':FREQ:CENT ' num2str(str2double(get(edit_h,'String'))*1e9)])
set(edit_h,'String','',...
'Visible','off')
main_softkeys
end
function close_button_callback(source,eventdata)
set(softkey7h,'fontweight','bold')
pause(.1)
set(softkey7h,'fontweight','normal')
stop(th)
fprintf(mxa,':DISP:ENAB ON');
pause(.01)
fprintf(mxa,'*CLS');
pause(.01)
fprintf(mxa,'*RST');
pause(.01)
fprintf(mxa,':SYST:PRES')
pause(.01)
fprintf(mxa,':INST:NSEL 1');
disp('Disconnecting from MXA ...');
fclose(mxa);
delete(mxa);
clear mxa;
close(gcf)
instrreset
end
function cont_button_callback(source,eventdata)
stop(th)
set(source,'fontweight','bold')
pause(.1)
set(source,'fontweight','normal')
set(th,'ExecutionMode','fixedSpacing') % Makes timer repetitive
start(th)
end
function single_button_callback(source,eventdata)
stop(th)
set(softkey2h,'fontweight','bold')
pause(.1)
set(softkey2h,'fontweight','normal')
set(th,'ExecutionMode','singleShot') % Makes timer a single-shot
start(th)
end
function am_demod_callback(source,eventdata)
if strcmp(eventdata,'key')
if ~get(softkey3h,'Value')
set(softkey3h,'Value',1)
else
set(softkey3h,'Value',0)
end
end
button_status=get(source,'value');
if button_status
set(softkey3h,'fontweight','bold')
set(source,'ForegroundColor','r')
set(ph_am_demod,'Visible','on')
am_demod=1;
else
set(softkey3h,'fontweight','normal')
set(source,'ForegroundColor','k')
set(ph_am_demod,'Visible','off')
am_demod=0;
end
end
function fm_demod_callback(source,eventdata)
if strcmp(eventdata,'key')
if ~get(softkey4h,'Value')
set(softkey4h,'Value',1)
else
set(softkey4h,'Value',0)
end
end
button_status=get(source,'value');
if button_status
set(softkey4h,'fontweight','bold')
set(source,'ForegroundColor',fm_demod_color)
set(ph_fm_demod,'Visible','on')
fm_demod=1;
else
set(softkey4h,'fontweight','normal')
set(source,'ForegroundColor','k')
set(ph_fm_demod,'Visible','off')
fm_demod=0;
end
end
function pm_demod_callback(source,eventdata)
if strcmp(eventdata,'key')
if ~get(softkey5h,'Value')
set(softkey5h,'Value',1)
else
set(softkey5h,'Value',0)
end
end
button_status=get(source,'value');
if button_status
set(softkey5h,'fontweight','bold')
set(source,'ForegroundColor',pm_demod_color)
set(ph_pm_demod,'Visible','on')
pm_demod=1;
else
set(softkey5h,'fontweight','normal')
set(source,'ForegroundColor','k')
set(ph_pm_demod,'Visible','off')
pm_demod=0;
end
end
function ave_popup_callback(source,eventdata)
str = get(source,'String');
val = get(source,'Value');
fprintf(mxa,['AVER:COUNT ' str{val}]);
end
function keypress(source,event)
if (length(event.Modifier) == 2 && ...
strcmp(event.Modifier{1},'shift') && ...
strcmp(event.Modifier{2},'control'))
if event.Key(1) == 'd'
close_button_callback
end
if strcmp(event.Key,'f7')
%close_button_callback
feval(get(softkey7h,'Callback'),softkey7h,[])
end
if strcmp(event.Key,'f1')
feval(get(softkey1h,'Callback'),softkey1h,[])
end
if strcmp(event.Key,'f2')
feval(get(softkey2h,'Callback'),softkey2h,[])
end
if strcmp(event.Key,'f3')
feval(get(softkey3h,'Callback'),softkey3h,'key')
end
if strcmp(event.Key,'f4')
feval(get(softkey4h,'Callback'),softkey4h,'key')
end
if strcmp(event.Key,'f5')
feval(get(softkey5h,'Callback'),softkey5h,'key')
end
if strcmp(event.Key,'f')
selected_param='freq';
set(freq_text_h,'ForegroundColor','g')
%set(span_text_h,'Color','w')
%set(ref_text_h,'Color','w')
set(edit_h,'Visible','on','String','')
set(softkey1h,'ForegroundColor','k','FontWeight','Normal')
set(softkey2h,'ForegroundColor','k','FontWeight','Normal')
set(softkey3h,'ForegroundColor','k','FontWeight','Normal')
set(softkey4h,'ForegroundColor','k','FontWeight','Normal')
set(softkey5h,'ForegroundColor','k','FontWeight','Normal')
set(softkey6h,'ForegroundColor','k','FontWeight','Normal')
set(softkey7h,'ForegroundColor','k','FontWeight','Normal')
freq_softkeys
end
% if strcmp(event.Key,'s')
% selected_param='span';
% set(freq_text_h,'Color','w')
% set(span_text_h,'Color','g')
% set(ref_text_h,'Color','w')
% end
% if strcmp(event.Key,'a')
% selected_param='ref';
% set(freq_text_h,'Color','w')
% set(span_text_h,'Color','w')
% set(ref_text_h,'Color','g')
% end
end
if strcmp(event.Key,'uparrow')
if strcmp(selected_param,'freq')
fprintf(mxa,[':FREQ:CENT ' num2str(center + span/10)]);
end
if strcmp(selected_param,'span')
[span_tmp, span_idx] = min(abs(span_val-span));
if ((span_idx == 1) || (span_idx == length(span_val)))
next_span = span_val(span_idx);
else
next_span = span_val(span_idx+1);
end
fprintf(mxa,[':FREQ:SPAN ' num2str(next_span)]);
end
if strcmp(selected_param,'ref')
fprintf(mxa,[':DISP:WIND:TRAC:Y:RLEV ' num2str(round(ref) + 10)]);
end
end
if strcmp(event.Key,'downarrow')
if strcmp(selected_param,'freq')
fprintf(mxa,[':FREQ:CENT ' num2str(center - span/10)]);
end
if strcmp(selected_param,'span')
[span_tmp, span_idx] = min(abs(span_val-span));
if ((span_idx == 1) || (span_idx == length(span_val)))
next_span = span_val(span_idx);
else
next_span = span_val(span_idx-1);
end
fprintf(mxa,[':FREQ:SPAN ' num2str(next_span)]);
end
if strcmp(selected_param,'ref')
fprintf(mxa,[':DISP:WIND:TRAC:Y:RLEV ' num2str(round(ref) - 10)]);
end
end
if strcmp(event.Key,'leftarrow')
if strcmp(selected_param,'freq')
fprintf(mxa,[':FREQ:CENT ' num2str(center - span/200)]);
end
if strcmp(selected_param,'span')
fprintf(mxa,[':FREQ:SPAN ' num2str(span - span/200)]);
end
if strcmp(selected_param,'ref')
fprintf(mxa,[':DISP:WIND:TRAC:Y:RLEV ' num2str(round(ref) - 1)]);
end
end
if strcmp(event.Key,'rightarrow')
if strcmp(selected_param,'freq')
fprintf(mxa,[':FREQ:CENT ' num2str(center + span/200)]);
end
if strcmp(selected_param,'span')
fprintf(mxa,[':FREQ:SPAN ' num2str(span + span/200)]);
end
if strcmp(selected_param,'ref')
fprintf(mxa,[':DISP:WIND:TRAC:Y:RLEV ' num2str(round(ref) + 1)]);
end
end
if (strcmp(event.Key,'0') ||...
strcmp(event.Key,'1') ||...
strcmp(event.Key,'2') ||...
strcmp(event.Key,'3') ||...
strcmp(event.Key,'4') ||...
strcmp(event.Key,'5') ||...
strcmp(event.Key,'6') ||...
strcmp(event.Key,'7') ||...
strcmp(event.Key,'8') ||...
strcmp(event.Key,'9'))
set(edit_h,'String', [get(edit_h,'String') event.Key])
end
if strcmp(event.Key,'period')
set(edit_h,'String', [get(edit_h,'String') '.'])
end
if strcmp(event.Key,'backspace')
present_edit_string = get(edit_h,'String');
set(edit_h,'String', present_edit_string(1:end-1))
end
%event.Key
%event.Modifier
%event.Character
end
function str=process_freq_units(val)
if (abs(val) < 1e3) str = sprintf('%3.0f Hz',val);
elseif (abs(val) < 1e6) str = sprintf('%3.3f kHz',val/1e3);
elseif (abs(val) < 1e9) str = sprintf('%3.6f MHz',val/1e6);
else str = sprintf('%3.9f GHz',val/1e9);
end
end
function update_plot(varargin)
fprintf(mxa,':READ:WAV0?');
data = binblockread(mxa,'float32');
%nr_points=length(data);
fscanf(mxa); % Remove the data block terminator
inphase = data(1:2:end);
quad = data(2:2:end);
set(ph_i,'Ydata',inphase);
set(ph_q,'Ydata',quad);
set(ah,'Ylim', [-.2 .2])
set(ah,'YTick',-.2:.05:.2)
iq = inphase + j*quad;
ang = angle(iq);
ph = unwrap(ang);
demod = diff(ph);
demod_detrend = detrend(demod);
if fm_demod
set(ph_fm_demod,'Ydata',demod);
end
if am_demod
set(ph_am_demod,'Ydata',abs(iq));
end
if pm_demod
set(ph_pm_demod,'Ydata',ang/(2*pi));
end
set(ah2,'Ylim', [-.5 .5])
set(ah2,'YTick',-.5:.1:.5)
hspect_plot = msspectrum(h_spect_estmethod,iq,...
'NFFT',spect_points,'CenterDC',true);
set(ph_iq_spect,'Ydata',10*log10(hspect_plot.data));
set(ah3,'Ylim', [-90 10])
set(ah3,'YTick',-90:10:10)
%ref = str2double(query(mxa,'DISP:WIND:TRAC:Y:RLEV?'));
%span = str2double(query(mxa,':FREQ:SPAN?'));
center = str2double(query(mxa,'FREQ:CENT?'));
%rl=round(ref*10)/10;
%set(ah,'Ylim', [rl-100 rl])
%set(ah,'YTick',rl-100:10:rl)
%set(ah,'Yticklabel',num2str( (rl-100:10:rl)','%+6.1f\n'))
%%set(ah,'YTick',rl-100:10:rl) %comment to make grid slide
set(freq_text_h, 'String', ['Center: ' process_freq_units(center)]);
%set(span_text_h, 'String', ['Span: ' process_freq_units(str2double(query(mxa,'FREQ:SPAN?')))]);
%set(ref_text_h, 'String', sprintf('Ref: %.2f dBm', ref));
dev_max = max(abs(demod_detrend))/(2*pi*733.33333e-9);
set(dev_max_text_h, 'String', ['Max. Freq. Deviation: ' process_freq_units(dev_max)]);
% dev_min = min(demod_detrend)/(2*pi*733.33333e-9);
% set(dev_min_text_h, 'String', ['Max freq deviation: ' process_freq_units(dev_min)]);
freq_off = mean(demod)/(2*pi*733.33333e-9);
set(freq_off_text_h, 'String', ['Freq. Offset: ' process_freq_units(freq_off)]);
drawnow
end
end