MATLAB Answers

How to run program multiple times changing the array index and saving the output.

조회 수: 2(최근 30일)
Manuel Ruano
Manuel Ruano 27 Nov 2020
답변: Raunak Gupta 5 Dec 2020
I'm trying to sweep the SNR value into the function so I can plot how the SNR VS BER. I keep getting errors when I try to use loops and my data gets wonky when it does succeed. The BER value should go up as SNR goes up but it stays constant and doesnt trend correctly.
clear;
% clc;
message_length = 1200; %in bits
M=64; %M-QAM
phase_offset = 0.5*pi/20;
snr = 0:2:45;%signal-to-noise ratio in dB
SignalP=1;
NoiseP=.01;
barker_length = 13; %13 or 5 only
L = 45; % L is noise-only sample length. L=[20,50] -> 100-L =[50,80]
% bits_per_symbol = log2(M);
switch M
case 2
bits_per_symbol = 1;
case 16
bits_per_symbol = 4;
case 64
bits_per_symbol = 6;
otherwise
"******** NOT SUPPORTED QAM SIZE *********"
end
switch barker_length
case 13
preamble = [1 1 1 1 1 -1 -1 1 1 -1 1 -1 1];
mf_threshold = 10;% you may experiment with different threshold values
case 5
preamble = [1 1 1 -1 1];
mf_threshold = 4;% you may experiment with different threshold values
otherwise
"******** NOT SUPPORTED PREAMBLE LENGTH *********"
end
message=round(rand(1,message_length));%rand() provides random number between 0 and 1 with uniform pdf
for k=1:message_length/bits_per_symbol
t_sum = 0;
for m=1:bits_per_symbol
t_sum = t_sum + (2^(bits_per_symbol-m))*message(bits_per_symbol*k - m + 1);%binary to unsigned integer
%e.g. '1 0 1 1' with right-most bit as MSB = 1+0*2+1*4+1+1*8
end
symbol_index(k) = t_sum; % between 0 and M-1
end
% tx_symbol = qammod(symbol_index, M,'UnitAveragePower',true, 'PlotConstellation',true);
tx_symbol = qammod(symbol_index, M,'UnitAveragePower',true);
tx_signal = [preamble tx_symbol];
tx_signal_rot = tx_signal * (cos(phase_offset) + i * sin(phase_offset));
tx_signal_sim = [zeros(1,L) tx_signal_rot zeros(1,100-L)];
rx_signal = awgn(tx_signal_sim,snr(n));% input singal power must be 1.0 (0 dBW), snr in dB
%e.g. snr = 20 (dB)-> signal-to-noise ratio is 10^(20/10)=100, power of
%noise is 0.01
%rx_signal = awgn(tx_signal_rot,snr,'measured'); %signal pwr measured
%rx_signal = awgn(tx_signal_sim,snr,signalpower); %must specify the signal power
[c,lags] = xcorr(preamble,rx_signal);% takes auto correlation of preamble and the received signal
c1 = real(c);%finds the magnitude of the vector.
[pkt,lct] = findpeaks(c1,'Threshold',mf_threshold);%finds the peaks and location of the peaks with the a threshold value.
start_index=lct(end);%finds the location of the of the lag index
c2=c(start_index);% Finds the max value original values for real and imaginary part
theta= angle(c2);%estimates what the phase offset value is from the autocorrlated values.
start_location=(-1*lags(start_index)+1); %gives data start location then adds one to begin at first data value
end_location=length(rx_signal)-((100-(start_location-1)));%finds the end location if the number of zeros is known
rx_signal1=rx_signal(start_location:end_location);%removes the added zeros
rx_signal_not_rot= rx_signal1 * (cos(theta) + i * sin(theta));%attempts to remove the phase shift
rx_signal_no_preamble= rx_signal_not_rot(barker_length+1:end);%removes the barker code from the signal
z = qamdemod(rx_signal_no_preamble,M,'UnitAveragePower',true); %demondulates the received signal before demapping can begin
b_array = de2bi(z,bits_per_symbol,'right-msb');%Takes the mapping index and creates a matrix representation in binary with right-msb
rx_signal_final=[];%Takes the matrix and turns it into an array length of sent message.
for i=1:size(b_array,1)
rx_signal_final=[rx_signal_final b_array(i,:)];
end
[BitErrors,BER] = biterr(rx_signal_final,message);%Number= the number of bits that are different, Ratio=the ratio of received over sent
s = isequal(message,double(rx_signal_final));%%Checks to see if the demodulated message and the sent message are the same.

답변(1개)

