source: ResearchApps/PHY/WARPLAB/WARPLab7/M_Code_Examples/wl_example_siso_spectrogram.m

Last change on this file was 4776, checked in by chunter, 8 years ago

reverted to previous svn rev (last commit unintentional)

File size: 8.3 KB
Line 
1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2% wl_example_siso_spectrogram.m
3%
4% In this example, we will use a single WARPLab receiver to plot a
5% spectrogram of a received waveform.
6%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7clear;
8
9CHANNEL         = 6;         % Choose the channel we will receive on
10
11NUM_SAMPLES     = 2^25;      % Number of samples to request
12
13WRITE_PNG_FILES = 1;         % Enable writing plots to PNG
14
15%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16% Set up the WARPLab experiment
17%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
18
19% Create a node object
20node = wl_initNodes(1);
21
22% Read Trigger IDs into workspace
23trig_in_ids  = wl_getTriggerInputIDs(node);
24trig_out_ids = wl_getTriggerOutputIDs(node);
25
26% For both nodes, we will allow Ethernet to trigger the buffer baseband and the AGC
27wl_triggerManagerCmd(node, 'output_config_input_selection', [trig_out_ids.BASEBAND, trig_out_ids.AGC], [trig_in_ids.ETH_A]);
28
29% Set the trigger output delays.
30%
31% NOTE:  We are waiting 3000 ns before starting the AGC so that there is time for the inputs
32%   to settle before sampling the waveform to calculate the RX gains.
33%
34node.wl_triggerManagerCmd('output_config_delay', [trig_out_ids.BASEBAND], 0);
35node.wl_triggerManagerCmd('output_config_delay', [trig_out_ids.AGC], 3000);     % 3000 ns delay before starting the AGC
36
37% Get IDs for the interfaces on the board.
38ifc_ids = wl_getInterfaceIDs(node);
39
40% Use RFA as the receiver
41RF_RX     = ifc_ids.RF_A;
42RF_RX_VEC = ifc_ids.RF_A;
43
44% Check the number of samples
45max_rx_samples = wl_basebandCmd(node, RF_RX, 'rx_buff_max_num_samples');
46
47if ( strcmp( class(node.transport), 'wl_transport_eth_udp_mex' ) )
48    if ( NUM_SAMPLES > node.baseband.MEX_TRANSPORT_MAX_IQ )
49        fprintf('\nWARNING:  Requested %d samples.  Due to Matlab memory limitations, the mex transport only supports %d samples.', NUM_SAMPLES, node.baseband.MEX_TRANSPORT_MAX_IQ);
50        fprintf('WARNING:  If your computer has enough physical memory, you can adjust this limit using node.baseband.MEX_TRANSPORT_MAX_IQ ');
51        fprintf('WARNING:  up to a maximum of %d samples.\n\n', max_rx_samples);
52       
53        NUM_SAMPLES = node.baseband.MEX_TRANSPORT_MAX_IQ;
54    end
55else 
56    if ( NUM_SAMPLES > node.baseband.JAVA_TRANSPORT_MAX_IQ )
57        fprintf('\nWARNING:  WARPLab by default only supports %d samples for the spectrogram\n', node.baseband.JAVA_TRANSPORT_MAX_IQ);
58        fprintf('WARNING:  using the java transport.  Please use the MEX transport to increase the\n');
59        fprintf('WARNING:  number of samples in the spectrogram.\n\n');
60
61        NUM_SAMPLES = node.baseband.JAVA_TRANSPORT_MAX_IQ;
62    end
63end
64
65if ( NUM_SAMPLES > max_rx_samples ) 
66    fprintf('\nWARNING:  Requested %d samples.  Node only supports %d samples.\n\n', NUM_SAMPLES, max_rx_samples);
67   
68    NUM_SAMPLES = max_rx_samples;   
69end
70
71% Get the sample rate of the node
72Ts = 1/(wl_basebandCmd(node, 'tx_buff_clk_freq'));
73
74% Print information to the console
75fprintf('WARPLab Spectrogram Example:\n');
76fprintf('    Generating spectrogram using %.4f seconds of data (%d samples).\n', (NUM_SAMPLES * Ts), NUM_SAMPLES );
77
78% Create a UDP broadcast trigger and tell each node to be ready for it
79eth_trig = wl_trigger_eth_udp_broadcast;
80wl_triggerManagerCmd(node, 'add_ethernet_trigger', [eth_trig]);
81
82% Set up the interface for the experiment
83wl_interfaceCmd(node, ifc_ids.RF_ALL, 'channel', 2.4, CHANNEL);
84
85% Set the gains manually
86wl_interfaceCmd(node, ifc_ids.RF_ALL, 'rx_gain_mode', 'manual');
87RxGainRF = 3;                % Rx RF Gain in [1:3]
88RxGainBB = 10;               % Rx Baseband Gain in [0:31]
89wl_interfaceCmd(node, ifc_ids.RF_ALL, 'rx_gains', RxGainRF, RxGainBB);
90
91%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
92% Receive signal using WARPLab
93%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
94
95% Set the receive length to the number of samples
96wl_basebandCmd(node, 'rx_length', NUM_SAMPLES);
97
98% Open up the transceiver's low-pass filter to its maximum bandwidth (36MHz)
99wl_interfaceCmd(node, RF_RX, 'rx_lpf_corn_freq', 3);
100
101% Enable to node to receive data
102wl_interfaceCmd(node, RF_RX, 'rx_en');
103wl_basebandCmd(node, RF_RX, 'rx_buff_en');
104
105% Trigger the node to receive samples
106eth_trig.send();
107
108% Read the samples from the node
109rx_IQ = wl_basebandCmd(node, RF_RX_VEC, 'read_IQ', 0, NUM_SAMPLES);
110
111% Disable the RX buffers
112wl_basebandCmd(node, ifc_ids.RF_ALL, 'tx_rx_buff_dis');
113wl_interfaceCmd(node, ifc_ids.RF_ALL, 'tx_rx_dis');
114
115%%
116close all
117%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
118% Visualize results
119%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
120
121% Figure 1: Time Series
122t_vec = (0:(NUM_SAMPLES-1))/(40e6);
123
124% MATLAB can really slow down when trying to plot a lot of samples. There
125% isn't much point to plotting a vector that is much longer than the number
126% of pixels in the plot, so we will decimate the vector down to ~10000 samples.
127
128rx_IQ_decimate = rx_IQ(1:floor(NUM_SAMPLES/10000):end);
129t_vec_decimate = t_vec(1:floor(NUM_SAMPLES/10000):end);
130
131figure(1);clf;
132ax(1) = subplot(2,1,1);
133plot(t_vec_decimate, real(rx_IQ_decimate),'b-')
134xlabel('Time (seconds)')
135title('I Received Waveform')
136
137ax(2) = subplot(2,1,2);
138plot(t_vec_decimate, real(rx_IQ_decimate),'b-')
139xlabel('Time (seconds)')
140title('Q Received Waveform')
141
142linkaxes(ax,'xy')
143axis tight
144
145if(WRITE_PNG_FILES)
146    print(gcf,'wl_rx_timeseries','-dpng','-r96','-painters')
147end
148
149% Figure 2: Spectrogram
150
151% MATLAB has a sophisticated 'spectrogram' function in the Signal Processing
152% Toolbox. In this example, we'll build our own crude spectrogram by
153% reshaping the received vector into a matrix and taking many FFTs. Note:
154% our approach has zero overlap in the FFTs.
155
156% Limit under which we will not show a zoomed in portion of the spectrogram. 
157zoom_span_time    = 100/1000;                         % 100 ms
158ZOOM_SAMPLE_LIMIT = 4 * (zoom_span_time * 40e6);
159
160
161% First, we need to split our receive vector into M pieces of N samples
162% each. The relative size of M and N affects whether you want more
163% resolution in time(M) or more resolution in frequency (N). By default, we
164% will make M equal to N, but this is not a fundamental requirement.
165M = floor(sqrt(NUM_SAMPLES));
166N = M;
167
168% Now we can reshape the received vector into a matrix of M rows and N columns;
169% Reshape the long vector of M*N to a matrix so we can take M FFTs of length N
170
171rx_IQ_slice    = rx_IQ(1:(M*N));
172rx_IQ_mat      = reshape(rx_IQ_slice, M, N).';
173rx_spectrogram = fft(rx_IQ_mat, N, 2);
174
175% Zero out any DC offset
176rx_spectrogram(:,1) = zeros(M,1);
177
178% Perform an fftshift so that the DC frequency bin is in the middle
179rx_spectrogram = fftshift(rx_spectrogram,2);
180
181% Plot the Spectrogram on a dB scale
182h = figure('units','pixels','Position',[100 100 2000 1000]);clf;
183set(h,'PaperPosition',[.25 .25 20 10]);
184
185% Plot the entire view
186if ( NUM_SAMPLES >= ZOOM_SAMPLE_LIMIT )
187    subplot(1,2,1)
188end
189
190x_axis = linspace(-20,20,N);
191y_axis = (0:(M-1)) / (40e6 / N);
192imagesc(x_axis,y_axis,20*log10(abs(rx_spectrogram)./max(abs(rx_spectrogram(:)))));
193caxis([-50 0])
194colorbar
195axis square
196
197xlabel('Frequency (MHz)')
198ylabel('Time (s)')
199title(sprintf('Spectrogram on dB Scale (%1.4f second view)', max(t_vec)))
200
201if ( NUM_SAMPLES >= ZOOM_SAMPLE_LIMIT )
202    % Zoom into a small piece in the middle of the spectrogram
203    subplot(1,2,2)
204
205    % Let's zoom in on a chunk out of the entire reception
206    zoom_span_index = ceil(zoom_span_time * (40e6 / N));
207    index_range     = floor((M/2)-(zoom_span_index/2)):floor((M/2)+(zoom_span_index/2));
208
209    y_axis_slice         = y_axis( index_range );
210    rx_spectrogram_slice = rx_spectrogram( index_range, : );
211
212    imagesc(x_axis, y_axis_slice, 20 * log10(abs(rx_spectrogram_slice)./max(abs(rx_spectrogram(:)))));
213    caxis([-50 0])
214    colorbar
215    axis square
216
217    xlabel('Frequency (MHz)')
218    ylabel('Time (s)')
219    title(sprintf('Spectrogram on dB Scale (%1.4f second view)', zoom_span_time))
220end
221
222if(WRITE_PNG_FILES)
223    print(gcf,'wl_rx_spectrogram','-dpng','-r200','-painters')
224end
225
226
227
228
229
Note: See TracBrowser for help on using the repository browser.