1. EXP NUMBER 3 ISI WITH PAM
  2. clear all;
  3. clc;
  4. N = 10^5; %Number of symbols to transmit
  5. MOD_TYPE = 'PAM'; %modulation type
  6. M = 4; %modulation level for the chosen modulation MOD_TYPE
  7. d = ceil(M.*rand(1,N)); %random numbers from 1 to M for input to PAM
  8. u = modulate(MOD_TYPE,M,d);%MPAM modulation
  9. figure; stem(real(u)); %plot modulated symbols
  10. title('PAM modulated symbols u(k)');
  11. xlim([0 20])
  12. ylim([-5 5])
  13.  
  14. L=4; %Oversampling factor (L samples per symbol period)
  15. v=[u;zeros(L-1,length(u))];%insert L-1 zero between each symbols
  16. %Convert to a single stream
  17. v=v(:).';%now the output is at sampling rate
  18. figure;stem(real(v)); title('Oversampled symbols v(n)');
  19. xlim([0 150])
  20. ylim([-5 5])
  21.  
  22. %----Pulse shaping-----
  23. beta = 0.3;% roll-off factor for Tx SRRC filter
  24. Nsym=8;%SRRC filter span in symbol durations
  25. L=4; %Oversampling factor (L samples per symbol period)
  26. [p,t,filtDelay] = srrcFunction(beta,L,Nsym);%design filter
  27. s=conv(v,p,'full');%Convolve modulated syms with p[n] filter
  28. figure; plot(real(s),'r'); title('Pulse shaped symbols s(n)');
  29. xlim([0 150])
  30. ylim([-5 5])
  31.  
  32. EbN0dB = 1000; %EbN0 in dB for AWGN channel
  33. snr = 10*log10(log2(M))+EbN0dB; %Converting given Eb/N0 dB to SNR
  34. %log2(M) gives the number of bits in each modulated symbol
  35. r = add_awgn_noise(s,snr,L); %AWGN , add noise for given SNR, r=s+w
  36. %L is the oversampling factor used in simulation
  37. figure; plot(real(r),'r');title('Received signal r(n)');
  38. xlim([0 150])
  39. ylim([-5 5])
  40.  
  41.  
  42. vCap=conv(r,p,'full');%convolve received signal with Rx SRRC filter
  43. figure; plot(real(vCap),'r');
  44. title('After matched filtering $\hat{v}$(n)','Interpreter','Latex');
  45. xlim([0 150])
  46. ylim([-20 20])
  47.  
  48. %------Symbol rate Sampler-----
  49. uCap = vCap(2*filtDelay+1:L:end-(2*filtDelay))/L;
  50. %downsample by L from 2*filtdelay+1 position result by normalized L,
  51. %as the matched filter result is scaled by L
  52. figure; stem(real(uCap)); hold on;
  53. title('After symbol rate sampler $\hat{u}$(n)',...
  54. 'Interpreter','Latex');
  55. dCap = demodulate(MOD_TYPE,M,uCap); %demodulation
  56. xlim([0 20])
  57. ylim([-5 5])
  58.  
  59.  
  60. %plot eye at the receiver after matched filtering
  61. figure;
  62. plotEyeDiagram(vCap,L,3*L,2*filtDelay,100);
  63. xlim([0 3])
  64. ylim([-15 15])
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72. EXP NUMBER 5A.DSSS
  73.  
  74.  
  75. clear all;
  76. %% parameters
  77. Fs = 1000;
  78. fc = 100;
  79. fp = 4;
  80. bit_t = 0.1;
  81. %% message generation with BPSK
  82. m = [0 0 1 1 1 1 0 0];
  83. for bit = 1:length(m)
  84. if(m(bit)==0)
  85. m(bit) = -1;
  86. end
  87. end
  88. message = repmat(m,fp,1);
  89. message = reshape(message,1,[]);
  90. %% PN generation and multiply with message
  91. pn_code = randi([0,1],1,length(m)*fp);
  92. for bit = 1:length(pn_code)
  93. if(pn_code(bit)==0)
  94. pn_code(bit) = -1;
  95. end
  96. end
  97. DSSS = message.*pn_code;
  98. %% create carrier and multipy with encoded sequence
  99. t = 0:1/Fs:(bit_t-1/Fs);
  100. s0 = -1*cos(2*pi*fc*t);
  101. s1 = cos(2*pi*fc*t);
  102. carrier = [];
  103. BPSK = [];
  104. for i = 1:length(DSSS)
  105. if (DSSS(i) == 1)
  106. BPSK = [BPSK s1];
  107. elseif (DSSS(i) == -1)
  108. BPSK = [BPSK s0];
  109. end
  110. carrier = [carrier s1];
  111.  
  112. end
  113. %% demodulation
  114. rx =[];
  115. for i = 1:length(pn_code)
  116. if(pn_code(i)==1)
  117. rx = [rx BPSK((((i-1)*length(t))+1):i*length(t))];
  118. else
  119. rx = [rx (-1)*BPSK((((i-1)*length(t))+1):i*length(t))];
  120. end
  121. end
  122. demod = rx.*carrier;
  123. result = [];
  124. for i = 1:length(m)
  125. x = length(t)*fp;
  126. cx = sum(carrier(((i-1)*x)+1:i*x).*demod(((i-1)*x)+1:i*x));
  127. if(cx>0)
  128. result = [result 1];
  129. else
  130. result = [result -1];
  131. end
  132. end
  133. pn_codeWrong = randi([0,1],1,length(m)*fp);
  134. resultWrong = [];
  135. rx2 =[];
  136. for i = 1:length(pn_code)
  137. if(pn_codeWrong(i)==1)
  138. rx2 = [rx2 BPSK((((i-1)*length(t))+1):i*length(t))];
  139. else
  140. rx2 = [rx2 (-1)*BPSK((((i-1)*length(t))+1):i*length(t))];
  141. end
  142. end
  143. demod2 = rx2.*carrier;
  144. for i = 1:length(m)
  145. x = length(t)*fp;
  146. cx = sum(carrier(((i-1)*x)+1:i*x).*demod2(((i-1)*x)+1:i*x));
  147. if(cx>0)
  148. resultWrong = [resultWrong 1];
  149. else
  150. resultWrong = [resultWrong -1];
  151.  
  152. end
  153. end
  154. message1 = repmat(result,fp,1);
  155. message1 = reshape(message1,1,[]);
  156. message2 = repmat(resultWrong,fp,1);
  157. message2 = reshape(message2,1,[]);
  158. %% Draw original message, PN code , encoded sequence on time domain
  159. pn_size = length(pn_code);
  160. tpn = linspace(0,length(m)*bit_t-bit_t/fp,pn_size);
  161. tm = 0:bit_t/fp:length(m)*bit_t-bit_t/fp;
  162. figure
  163. subplot(311)
  164. stairs(tm,message,'linewidth',2)
  165. title('Message bit sequence')
  166. axis([0 length(m)*bit_t -1 1]);
  167. subplot(312)
  168. stairs(tpn,pn_code,'linewidth',2)
  169. title('Pseudo-random code');
  170. axis([0 length(m)*bit_t -1 1]);
  171. subplot(313)
  172. stairs(tpn,DSSS,'linewidth',2)
  173. title('Modulated signal');
  174. axis([0 length(m)*bit_t -1 1]);
  175. figure
  176. subplot(311)
  177. stairs(tm,message,'linewidth',2)
  178. title('Message bit sequence')
  179. axis([0 length(m)*bit_t -1 1]);
  180. subplot(312)
  181. stairs(tm,message1,'linewidth',2)
  182. title('Received message using true pseudo-random code')
  183. axis([0 length(m)*bit_t -1 1]);
  184. subplot(313)
  185. stairs(tm,message2,'linewidth',2)
  186. title('Received message using wrong pseudo-random code')
  187. axis([0 length(m)*bit_t -1 1]);
  188. %% Draw original message, PN code , encoded sequence on frequency domain
  189. f = linspace(-Fs/2,Fs/2,1024);
  190. figure
  191. subplot(311)
  192. plot(f,abs(fftshift(fft(message,1024))),'linewidth',2);
  193.  
  194. title('Message spectrum')
  195. subplot(312)
  196. plot(f,abs(fftshift(fft(pn_code,1024))),'linewidth',2);
  197. title('Pseudo-random code spectrum');
  198. subplot(313)
  199. plot(f,abs(fftshift(fft(DSSS,1024))),'linewidth',2);
  200. title('Modulated signal spectrum');
  201. figure;
  202. subplot(311)
  203. plot(f,abs(fftshift(fft(BPSK,1024))),'linewidth',2);
  204. title('Transmitted signal spectrum');
  205. subplot(312)
  206. plot(f,abs(fftshift(fft(rx,1024))),'linewidth',2);
  207. title('Received signal multiplied by pseudo code');
  208. subplot(313)
  209. plot(f,abs(fftshift(fft(demod,1024))),'linewidth',2);
  210. title('Demodulated signal spectrum before decision device ');
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218. EXP NUMBER 5B FHSS
  219. FHSS
  220.  
  221. clc; clear all;% Parameters
  222. num_bits = 20; % Number of bits
  223. samples_per_bit = 120; % Samples per bit
  224. num_carriers = 6; % Number of carrier frequencies
  225. samples = [10, 20, 30, 40, 60, 120]; % Samples for each carrier frequency
  226.  
  227. % Manual Entry of Bit Sequence
  228. disp('Enter your bit sequence as a series of 1s and 0s separated by spaces (e.g., "1 0 1 1 0"):');
  229. manual_input = input('', 's'); % Take input as a string
  230. bit_sequence = str2num(manual_input); % Convert to numeric array
  231.  
  232. if length(bit_sequence) ~= num_bits
  233. error('The number of bits entered must match the defined number of bits (%d).', num_bits);
  234. end
  235. % Convert 0 -> -1, 1 -> +1 for BPSK
  236. sequence = 2 * bit_sequence - 1;
  237. % Repeat bits for the bit duration
  238. input_signal = repelem(sequence, samples_per_bit); % Repeat for bit duration
  239.  
  240. % Generate Carrier Signal with Exact Length
  241. t_carrier = linspace(0, 2*pi*num_bits, samples_per_bit*num_bits); % Time vector
  242. carrier_signal = cos(t_carrier); % Continuous cosine carrier wave
  243.  
  244. % Plot Original Bit Sequence
  245. figure(1);
  246. subplot(4,1,1); plot(input_signal); axis([-100 2400 -1.5 1.5]);
  247. title('\bf\it Original Bit Sequence');
  248.  
  249. % BPSK Modulation
  250. bpsk_mod_signal = input_signal .* carrier_signal;
  251. subplot(4,1,2); plot(bpsk_mod_signal); axis([-100 2400 -1.5 1.5]);
  252. title('\bf\it BPSK Modulated Signal');
  253.  
  254. % Generate 6 Carrier Frequencies
  255. carriers = cell(1, num_carriers);
  256. for i = 1:num_carriers
  257. t = linspace(0, 2*pi, samples(i) + 1); t(end) = []; % Time for each carrier
  258. carriers{i} = repmat(cos(t), 1, ceil(samples_per_bit / length(t)));
  259. carriers{i} = carriers{i}(1:samples_per_bit); % Trim to exact length
  260. end
  261.  
  262. % Spread Signal with Random Carrier Frequencies
  263. spread_signal = [];
  264. for i = 1:num_bits
  265. carrier_idx = randi([1, num_carriers]); % Randomly select a carrier
  266. spread_signal = [spread_signal carriers{carrier_idx}];
  267. end
  268. subplot(4,1,3); plot(spread_signal); axis([-100 2400 -1.5 1.5]);
  269. title('\bf\it Spread Signal with 6 frequencies');
  270.  
  271. % Spreading BPSK Signal
  272. freq_hopped_sig = bpsk_mod_signal .* spread_signal;
  273. subplot(4,1,4); plot(freq_hopped_sig); axis([-100 2400 -1.5 1.5]);
  274. title('\bf\it Frequency Hopped Spread Spectrum Signal');
  275.  
  276. % Demodulation
  277. bpsk_demodulated = freq_hopped_sig ./ spread_signal;
  278. figure(2);
  279. subplot(2,1,1); plot(bpsk_demodulated); axis([-100 2400 -1.5 1.5]);
  280. title('\bf Demodulated BPSK Signal from Wide Spread');
  281.  
  282. % Recover Original Bit Sequence
  283. original_BPSK_signal = bpsk_demodulated ./ carrier_signal;
  284. subplot(2,1,2); plot(original_BPSK_signal); axis([-100 2400 -1.5 1.5]);
  285. title('\bf Transmitted Original Bit Sequence');
  286.  
  287.  
  288.  
  289. E6L = 4; % Oversampling factor
  290. rollOff = 0.5; % Pulse shaping roll-off factor
  291. rcDelay = 10;
  292. % Filter:
  293. htx = rcosdesign(rollOff, 6, 4);
  294. % Note half of the target delay is used, because when combined
  295. % to the matched filter, the total delay will be achieved.
  296. hrx = conj(fliplr(htx));
  297. p = conv(htx,hrx);
  298. M = 2; % PAM Order
  299. % Arbitrary binary sequence alternating between 0 and 1
  300. data = zeros(1, 2*rcDelay);
  301. data(1:2:end) = 1;
  302. % PAM-modulated symbols:
  303. txSym = real(pammod(data, M));
  304. % Upsampling
  305. txUpSequence = upsample(txSym, L);
  306. % Pulse Shaping
  307. txSequence = filter(htx, 1, txUpSequence);
  308. %Delay in channel random channel propagation delay in units of sampling intervals (not symbol intervals)
  309. timeOffset = 1; % Delay (in samples) added
  310. % Delayed sequence
  311. rxDelayed = [zeros(1, timeOffset), txSequence(1:end-timeOffset)];
  312. % Received sequence with Delayed
  313. mfOutput = filter(hrx, 1, rxDelayed); % Matched filter output
  314. rxSym = downsample(mfOutput, L);
  315. % Generate a vector that shows the selected samples
  316. selectedSamples = upsample(rxSym, L);
  317. selectedSamples(selectedSamples == 0) = NaN;
  318. % scatter plot
  319. figure
  320. plot(complex(rxSym(rcDelay+1:end)), 'o')
  321. grid on
  322. xlim([-1.5 1.5])
  323. title('Rx Scatterplot')
  324. xlabel('In-phase (I)')
  325. ylabel('Quadrature (Q)')
  326. figure
  327. stem(rxSym)
  328. title('Symbol Sequence with delay')
  329. xlabel('Symbol Index')
  330. ylabel('Amplitude')
  331. %Symbol timing recovery
  332. rxSym = downsample(mfOutput, L, timeOffset);
  333. selectedSamples = upsample(rxSym, L);
  334. selectedSamples(selectedSamples == 0) = NaN;
  335. figure
  336. plot(complex(rxSym(rcDelay+1:end)), 'o')
  337. grid on
  338. xlim([-1.5 1.5])
  339. title('Rx Scatterplot')
  340. xlabel('In-phase (I)')
  341. ylabel('Quadrature (Q)')
  342. figure
  343. stem(rxSym)
  344. title('Symbol Sequence without delay')
  345. xlabel('Symbol Index')
  346. ylabel('Amplitude')
  347.  
  348.  
  349.  
  350.  
  351. Exp 6
  352. E6L = 4; % Oversampling factor
  353. rollOff = 0.5; % Pulse shaping roll-off factor
  354. rcDelay = 10;
  355. % Filter:
  356. htx = rcosdesign(rollOff, 6, 4);
  357. % Note half of the target delay is used, because when combined
  358. % to the matched filter, the total delay will be achieved.
  359. hrx = conj(fliplr(htx));
  360. p = conv(htx,hrx);
  361. M = 2; % PAM Order
  362. % Arbitrary binary sequence alternating between 0 and 1
  363. data = zeros(1, 2*rcDelay);
  364. data(1:2:end) = 1;
  365. % PAM-modulated symbols:
  366. txSym = real(pammod(data, M));
  367. % Upsampling
  368. txUpSequence = upsample(txSym, L);
  369. % Pulse Shaping
  370. txSequence = filter(htx, 1, txUpSequence);
  371. %Delay in channel random channel propagation delay in units of sampling intervals (not symbol intervals)
  372. timeOffset = 1; % Delay (in samples) added
  373. % Delayed sequence
  374. rxDelayed = [zeros(1, timeOffset), txSequence(1:end-timeOffset)];
  375. % Received sequence with Delayed
  376. mfOutput = filter(hrx, 1, rxDelayed); % Matched filter output
  377. rxSym = downsample(mfOutput, L);
  378. % Generate a vector that shows the selected samples
  379. selectedSamples = upsample(rxSym, L);
  380. selectedSamples(selectedSamples == 0) = NaN;
  381. % scatter plot
  382. figure
  383. plot(complex(rxSym(rcDelay+1:end)), 'o')
  384. grid on
  385. xlim([-1.5 1.5])
  386. title('Rx Scatterplot')
  387. xlabel('In-phase (I)')
  388. ylabel('Quadrature (Q)')
  389. figure
  390. stem(rxSym)
  391. title('Symbol Sequence with delay')
  392. xlabel('Symbol Index')
  393. ylabel('Amplitude')
  394. %Symbol timing recovery
  395. rxSym = downsample(mfOutput, L, timeOffset);
  396. selectedSamples = upsample(rxSym, L);
  397. selectedSamples(selectedSamples == 0) = NaN;
  398. figure
  399. plot(complex(rxSym(rcDelay+1:end)), 'o')
  400. grid on
  401. xlim([-1.5 1.5])
  402. title('Rx Scatterplot')
  403. xlabel('In-phase (I)')
  404. ylabel('Quadrature (Q)')
  405. figure
  406. stem(rxSym)
  407. title('Symbol Sequence without delay')
  408. xlabel('Symbol Index')
  409. ylabel('Amplitude')
  410.  
  411.  
  412.  
  413.  
  414. EXP NUMBER 7A FSEL
  415. clc;clear all;close all;
  416. fs = 1e6; % Sample rate (1 MHz)
  417. numSamples = 10000; % Number of samples
  418. numPaths = 5; % Number of multipath components
  419. maxDelay = 3e-6; % Maximum delay spread (3 microseconds)
  420. dopplerShift = 100; % Maximum Doppler shift (100 Hz)
  421. % Generate an impulse signal (delta function)
  422. impulseSignal = [1; zeros(numSamples-1, 1)]; % An impulse signal
  423. % Create a frequency-selective Rayleigh fading channel
  424. rayleighChan = comm.RayleighChannel( ...
  425. 'SampleRate', fs, ...
  426. 'PathDelays', linspace(0, maxDelay, numPaths), ... % Multipath delays
  427. 'AveragePathGains', [-2 -3 -6 -8 -10], ... % Path gains (dB)
  428. 'MaximumDopplerShift', dopplerShift, ... % Doppler shift
  429. 'NormalizePathGains', true);
  430. % Pass the impulse signal through the frequency-selective fading channel
  431. rxImpulseSignal = rayleighChan(impulseSignal);
  432. % Plot the impulse response
  433. timeAxis = (0:numSamples-1)/fs; % Time axis for plotting
  434. figure;
  435. stem(timeAxis(1:100), 20*log10(abs(rxImpulseSignal(1:100)))); % Plot first 100 samples in dB
  436. title('Impulse Response of Frequency-Selective Rayleigh Fading Channel');
  437. xlabel('Time (s)');ylabel('Gain (dB)');grid on;
  438. % Frequency Response
  439. NFFT = 1024; % FFT size for frequency response
  440. freqResponse = fft(rxImpulseSignal, NFFT); % FFT of the received impulse signal
  441. freqAxis = linspace(-fs/2, fs/2, NFFT); % Frequency axis
  442. % Plot the frequency response
  443. figure;
  444. plot(freqAxis/1e6, 20*log10(abs(fftshift(freqResponse)))); % Shift zero frequency to center
  445. title('Frequency Response of Frequency-Selective Rayleigh Fading Channel');
  446. xlabel('Frequency (MHz)');ylabel('Magnitude (dB)');grid on;
  447.  
  448.  
  449. EXP NUMBER 7B FNSEL
  450. clc;clear all;close all
  451. fs = 1e6; % Sample rate (1 MHz)
  452. numSamples = 10000; % Number of samples
  453. maxDopplerShift = 100; % Maximum Doppler shift (100 Hz)
  454.  
  455.  
  456. % Generate random data signal (complex baseband)
  457. txSignal = (randn(numSamples, 1) + 1j*randn(numSamples, 1)); % Complex Gaussian signal
  458. % Create flat Rayleigh fading channel
  459. rayleighChan = comm.RayleighChannel( ...
  460. 'SampleRate', fs, ...
  461. 'MaximumDopplerShift', maxDopplerShift, ... % Doppler shift
  462. 'NormalizePathGains', true); % Normalize path gains
  463. % Pass the signal through the flat Rayleigh fading channel
  464. rxSignal = rayleighChan(txSignal);
  465. % Plot the transmitted and received signals (first 100 samples)
  466. figure;subplot(2, 1, 1);
  467. plot(real(txSignal(1:100)), 'b-o');hold on;
  468. plot(imag(txSignal(1:100)), 'r-x');
  469. title('Transmitted Signal (First 100 Samples)');
  470. xlabel('Sample Index');ylabel('Amplitude');
  471. legend('Real Part', 'Imaginary Part');grid on;
  472. subplot(2, 1, 2);
  473. plot(real(rxSignal(1:100)), 'b-o');hold on;
  474. plot(imag(rxSignal(1:100)), 'r-x');
  475. title('Received Signal through Flat Rayleigh Fading Channel (First 100 Samples)');
  476. xlabel('Sample Index');ylabel('Amplitude');
  477. legend('Real Part', 'Imaginary Part');grid on;
  478. % Compute and plot the power spectral density (PSD) of the transmitted and received signals
  479. figure;
  480. pwelch(txSignal, [], [], [], fs, 'centered');hold on;
  481. pwelch(rxSignal, [], [], [], fs, 'centered');
  482. title('Power Spectral Density (PSD) of Transmitted and Received Signals');
  483. xlabel('Frequency (Hz)');ylabel('Power/Frequency (dB/Hz)');
  484. legend('Transmitted Signal', 'Received Signal');grid on;
  485.  
  486.  
  487.  
  488.  
  489.  
  490.  
  491.  
  492. EXP NUMBER 6 SYMBOL TIMING ESTIMATION
  493. L = 4; % Oversampling factor
  494. rollOff = 0.5; % Pulse shaping roll-off factor
  495. rcDelay = 10;
  496. % Filter:
  497. htx = rcosdesign(rollOff, 6, 4);
  498. % Note half of the target delay is used, because when combined
  499. % to the matched filter, the total delay will be achieved.
  500. hrx = conj(fliplr(htx));
  501. p = conv(htx,hrx);
  502. M = 2; % PAM Order
  503.  
  504. % Arbitrary binary sequence alternating between 0 and 1
  505. data = zeros(1, 2*rcDelay);
  506. data(1:2:end) = 1;
  507.  
  508. % PAM-modulated symbols:
  509. txSym = real(pammod(data, M));
  510.  
  511. % Upsampling
  512. txUpSequence = upsample(txSym, L);
  513.  
  514. % Pulse Shaping
  515. txSequence = filter(htx, 1, txUpSequence);
  516.  
  517. %Delay in channel random channel propagation delay in units of sampling intervals (not symbol intervals)
  518. timeOffset = 1; % Delay (in samples) added
  519. % Delayed sequence
  520. rxDelayed = [zeros(1, timeOffset), txSequence(1:end-timeOffset)];
  521.  
  522. % Received sequence with Delayed
  523. mfOutput = filter(hrx, 1, rxDelayed); % Matched filter output
  524.  
  525. rxSym = downsample(mfOutput, L);
  526. % Generate a vector that shows the selected samples
  527. selectedSamples = upsample(rxSym, L);
  528. selectedSamples(selectedSamples == 0) = NaN;
  529.  
  530. % scatter plot
  531. figure
  532. plot(complex(rxSym(rcDelay+1:end)), 'o')
  533. grid on
  534. xlim([-1.5 1.5])
  535. title('Rx Scatterplot')
  536. xlabel('In-phase (I)')
  537. ylabel('Quadrature (Q)')
  538.  
  539. figure
  540. stem(rxSym)
  541. title('Symbol Sequence with delay')
  542. xlabel('Symbol Index')
  543. ylabel('Amplitude')
  544.  
  545. %Symbol timing recovery
  546. rxSym = downsample(mfOutput, L, timeOffset);
  547.  
  548. selectedSamples = upsample(rxSym, L);
  549. selectedSamples(selectedSamples == 0) = NaN;
  550.  
  551. figure
  552. plot(complex(rxSym(rcDelay+1:end)), 'o')
  553. grid on
  554. xlim([-1.5 1.5])
  555. title('Rx Scatterplot')
  556. xlabel('In-phase (I)')
  557. ylabel('Quadrature (Q)')
  558.  
  559. figure
  560. stem(rxSym)
  561. title('Symbol Sequence without delay')
  562. xlabel('Symbol Index')
  563. ylabel('Amplitude')
  564.  
  565.  
  566.  
  567.  
  568.  
  569.  
  570. EXP NUMBER 8 CARRIER PAHSE NDDL DDL
  571. % MATLAB Code for Carrier Phase Estimation
  572. % Parameters
  573. clear all; clc;
  574. N = 1000; % Number of symbols
  575. SNR_dB = 10; % Signal-to-Noise Ratio in dB
  576. M = 4; % QPSK modulation order
  577. loop_bandwidth = 0.01; % PLL loop bandwidth
  578. true_phase = pi / 3; % True phase of the carrier
  579.  
  580. % Generate QPSK symbols
  581. tx_symbols = exp(1j * (2 * pi * (0:M-1) / M)); % QPSK constellation points
  582. tx_data = randi([0 M-1], N, 1); % Random data
  583. tx_signal = tx_symbols(tx_data + 1); % Modulated signal
  584.  
  585. % Add noise to the transmitted signal
  586. noise = (1/sqrt(2*10^(SNR_dB/10))) * (randn(N, 1) + 1j * randn(N, 1));
  587. rx_signal = tx_signal .* exp(1j * true_phase) + noise; % Received signal
  588.  
  589. % 1. Maximum Likelihood Carrier Phase Estimation
  590. estimated_phase_ml = angle(sum(conj(tx_signal) .* rx_signal)); % ML estimation
  591. %fprintf('True Phase: %.2f rad, Estimated Phase (ML): %.2f rad\n', true_phase, estimated_phase_ml);
  592.  
  593. % 2. Phase-Locked Loop (PLL) Implementation
  594. phase_error_pll = zeros(N, 1); % Phase error for PLL
  595. estimated_phase_pll = zeros(N, 1); % Estimated phase for PLL
  596. current_phase_estimate_pll = 0; % Initial phase estimate for PLL
  597.  
  598. for n = 1:N
  599. % Phase detection
  600. phase_error_pll(n) = angle(rx_signal(n) * exp(-1j * current_phase_estimate_pll));
  601. current_phase_estimate_pll = current_phase_estimate_pll + loop_bandwidth * phase_error_pll(n);
  602. estimated_phase_pll(n) = current_phase_estimate_pll;
  603. end
  604.  
  605. % 3. Apply Phase Correction to Received Signal
  606. corrected_rx_signal = rx_signal .* exp(-1j * estimated_phase_pll); % Corrected received signal
  607.  
  608. % Plot Original and Corrected Constellation Diagrams
  609. figure;
  610. subplot(2, 1, 1);
  611. scatter(real(rx_signal), imag(rx_signal), 'filled');
  612. title('Received Signal Constellation Diagram');
  613. xlabel('In-Phase');
  614. ylabel('Quadrature');
  615. axis equal;
  616. grid on;
  617.  
  618. subplot(2, 1, 2);
  619. scatter(real(corrected_rx_signal), imag(corrected_rx_signal), 'filled');
  620. title('Corrected Signal Constellation Diagram');
  621. xlabel('In-Phase');
  622. ylabel('Quadrature');
  623. axis equal;
  624. grid on;
  625.  
  626. % 4. Effect of Additive Noise on Phase Estimate
  627. SNR_dB_range = 0:2:20; % SNR range for variance calculation
  628. phase_error_variance = zeros(length(SNR_dB_range), 1);
  629.  
  630. for idx = 1:length(SNR_dB_range)
  631. SNR_dB = SNR_dB_range(idx);
  632. noise_variance = 1/(2*10^(SNR_dB/10));
  633. noise = sqrt(noise_variance) * (randn(N, 1) + 1j * randn(N, 1));
  634. % Received signal with noise
  635. rx_signal = exp(1j * true_phase) + noise; % Use a single reference for variance calculation
  636. % ML phase estimation
  637. estimated_phase = angle(sum(rx_signal));
  638. % Phase error variance
  639. phase_error_variance(idx) = var(angle(rx_signal) - true_phase);
  640. end
  641.  
  642. % Plot the phase error variance as a function of SNR
  643. figure;
  644. plot(SNR_dB_range, phase_error_variance);
  645. xlabel('SNR (dB)');
  646. ylabel('Phase Error Variance');
  647. title('Effect of Noise on Phase Estimation');
  648.  
  649. % 5. Decision-Directed and Non-Decision-Directed Loops
  650. phase_error_dd = zeros(N, 1); % Decision-directed phase error
  651. phase_error_ndd = zeros(N, 1); % Non-decision-directed phase error
  652. estimated_phase_dd = zeros(N, 1);
  653. estimated_phase_ndd = zeros(N, 1);
  654.  
  655. % Initialization
  656. current_phase_estimate_dd = 0;
  657. current_phase_estimate_ndd = 0;
  658.  
  659. for n = 1:N
  660. % Simulate received signal with phase offset and noise
  661. noise = (1/sqrt(2*10^(SNR_dB))) * (randn + 1j * randn);
  662. rx_signal = tx_signal(n) * exp(1j * true_phase) + noise;
  663.  
  664. % Decision-Directed (DD) Loop
  665. detected_symbol = exp(1j * round(angle(rx_signal) * M / (2 * pi)) * 2 * pi / M); % Symbol detection
  666. phase_error_dd(n) = angle(detected_symbol * exp(-1j * current_phase_estimate_dd));
  667. current_phase_estimate_dd = current_phase_estimate_dd + loop_bandwidth * phase_error_dd(n);
  668. estimated_phase_dd(n) = current_phase_estimate_dd;
  669.  
  670. % Non-Decision-Directed (NDD) Loop
  671. phase_error_ndd(n) = angle(rx_signal * exp(-1j * current_phase_estimate_ndd));
  672. current_phase_estimate_ndd = current_phase_estimate_ndd + loop_bandwidth * phase_error_ndd(n);
  673. estimated_phase_ndd(n) = current_phase_estimate_ndd;
  674. end
  675.  
  676. % Plot the results for DD and NDD loops
  677. figure;
  678. subplot(2, 1, 1);
  679. plot(1:N, estimated_phase_dd);
  680. title('Decision-Directed Phase Estimate');
  681. xlabel('Samples');
  682. ylabel('Estimated Phase (radians)');
  683.  
  684. subplot(2, 1, 2);
  685. plot(1:N, estimated_phase_ndd);
  686. title('Non-Decision-Directed Phase Estimate');
  687. xlabel('Samples');
  688. ylabel('Estimated Phase (radians)');