Raunak Gupta
Raunak Gupta 5 Dec 2020
Hi Manuel,
You can convert the code which needs to be run for different SNR values into a function which return BER is output. Then you can use for loop for calculating SNR for multiple BER values in a separate script. Below code might help, I have checked with SNR values and its working fine (BER decreasing with Increasing SNR) but after SNR value greater than 22 dB, BER is coming as 0. Maybe you can recheck the logic if something is missing there.
snr = 0:2:45;%signal-to-noise ratio in dB
BER = zeros(size(snr));
for index=1:length(snr)
BER(index) = calculateBER(snr(index));
disp(BER(index));
end
function berValue = calculateBER(snrValue)
message_length = 1200; %in bits
M=64; %M-QAM
phase_offset = 0.5*pi/20;
% bits_per_symbol = log2(M);
SignalP=1;
NoiseP=.01;
barker_length = 13; %13 or 5 only
L = 45; % L is noise-only sample length. L=[20,50] -> 100-L =[50,80]
switch M
case 2
bits_per_symbol = 1;
case 16
bits_per_symbol = 4;
case 64
bits_per_symbol = 6;
otherwise
%"******** NOT SUPPORTED QAM SIZE *********"
end
switch barker_length
case 13
preamble = [1 1 1 1 1 -1 -1 1 1 -1 1 -1 1];
mf_threshold = 10;% you may experiment with different threshold values
case 5
preamble = [1 1 1 -1 1];
mf_threshold = 4;% you may experiment with different threshold values
otherwise
%"******** NOT SUPPORTED PREAMBLE LENGTH *********"
end
message=round(rand(1,message_length));%rand() provides random number between 0 and 1 with uniform pdf
for k=1:message_length/bits_per_symbol
t_sum = 0;
for m=1:bits_per_symbol
t_sum = t_sum + (2^(bits_per_symbol-m))*...
message(bits_per_symbol*k - m + 1);%binary to unsigned integer
%e.g. '1 0 1 1' with right-most bit as MSB = 1+0*2+1*4+1+1*8
end
symbol_index(k) = t_sum; % between 0 and M-1
end
% tx_symbol = qammod(symbol_index, M,'UnitAveragePower',true, 'PlotConstellation',true);
tx_symbol = qammod(symbol_index, M,'UnitAveragePower',true);
tx_signal = [preamble tx_symbol];
tx_signal_rot = tx_signal * (cos(phase_offset) + 1i * sin(phase_offset));
tx_signal_sim = [zeros(1,L) tx_signal_rot zeros(1,100-L)];
rx_signal = awgn(tx_signal_sim,snrValue);% input singal power must be 1.0 (0 dBW), snr in dB
%e.g. snr = 20 (dB)-> signal-to-noise ratio is 10^(20/10)=100, power of
%noise is 0.01
%rx_signal = awgn(tx_signal_rot,snr,'measured'); %signal pwr measured
%rx_signal = awgn(tx_signal_sim,snr,signalpower); %must specify the signal power
[c,lags] = xcorr(preamble,rx_signal);% takes auto correlation of preamble and the received signal
c1 = real(c);%finds the magnitude of the vector.
[pkt,lct] = findpeaks(c1,'Threshold',mf_threshold);%finds the peaks and location of the peaks with the a threshold value.
start_index=lct(end);%finds the location of the of the lag index
c2=c(start_index);% Finds the max value original values for real and imaginary part
theta= angle(c2);%estimates what the phase offset value is from the autocorrlated values.
start_location=(-1*lags(start_index)+1); %gives data start location then adds one to begin at first data value
end_location=length(rx_signal)-((100-(start_location-1)));%finds the end location if the number of zeros is known
rx_signal1=rx_signal(start_location:end_location);%removes the added zeros
rx_signal_not_rot= rx_signal1 * (cos(theta) + 1i * sin(theta));%attempts to remove the phase shift
rx_signal_no_preamble= rx_signal_not_rot(barker_length+1:end);%removes the barker code from the signal
z = qamdemod(rx_signal_no_preamble,M,'UnitAveragePower',true); %demondulates the received signal before demapping can begin
b_array = de2bi(z,bits_per_symbol,'right-msb');%Takes the mapping index and creates a matrix representation in binary with right-msb
rx_signal_final=[];%Takes the matrix and turns it into an array length of sent message.
for i=1:size(b_array,1)
rx_signal_final=[rx_signal_final b_array(i,:)];
end
[BitErrors,berValue] = biterr(rx_signal_final,message);%Number= the number of bits that are different, Ratio=the ratio of received over sent
s = isequal(message,double(rx_signal_final));%%Checks to see if the demodulated message and the sent message are the same.
end

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by