source: ResearchApps/PHY/WARPLAB/WARPLab_v05_2/WorkshopExercises/warplab_siso_example_Comm_WorkshopExercise.m

Last change on this file was 1455, checked in by sgupta, 12 years ago

workshop exercises

File size: 25.9 KB
Line 
1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2% Using WARPLab (SISO configuration) to Transmit Bits Over a Wireless
3% Channel .
4%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5
6% This matlab srcipt generates a bitstream, modulates the bitstream using
7% DQPSK, transmits the modulated symbols over a wireless channel using
8% WARPLab, and demodulates the received signal to obtain the
9% transmitted bits. Bit error rate (BER) is computed by comparing the
10% transmitted bitstream with the bitstream recovered at the receiver
11
12% The specific steps implemented in this script are the following:
13
14% 0. Initialization, define paramters, create pulse shaping filter, and
15% create reference matrix for detection of preamble
16% 1. Generate a random bit stream and map it to symbols
17% 2. Modulate the symbols (map symbols to constellation points) and append
18% preamble symbols
19% 3. Upsample the modulated symbols with the appended preamble and filter
20% using a pulse shaping filter
21% 4. Upconvert from baseband to 5MHz to avoid radio DC attenuation
22% 5. Transmit the signal over a wireless channel using Warplab
23% 6. Downconvert from 5MHz to baseband
24% 7. Filter the received signal with a Matched Filter (matched to the pulse
25% shaping filter), detect preamble, and downsample output of Matched Filter
26% 8. Demodulate and recover the transmitted bitstream
27% 9. Compute the Bit Error Rate (BER) and close sockets
28
29% Part of this code was adapted from Matlab's commdoc_mod and commdoc_rrc
30% examples.
31
32% You will write a matlab script that implements the ten steps above.
33% Part of the code is provided, some part of the code you will write. Read
34% the code below and fill in with your code wherever you are asked to do
35% so.
36
37% NOTE : To avoid conflict with other groups using the boards, please
38% test the code you write in this script in any of the following three
39% ways:
40%
41% Option 1. Run this script from matlab's Command Window by entering the
42% name of the script (enter warplab_siso_example_Comm_WorkshopExercise
43% in matlab's Command Window).
44% Option 2. In the menu bar go to Debug and select Run. If there
45% are errors in the code, error messages will appear in the Command Window.
46% Option 3. Press F5. If the are errors in the code, error messages will
47% appear in the Command Window.
48%
49% DO NOT USE the Evaluate selection option and DO NOT run the script by
50% sections. To test any change, always run the whole script by following
51% any of the three options above.
52
53try,
54%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
55% Code to avoid conflict between users, only needed for the workshop, go to
56% step 0 below to start the initialization and definition of parameters
57%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
58% fid = fopen('c:\boards_lock.txt');
59%
60% if(fid > -1)
61%     fclose('all');
62%   errordlg('Boards already in use - Please try again!');
63%   return;
64% end
65%
66% !echo > c:\boards_lock.txt
67
68%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
69% 0. Initialization, define paramters, create pulse shaping filter, and
70% create reference matrix for detection of preamble
71%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72% Define basic parameters
73M = 4; % Size of signal constellation
74k = log2(M); % Number of bits per symbol
75nsamp = 8; % Oversampling rate or Number of samples per symbol
76
77% Define parameters related to the pulse shaping filter and create the
78% pulse shaping filter
79% This pulse shaping filter is a Squared Root Raised Cosine (SRRC) filter
80filtorder = 64; % Filter order
81delay = filtorder/(nsamp*2); % Group delay (# of input samples). Group
82% delay is the time between the input to the filter and the filter's peak
83% response counted in number of input samples. In number of output samples
84% the delay would be equal to 'delay*nsam'.
85rolloff = 0.3; % Rolloff factor of filter
86rrcfilter = rcosine(1,nsamp,'fir/sqrt',rolloff,delay); % Create SRRC filter
87
88% Plot the filter's impulse response in a stem plot
89figure; % Create new figure window.
90stem(rrcfilter);
91title('Raised Cosine Impulse Response');
92xlabel('n (samples)'); ylabel('Amplitude');
93
94% Define number of symbols to process, number of bits to process, and the
95% preamble.
96% The Warplab transmit buffer can store a maximum of 2^14 samples, the
97% number of samples per symbol is equal 'nsam', and the SRRC filter delay
98% in number of samples is equal to 'delay*nsam'. Consequently, the total
99% number of symbols to be transmitted must be less than
100% (2^14-200)/nsam-2*delay. We subtract extra 200 to account for jitter in
101% sync trigger.
102nsym = floor((2^14-200)/nsamp-2*delay);  % Number or symbols to transmit
103preamble = [-1;-1;-1;1;-1;0;0;0;0;0;0;0;0]; % Preamble is a Barker sequence
104                                            % modulated with BPSK
105nsym_preamble = length(preamble); % number of symbols in preamble
106nsym_payload = nsym-nsym_preamble;
107nbits = floor(nsym_payload*k); % Number of bits to process
108
109% Create a reference matrix used for detection of the preamble in the
110% received signal. We will correlate the received signal with the reference
111% matrix
112preamble_upsamp = upsample(preamble,nsamp); % Upsample preamble
113length_preamble_upsamp = length(preamble_upsamp);
114corr_window = 300; % We expect to find the preamble within the first
115                   % 300 received samples
116reference_samples = zeros(corr_window,1); % Create reference vector.
117reference_samples(1:length_preamble_upsamp) = preamble_upsamp; 
118                     % First samples of reference vector correspond to the
119                     % preamble upsampled
120reference_matrix = toeplitz(reference_samples,...
121circshift(reference_samples(corr_window:-1:1),1)); 
122         % Create reference matrix. The first column of the reference
123         % matrix is equal to the reference_samples vector. The i-th column
124         % of the reference matrix is equal to circular shift of the
125         % reference samples vector, it is a shift down by i samples.
126
127
128%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
129% 1. Generate a random bit stream and map it to symbols
130%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
131
132%-------------------------------------------------------------------------%
133% USER CODE HERE
134
135% Create a random binary data stream as a column vector. The number of
136% elements is equal to 'nbits'. You can use Matlab's 'randint' function.
137% Store the vector in a variable named 'x'
138
139%-------------------------------------------------------------------------%
140
141% Map bits in vector x into k-bit symbols
142xsym = bi2de(reshape(x,k,length(x)/k).','left-msb');
143
144% Stem plot of bits and symbols
145% Plot first 40 bits in a stem plot.
146figure;
147subplot(2,1,1)
148stem(x(1:40),'filled');
149title('Random Bits');
150xlabel('Bit Index'); ylabel('Binary Value');
151% Plot first 40/k symbols in a stem plot.
152subplot(2,1,2)
153stem(xsym(1:40/k),'filled');
154title('Random Bits Mapped to Symbols');
155xlabel('Symbol Index'); ylabel('Integer Value');
156
157%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
158% 2. Modulate the symbols (map symbols to constellation points) and append
159% preamble symbols
160%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
161
162%-------------------------------------------------------------------------%
163% USER CODE HERE
164
165% Modulate the symbols in vector 'xsym' using DQPSK. You can use Matlab's
166% 'dpskmod' function. The alphabet or constellation size 'M' was set in
167% step 0 above as 'M=4'. Store the modulated symbols in a variable named
168% 'ytx_mod'.
169
170%-------------------------------------------------------------------------%
171
172% Append preamble
173ytx_mod = [preamble;ytx_mod];
174
175%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
176% 3. Upsample the modulated symbols with the appended preamble and filter
177% using a pulse shaping filter
178%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
179% Upsample and apply square root raised cosine filter.
180ytx_mod_filt = rcosflt(ytx_mod,1,nsamp,'filter',rrcfilter);
181
182% Stem Plot of modulated symbols before and after Squared Root Raised
183% Cosine (SRRC) filter
184% Plots first 30 symbols.
185% Plots I and Q in different windows
186figure; % Create new figure window.
187subplot(2,1,1)
188stem([1:nsamp:nsamp*30],real(ytx_mod(1:30)));
189hold
190stem(real(ytx_mod_filt(1+delay*nsamp:1+30*nsamp+delay*nsamp)),'r');
191title('I Signal');
192xlabel('n (sample)'); ylabel('Amplitude');
193legend('Before SRRC Filter','After SRRC Filter');
194subplot(2,1,2)
195stem([1:nsamp:nsamp*30],imag(ytx_mod(1:30)));
196hold
197stem(imag(ytx_mod_filt(1+delay*nsamp:1+30*nsamp+delay*nsamp)),'r');
198title('Q Signal');
199xlabel('n (sample)'); ylabel('Amplitude');
200
201%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
202% 4. Upconvert from baseband to 5MHz to avoid radio DC attenuation
203%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
204time = [0:1:length(ytx_mod_filt)-1]/40e6; % Sampling Freq. is 40MHz
205ytx_mod_filt_up = ytx_mod_filt .* exp(sqrt(-1)*2*pi*5e6*time).';
206
207%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
208% 5. Transmit the signal over a wireless channel using Warplab
209%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
210% Follow the steps for transmission and reception of data using Warplab.
211% These are the steps in the matlab script warplab_example_TxRx.m
212
213% In this example the vector to transmit is the 'ytx_mod_filt' vector.
214
215%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
216% 5.0. Initializaton and definition of parameters
217%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
218%Load some global definitions (packet types, etc.)
219warplab_defines
220
221% Create Socket handles and intialize nodes
222[socketHandles, packetNum] = warplab_initialize;
223
224% Separate the socket handles for easier access
225% The first socket handle is always the magic SYNC
226% The rest of the handles are the handles to the WARP nodes
227udp_Sync = socketHandles(1);
228udp_node1 = socketHandles(2);
229udp_node2 = socketHandles(3);
230
231% Define WARPLab parameters.
232%-------------------------------------------------------------------------%
233% USER CODE HERE
234
235% Create the following variables and assign them valid values:
236% TxDelay: Value of the Transmitter Delay. For this exercise set TxDelay
237%             equal to 100. This value of TxDelay will allow detection
238%             of the preamble if there is a jitter of 100 samples or less
239%             in the sync trigger (if transmission is triggered 100 samples
240%             or less before capture is triggered).
241% TxLength : Length of transmission or number of samples to transmit.
242%            In [0:2^14-TxDelay]
243%            For this exercise the vector to transmit is the 'ytx_mod_filt_up'
244%            vector. Set TxLength equal to the length of the 'ytx_mod_filt_up'
245%            vector. You can use Matlab's 'length' function. 
246% CarrierChannel: Channel in the 2.4 GHz band. In [1:14]
247% Node1_Radio2_TxGain_BB: Tx Baseband Gain. In [0:3]
248% Node1_Radio2_TxGain_RF: Tx RF Gain. In [0:63]
249% Node2_Radio2_RxGain_BB: Rx Baseband Gain. In [0:31]
250% Node2_Radio2_RxGain_RF: Rx RF Gain. In [1:3] 
251
252% Note: For this experiment node 1 will be set as the transmitter and node
253% 2 will be set as the receiver (this is done later in the code), hence,
254% there is no need to define receive gains for node 1 and there is no
255% need to define transmitter gains for node 2.
256
257%-------------------------------------------------------------------------%
258
259TxMode = 0; % Transmission mode. In [0:1]
260            % 0: Single Transmission
261            % 1: Continuous Transmission. Tx board will continue
262            % transmitting the vector of samples until the user manually
263            % disables the transmitter.
264
265% Download the WARPLab parameters to the WARP nodes.
266% The nodes store the TxDelay, TxLength, and TxMode parameters in
267% registers defined in the WARPLab sysgen model. The nodes set radio
268% related parameters CarrierChannel, TxGains, and RxGains, using the
269% radio controller functions.
270
271% The TxDelay, TxLength, and TxMode parameters need to be known at the transmitter;
272% the receiver doesn't require knowledge of these parameters (the receiver
273% will always capture 2^14 samples). For this exercise node 1 will be set as
274% the transmitter (this is done later in the code). Since TxDelay, TxLength and
275% TxMode are only required at the transmitter we download the TxDelay, TxLength and
276% TxMode parameters only to the transmitter node (node 1).
277
278warplab_writeRegister(udp_node1,TX_DELAY,TxDelay);
279warplab_writeRegister(udp_node1,TX_LENGTH,TxLength);
280warplab_writeRegister(udp_node1,TX_MODE,TxMode);
281% The CarrierChannel parameter must be downloaded to all nodes 
282warplab_setRadioParameter(udp_node1,CARRIER_CHANNEL,CarrierChannel);
283warplab_setRadioParameter(udp_node2,CARRIER_CHANNEL,CarrierChannel);
284% Node 1 will be set as the transmitter so download Tx gains to node 1.
285warplab_setRadioParameter(udp_node1,RADIO2_TXGAINS,(Node1_Radio2_TxGain_RF + Node1_Radio2_TxGain_BB*2^16));
286% Node 2 will be set as the receiver so download Rx gains to node 2.
287warplab_setRadioParameter(udp_node2,RADIO2_RXGAINS,(Node2_Radio2_RxGain_BB + Node2_Radio2_RxGain_RF*2^16));
288
289%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
290% 5.1. Generate a vector of samples to transmit and send the samples to the
291% WARP board (Sample Frequency is 40MHz)
292%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
293% Prepare some data to be transmitted
294
295% Scale signal to transmit so that it spans [-1,1] range. We do this to
296% use the full range of the DAC at the tranmitter
297scale = 1 / max( [ max(real(ytx_mod_filt_up)) , max(imag(ytx_mod_filt_up)) ] );
298ytx_mod_filt_up = scale*ytx_mod_filt_up;
299
300Node1_Radio2_TxData = ytx_mod_filt_up.'; % Create a signal to transmit. Signal must be a
301% row vector
302
303% Download the samples to be transmitted
304%-------------------------------------------------------------------------%
305% USER CODE HERE
306% Download the 'Node1_Radio2_TxData' vector to WARP node 1 using the
307% 'warplab_writeSMWO' function. The 'Node1_Radio2_TxData' vector is the
308% vector of samples to be transmitted.
309
310% Hints:
311
312% 1. The first argument of the 'warplab_writeSMWO' function identifies the
313% node to which samples will be downloaded to. In this exercise we will set
314% node 1 as the transmitter node, the id or handle to node 1 is 'udp_node1'.
315
316% 2. The second argument of the 'warplab_writeSMWO' function identifies the
317% transmit buffer where the samples will be written. For this exercise we
318% will transmit from radio 2, hence, samples must be downloaded to radio 2
319% Tx buffer, the id for this buffer is 'RADIO2_TXDATA'.
320
321% 3. The third argument of the 'warplab_writeSMWO' function is the
322% vector of samples to download, it must be a row vector. For this
323% exercise the 'Node1_Radio2_TxData' vector is the vector of samples to be
324% transmitted, hence, this is the vector that must be downloaded to radio 2
325% Tx buffer.
326
327% 4. The 'warplab_writeSMWO' function was used in the previous exercise.
328
329%-------------------------------------------------------------------------%
330
331%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
332% 5.2. Prepare WARP boards for transmission and reception and send trigger to
333% start transmission and reception (trigger is the SYNC packet)
334%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
335% The following lines of code set node 1 as transmitter and node 2 as
336% receiver; transmission and capture are triggered by sending the SYNC
337% packet.
338
339%-------------------------------------------------------------------------%
340% USER CODE HERE
341% Enable transmitter radio path in radio 2 in node 1 (enable radio 2 in
342% node 1 as transmitter) by sending the RADIO2_TXEN command to node 1 using
343% the 'warplab_sendCmd' function.
344
345% Hints:
346
347% 1. The first argument of the 'warplab_sendCmd' function identifies the
348% node to which the command will be sent to. The id or handle to node 1 is
349% 'udp_node1'.
350
351% 2. The second argument of the 'warplab_sendCmd' function identifies the
352% command that will be sent.
353
354% 3. The third argument of the 'warplab_sendCmd' command is a field that is
355% not used at the moment, it may be used in future versions of WARPLab to
356% keep track of packets. Use 'packetNum' as the third argument of the
357% 'warplab_sendCmd' command.
358
359% 4. The 'warplab_sendCmd' function was used in the previous exercise.
360
361%-------------------------------------------------------------------------%
362
363%-------------------------------------------------------------------------%
364% USER CODE HERE
365% Enable transmission of node1's radio 2 Tx buffer (enable transmission
366% of samples stored in radio 2 Tx Buffer in node 1) by sending the
367% RADIO2TXBUFF_TXEN command to node 1 using the 'warplab_sendCmd' function.
368
369%-------------------------------------------------------------------------%
370
371%-------------------------------------------------------------------------%
372% USER CODE HERE
373% Enable receiver radio path in radio 2 in node 2 (enable radio 2 in
374% node 2 as receiver) by sending the RADIO2_RXEN command to node 2 using
375% the 'warplab_sendCmd' function.
376% Hint: The id or handle to node 2 is 'udp_node2'.
377
378%-------------------------------------------------------------------------%
379
380%-------------------------------------------------------------------------%
381% USER CODE HERE
382
383% Enable capture in node2's radio 2 Rx Buffer (enable radio 2 rx buffer in
384% node 2 for storage of samples) by sending the RADIO2RXBUFF_RXEN command to
385% node 2 using the 'warplab_sendCmd' function.
386
387%-------------------------------------------------------------------------%
388
389% Prime transmitter state machine in node 1. Node 1 will be
390% waiting for the SYNC packet. Transmission from node 1 will be triggered
391% when node 1 receives the SYNC packet.
392warplab_sendCmd(udp_node1, TX_START, packetNum);
393
394% Prime receiver state machine in node 2. Node 2 will be waiting
395% for the SYNC packet. Capture at node 2 will be triggered when node 2
396% receives the SYNC packet.
397warplab_sendCmd(udp_node2, RX_START, packetNum);
398
399% Send the SYNC packet
400warplab_sendSync(udp_Sync);
401
402%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
403% 5.3. Read the received smaples from the Warp board
404%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
405%-------------------------------------------------------------------------%
406% USER CODE HERE
407
408% Read the received samples from the WARP board using the
409% 'warplab_readSMRO' function.  Store the samples in a variable named
410% 'Node2_Radio2_RawRxData'
411
412% Hints:
413
414% 1. The first argument of the 'warplab_readSMRO' function identifies the
415% node from which samples will be read. In this exercise we set node 2 as
416% the receiver node, the id or handle to node 2 is 'udp_node2'.
417
418% 2. The second argument of the 'warplab_readSMRO' function identifies the
419% receive buffer from which samples will be read. For this exercise samples
420% were captured in node 2 radio 2, hence, samples must be read from radio 2
421% Rx buffer, the id for this buffer is 'RADIO2_RXDATA'.
422
423% 3. The third argument of the 'warplab_readSMRO' function is the number of
424% samples to read; reading of samples always starts from address zero.
425% For this exercise set third argument of the 'warplab_readSMRO'
426% function equal to 'TxLength+CaptOffset+100' (Read extra 100 samples to
427% account for jitter in sync trigger)
428
429% 4. The 'warplab_readSMRO' function was used in the previous exercise.
430
431%-------------------------------------------------------------------------%
432
433% Process the received samples to obtain meaningful data
434[Node2_Radio2_RxData,Node2_Radio2_RxOTR] = warplab_processRawRxData(Node2_Radio2_RawRxData);
435
436%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
437% 5.4. Reset and disable the boards
438%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
439% Set radio 2 Tx buffer in node 1 back to Tx disabled mode
440warplab_sendCmd(udp_node1, RADIO2TXBUFF_TXDIS, packetNum);
441
442% Disable the transmitter radio
443warplab_sendCmd(udp_node1, RADIO2_TXDIS, packetNum);
444
445% Set radio 2 Rx buffer in node 2 back to Rx disabled mode
446warplab_sendCmd(udp_node2, RADIO2RXBUFF_RXDIS, packetNum);
447
448% Disable the receiver radio
449warplab_sendCmd(udp_node2, RADIO2_RXDIS, packetNum);
450%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
451% 5.5. Plot the transmitted and received data
452%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
453figure;
454subplot(2,2,1);
455plot(real(Node1_Radio2_TxData));
456title('Tx Node 1 Radio 2 I');
457xlabel('n (samples)'); ylabel('Amplitude');
458axis([0 2^14 -1 1]); % Set axis ranges.
459subplot(2,2,2);
460plot(imag(Node1_Radio2_TxData));
461title('Tx Node 1 Radio 2 Q');
462xlabel('n (samples)'); ylabel('Amplitude');
463axis([0 2^14 -1 1]); % Set axis ranges.
464subplot(2,2,3);
465plot(real(Node2_Radio2_RxData));
466title('Rx Node 2 Radio 2 I');
467xlabel('n (samples)'); ylabel('Amplitude');
468axis([0 2^14 -1 1]); % Set axis ranges.
469subplot(2,2,4);
470plot(imag(Node2_Radio2_RxData));
471title('Rx Node 2 Radio 2 Q');
472xlabel('n (samples)'); ylabel('Amplitude');
473axis([0 2^14 -1 1]); % Set axis ranges.
474
475%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
476% 6. Downconvert from 5MHz to baseband
477%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
478time = [0:1:length(Node2_Radio2_RxData)-1]/40e6; % Sampling Freq. is 40MHz
479yrx_bb = Node2_Radio2_RxData .* exp(-sqrt(-1)*2*pi*5e6*time);
480
481%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
482% 7. Filter the received signal with a Matched Filter (matched to the pulse
483% shaping filter), detect preamble, and downsample output of Matched Filter
484%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
485% Store received samples as a column vector
486yrx_bb = yrx_bb.';
487
488% Matched filter: Filter received signal using the SRRC filter
489yrx_bb_mf = rcosflt(yrx_bb,1,nsamp,'Fs/filter',rrcfilter);
490
491% Correlate with the reference matrix to find preamble sequence
492correlation = abs( (yrx_bb_mf(1:corr_window).') * reference_matrix );
493preamble_start = find(correlation == max(correlation)); % Start of preamble
494first_sample_index = preamble_start+length_preamble_upsamp; % Start of
495                                         % first symbol after preamble
496
497% Downsample output of Matched Filter
498yrx_bb_mf_ds = yrx_bb_mf(first_sample_index:end);
499yrx_bb_mf_ds = downsample(yrx_bb_mf_ds,nsamp);
500
501% Slice symbols of interest (nsym_payload symbols were transmitted so if
502% yrx_bb_mf_ds has more than nsym_payload elements the extra elements of the
503% yrx_bb_mf_ds vector are due to the extra samples read from the Rx buffer
504% and the extra samples added by the delay of the filters)
505yrx_bb_mf_ds = yrx_bb_mf_ds(1:nsym_payload); 
506
507% Stem Plot of signal before Matched Filter, after Matched Filter, and
508% after downsampling
509% Plots first 30 symbols.
510% Plots real and imaginary parts in different windows
511figure; % Create new figure window.
512subplot(2,1,1)
513stem(real(yrx_bb(first_sample_index-(1+delay*nsamp):first_sample_index-(1+delay*nsamp)+30*nsamp)),'b');
514hold
515stem(real(yrx_bb_mf(first_sample_index:first_sample_index+30*nsamp)),'r');
516stem([1:nsamp:nsamp*30],real(yrx_bb_mf_ds(1:30)),'k');
517title('I Symbols');
518xlabel('n (sample)'); ylabel('Amplitude');
519legend('Before Matched Filter','After Matched Filter','After Downsample');
520subplot(2,1,2)
521stem(imag(yrx_bb(first_sample_index-(1+delay*nsamp):first_sample_index-(1+delay*nsamp)+30*nsamp)),'b');
522hold
523stem(imag(yrx_bb_mf(first_sample_index:first_sample_index+30*nsamp)),'r');
524stem([1:nsamp:nsamp*30],imag(yrx_bb_mf_ds(1:30)),'k');
525title('Q Symbols');
526xlabel('n (sample)'); ylabel('Amplitude');
527
528% Scatter Plot of received and transmitted constellation points
529h = scatterplot(yrx_bb_mf_ds(1:end),1,0,'g.');
530hold on;
531scatterplot(ytx_mod(nsym_preamble+1:end),1,0,'k*',h);
532title('Constellations');
533legend('Received','Transmitted');
534axis([-2 2 -2 2]); % Set axis ranges.
535hold off;
536
537%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
538% 8. Demodulate and recover the transmitted bitstream
539%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
540
541%-------------------------------------------------------------------------%
542% USER CODE HERE
543
544% Demodulate the 'yrx_bb_mf_ds' vector. Remember modulation is DQPSK.
545% You can use Matlab's 'dpskdemod' function. The alphabet or constellation
546% size 'M' was set in step 0 above as 'M=4'. Store the demodulated symbols
547% in a variable named 'zsym'.
548
549%-------------------------------------------------------------------------%
550
551% Map Symbols to Bits
552z = de2bi(zsym,'left-msb'); % Convert integers to bits.
553% Convert z from a matrix to a vector.
554z = reshape(z.',prod(size(z)),1);
555
556% Plot first 80 transmitted bits and first 80 received bits in a stem plot
557figure;
558subplot(2,1,1)
559stem(x(1:80),'filled');
560title('Transmitted Bits');
561xlabel('Bit Index'); ylabel('Binary Value');
562subplot(2,1,2)
563stem(z(1:80),'filled');
564title('Received Bits');
565xlabel('Bit Index'); ylabel('Binary Value');
566
567%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
568% 9. Compute the Bit Error Rate (BER) and close sockets
569%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
570% Compare x and z to obtain the number of errors and the bit error rate
571[number_of_errors,bit_error_rate] = biterr(x(3:length(z)),z(3:length(z)))
572% We start comparing at three because the first two bits are are always
573% lost in DQPSK. We compare until minlen because z may be shorter
574% than x due to the jitter of the synch pulse.
575
576% Close sockets
577pnet('closeall');
578
579%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
580% Code to avoid conflict between users, only needed for the workshop
581%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
582% !del c:\boards_lock.txt
583catch,
584SocketHandleExists = exist('udp_node1');
585if(1==SocketHandleExists)   
586% If statement needed because user code errors may happen before the
587% packets are created
588% Reset nodes
589warplab_reset2x2Node(udp_node1);
590warplab_reset2x2Node(udp_node2);
591end
592% Close sockets
593pnet('closeall');
594% !del c:\boards_lock.txt
595lasterr
596end
Note: See TracBrowser for help on using the repository browser.