Файл: Приемопередатчик сигналов с многочастотной квадратурной амплитудной манипуляцией.pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 09.11.2023
Просмотров: 130
Скачиваний: 3
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
105 24. Интернет-ресурс для расчета потребляемой мощности ПЛИС Xilinx
WebPowerTools: www.xilinx.com/products/design_resources/power_central/index.htm
25. Виханский О.С. Наумов А.И. - Менеджмент - М.: Гардарики, 2003.
26. Гладышевский А.И. “Формирование производственного потенциала: анализ и прогнозирование”. - М.: Наука, 1992 27. Грузинов В.П. “Экономика предприятия и предпринимательства”. - М.:
СОФИТ, 1997 28. Ковалев В.В. “Финансовый анализ”. - М.: Наука, 1997.
39. “Экономика предприятия”: Учебник / под ред. Швандара В.А. - М.:
Банки и биржи. ЮНИТИ, 1998.
30. Курс экономики: Учебник / Под ред. Б.А. Райзберга. - ИНФРА-М, 1997.
- 720 с.
31. Schulze, Henrik and Christian Luders. Theory and Applications of OFDM and
CDMA John Wiley & Sons, Ltd. 2005 32. Theory of Frequency Division Multiplexing: http://zone.ni.com/devzone/cda/ph/p/id/269 33. Acosta, Guillermo. “OFDM Simulation Using MATLAB” 2000 34. A Brief History of OFDM http://www.wimax.com/commentary/wimax_weekly/sidebar-1-1-a-brief-history- of-ofdm
35. Lui, Hui and Li, Guoqing. OFDM-Based Broadband Wireless Networks
Design and
Optimization Wiley-Interscience 2005 36. Litwin, Louis and Pugel, Michael. “The Principles of OFDM” 2001 37. Heiskala, Juha and Terry, John. OFDM Wireless LANs: A Theoretical and
Practical Guide
SAMS 2001
106 38. Lawrey, Eric “Adaptive Techniques for Multiuser OFDM” Ph.D. Thesis,
James Cook
University 2001 39. BBC Research Department, Engineering Division, “An Introduction to
Digital Modulation and OFDM Techniques” 1993 40. Tran, L.C. and Mertins, A. “Quasi-Orthogonal Space-Time-Frequency
Codes in MB-
OFDM UWB” 2007 41. Understanding an OFDM transmission: http://www.dsplog.com/2008/02/03/understanding-an-ofdm-transmission/
42. Minimum frequency spacing for having orthogonal sinusoidals http://www.dsplog.com/2007/12/31/minimum-frequency-spacing-for-having- orthogonal-sinusoidals/
107
ПРИЛОЖЕНИЕ А
СХЕМА ЭЛЕКТРИЧЕСКАЯ СТРУКТУРНАЯ
108
109
ПРИЛОЖЕНИЕ В
СХЕМА ЭЛЕКТРИЧЕСКАЯ ФУНКЦИОНАЛЬНАЯ
110
111
112
ПРИЛОЖЕНИЕ С
СХЕМА ЭЛЕМТРИЧЕСКАЯ ПРИНЦИПИАЛЬНАЯ
113
114
115
ПРИЛОЖЕНИЕ D
ПЕРЕЧЕНЬ ЭЛЕМЕНТОВ
116
Лит.
Лист
Дата
Подп.
Изм Лист докум.
Разраб.
Н.контр.
Утв.
Провер.
1 2 3 4 5 6 7
1
П
од
п.
и
д
ат
а
И
нв
.
д
уб
л
.
В
за
м
.и
нв
.
П
од
п.
и
д
ат
а
42
5
В
ер
но
(
)
Н
.к
он
т
р
.
И
нв
.
по
дл
.
ф.2.106-5
Копировал
Формат А4
П
ер
в.
п
ри
м
ен
.
С
пр
ав
.
(
)
Листов
Примечание
Кол.
Наименование
Поз. обо-
значение
З
о
н
а
Приемопередатчик OFDM
Перечень элементов
ПГУ 1.11.05.01.10EР114
2
1 150 пФ-50В-NPO-1206+/-5%
1 1
2 2
2
С1, C2
С5
С6, С7
С8, С9
С10
С11
С12, С13
С14, С15 2
2
Кравченко
X1
Розетка 34000000-04 1
X2
Розетка СНЦ23-4/18В-1В ГЕ0.364.241ТУ
1
B1
Резонатор кварцевый MC-306 128МГц
В3 1
1
TR2
С21, С22 150 пкФ-50В-NPO-1206+/-5%
2 4
С23... С26 0,1 мкФ-50В-NPO-1206+/-5%
С16...С20 0,1 мкФ-50В-NPO-1206+/-5%
5
Конденсаторы
B2
Резонатор кварцевый HC-49U 4664МГц
Резонатор кварцевый MC-306 128МГц
1 1
1
TR1
Трансформатор четвертьволновый
Трансформатор питания ТП124-5
РК-50-9
C3, С4 0,1 мкФ-50В-NPO-1206+/-5%
2 12 пкФ-50В-NPO-1206+/-5%
0,1 мкФ-50В-NPO-1206+/-5%
10 мкФ-16В-В +/-10% (танталовый)
0,1 мкФ-50В-NPO-1206+/-5%
100 мкФ-16В-Е+/-10% (танталовый)
0,1 мкФ-50В-NPO-1206+/-5%
10 мкФ-16В-В +/-10% (танталовый)
С27... С30 12 пкФ-50В-NPO-1206+/-5%
4
С31, С32 0,1 мкФ-50В-NPO-1206+/-5%
2
117
118
119
ПРИЛОЖЕНИЕ Е
ЛИСТИНГ ПРОГРАММЫ MATLAB
ДЛЯ ПЕРЕДАЧИ И ПРИЕМА ИНФОРМАЦИИ
120
% *************** MAIN PROGRAM FILE *************** %
% This is the OFDM simulation program's main file.
% It requires a 256-grayscale bitmap file (*.bmp image file) as data source
% and the following 5 script and function m-files to work:
% ofdm_parameters.m, ofdm_base_convert.m, ofdm_modulate.m,
% ofdm_frame_detect.m, ofdm_demod.m
% ####################################################### %
% ************* OFDM SYSTEM INITIALIZATION: ************* %
% **** setting up parameters & obtaining source data **** %
% ####################################################### %
% Turn off exact-match warning to allow case-insensitive input files warning('off','MATLAB:dispatcher:InexactMatch');
clear all; % clear all previous data in MATLAB workspace close all; % close all previously opened figures and graphs fprintf('\n\n##########################################\n')
fprintf('#*********** OFDM Simulation ************#\n')
fprintf('##########################################\n\n')
% invoking ofdm_parameters.m script to set OFDM system parameters ofdm_parameters;
% save parameters for receiver save('ofdm_parameters');
% read data from input file x = imread(file_in);
% arrange data read from image for OFDM processing h = size(x,1);
w = size(x,2);
x = reshape(x,1,w*h);
baseband_tx = double(x);
% convert original data word size (bits/word) to symbol size (bits/symbol)
% symbol size (bits/symbol) is determined by choice of modulation method baseband_tx = ofdm_base_convert(baseband_tx, word_size, symb_size);
% save original baseband data for error calculation later save('err_calc.mat', 'baseband_tx');
121
% ####################################################### %
% ******************* OFDM TRANSMITTER ****************** %
% ####################################################### %
tic; % start stopwatch
% generate header and trailer (an exact copy of the header)
f = 0.25;
header = sin(0:f*2*pi:f*2*pi*(head_len-1));
f=f/(pi*2/3);
header = header+sin(0:f*2*pi:f*2*pi*(head_len-1));
% arrange data into frames and transmit frame_guard = zeros(1, symb_period);
time_wave_tx = [];
symb_per_carrier = ceil(length(baseband_tx)/carrier_count);
fig = 1;
if (symb_per_carrier > symb_per_frame) % === multiple frames === %
power = 0;
while isempty(baseband_tx)
% number of symbols per frame frame_len = min(symb_per_frame*carrier_count,length(baseband_tx));
frame_data = baseband_tx(1:frame_len);
% update the yet-to-modulate data baseband_tx = baseband_tx((frame_len+1):(length(baseband_tx)));
% OFDM modulation time_signal_tx = ofdm_modulate(frame_data,ifft_size,carriers,...
conj_carriers, carrier_count, symb_size, guard_time, fig);
fig = 0; %indicate that ofdm_modulate() has already generated plots
% add a frame guard to each frame of modulated signal time_wave_tx = [time_wave_tx frame_guard time_signal_tx];
frame_power = var(time_signal_tx);
end
% scale the header to match signal level power = power + frame_power;
% The OFDM modulated signal for transmission time_wave_tx = [power*header time_wave_tx frame_guard power*header];
else % === single frame === %
% OFDM modulation time_signal_tx = ofdm_modulate(baseband_tx,ifft_size,carriers,...
conj_carriers, carrier_count, symb_size, guard_time, fig);
% calculate the signal power to scale the header power = var(time_signal_tx);
% The OFDM modulated signal for transmission time_wave_tx = ...
[power*header frame_guard time_signal_tx frame_guard power*header];
end
% show summary of the OFDM transmission modeling peak = max(abs(time_wave_tx(head_len+1:length(time_wave_tx)-head_len)));
sig_rms = std(time_wave_tx(head_len+1:length(time_wave_tx)-head_len));
peak_rms_ratio = (20*log10(peak/sig_rms));
fprintf('\nSummary of the OFDM transmission and channel modeling:\n')
fprintf('Peak to RMS power ratio at entrance of channel is: %f dB\n', ...
peak_rms_ratio)
122
% ####################################################### %
% **************** COMMUNICATION CHANNEL **************** %
% ####################################################### %
% ===== signal clipping ===== %
clipped_peak = (10^(0-(clipping/20)))*max(abs(time_wave_tx));
time_wave_tx(find(abs(time_wave_tx)>=clipped_peak))...
= clipped_peak.*time_wave_tx(find(abs(time_wave_tx)>=clipped_peak))...
./abs(time_wave_tx(find(abs(time_wave_tx)>=clipped_peak)));
% ===== channel noise ===== %
power = var(time_wave_tx); % Gaussian (AWGN)
SNR_linear = 10^(SNR_dB/10);
noise_factor = sqrt(power/SNR_linear);
noise = randn(1,length(time_wave_tx)) * noise_factor;
time_wave_rx = time_wave_tx + noise;
% show summary of the OFDM channel modeling peak = max(abs(time_wave_rx(head_len+1:length(time_wave_rx)-head_len)));
sig_rms = std(time_wave_rx(head_len+1:length(time_wave_rx)-head_len));
peak_rms_ratio = (20*log10(peak/sig_rms));
fprintf('Peak to RMS power ratio at exit of channel is: %f dB\n', ...
peak_rms_ratio)
% Save the signal to be received save('received.mat', 'time_wave_rx', 'h', 'w');
fprintf('#******** OFDM data transmitted in %f seconds ********#\n\n', toc)
% ####################################################### %
% ********************* OFDM RECEIVER ******************* %
% ####################################################### %
disp('Press any key to let OFDM RECEIVER proceed...')
pause;
clear all; % flush all data stored in memory previously tic; % start stopwatch
% invoking ofdm_parameters.m script to set OFDM system parameters load('ofdm_parameters');
% receive data load('received.mat');
time_wave_rx = time_wave_rx.';
end_x = length(time_wave_rx);
start_x = 1;
data = [];
phase = [];
last_frame = 0;
unpad = 0;
if rem(w*h, carrier_count)=0
unpad = carrier_count - rem(w*h, carrier_count);
end num_frame=ceil((h*w)*(word_size/symb_size)/(symb_per_frame*carrier_count));
fig = 0;
123 for k = 1:num_frame if k==1 || k==num_frame || rem(k,max(floor(num_frame/10),1))==0
fprintf('Demodulating Frame #%d\n',k)
end
% pick appropriate trunks of time signal to detect data frame if k==1
time_wave = time_wave_rx(start_x:min(end_x, ...
(head_len+symb_period*((symb_per_frame+1)/2+1))));
else time_wave = time_wave_rx(start_x:min(end_x, ...
((start_x-1) + (symb_period*((symb_per_frame+1)/2+1)))));
end
% detect the data frame that only contains the useful information frame_start = ...
ofdm_frame_detect(time_wave, symb_period, envelope, start_x);
if k==num_frame last_frame = 1;
frame_end = min(end_x, (frame_start-1) + symb_period*...
(1+ceil(rem(w*h,carrier_count*symb_per_frame)/carrier_count)));
else frame_end=min(frame_start-1+(symb_per_frame+1)*symb_period, end_x);
end
% take the time signal abstracted from this frame to demodulate time_wave = time_wave_rx(frame_start:frame_end);
% update the label for leftover signal start_x = frame_end - symb_period;
if k==ceil(num_frame/2)
fig = 1;
end
% demodulate the received time signal
[data_rx, phase_rx] = ofdm_demod...
(time_wave, ifft_size, carriers, conj_carriers, ...
guard_time, symb_size, word_size, last_frame, unpad, fig);
if fig==1
fig = 0; % indicate that ofdm_demod() has already generated plots end phase = [phase phase_rx];
data = [data data_rx];
end phase_rx = phase; % decoded phase data_rx = data; % received data
% convert symbol size (bits/symbol) to file word size (bits/byte) as needed data_out = ofdm_base_convert(data_rx, symb_size, word_size);
fprintf('#********** OFDM data received in %f seconds *********#\n\n', toc)
% ####################################################### %
% ********************** DATA OUTPUT ******************** %
% ####################################################### %
% patch or trim the data to fit a w-by-h image if length(data_out)>(w*h) % trim extra data data_out = data_out(1:(w*h));
elseif length(data_out)<(w*h) % patch a partially missing row buff_h = h;
h = ceil(length(data_out)/w);
% if one or more rows of pixels are missing, show a message to indicate if h=buff_h disp('WARNING: Output image smaller than original')
disp(' due to data loss in transmission.')
124 end
% to make the patch nearly seamless,
% make each patched pixel the same color as the one right above it if length(data_out)=(w*h)
for k=1:(w*h-length(data_out))
mend(k)=data_out(length(data_out)-w+k);
end data_out = [data_out mend];
end end
% format the demodulated data to reconstruct a bitmap image data_out = reshape(data_out, w, h)';
data_out = uint8(data_out);
% save the output image to a bitmap (*.bmp) file imwrite(data_out, file_out, 'bmp');
% ####################################################### %
% ****************** ERROR CALCULATIONS ***************** %
% ####################################################### %
% collect original data before modulation for error calculations load('err_calc.mat');
fprintf('\n#**************** Summary of Errors ****************#\n')
% Let received and original data match size and calculate data loss rate if length(data_rx)>length(baseband_tx)
data_rx = data_rx(1:length(baseband_tx));
phase_rx = phase_rx(1:length(baseband_tx));
elseif length(data_rx) fprintf('Data loss in this communication = %f%% (%d out of %d)\n', ...
(length(baseband_tx)-length(data_rx))/length(baseband_tx)*100, ...
length(baseband_tx)-length(data_rx), length(baseband_tx))
end
% find errors errors = find(baseband_tx(1:length(data_rx))=data_rx);
fprintf('Total number of errors = %d (out of %d)\n', ...
length(errors), length(data_rx))
% Bit Error Rate fprintf('Bit Error Rate (BER) = %f%%\n',length(errors)/length(data_rx)*100)
% find phase error in degrees and translate to -180 to +180 interval phase_tx = baseband_tx*360/(2^symb_size);
phase_err = (phase_rx - phase_tx(1:length(phase_rx)));
phase_err(find(phase_err>=180)) = phase_err(find(phase_err>=180))-360;
phase_err(find(phase_err<=-180)) = phase_err(find(phase_err<=-180))+360;
fprintf('Average Phase Error = %f (degree)\n', mean(abs(phase_err)))
% Error pixels x = ofdm_base_convert(baseband_tx, symb_size, word_size);
x = uint8(x);
x = x(1:(size(data_out,1)*size(data_out,2)));
y = reshape(data_out', 1, length(x));
err_pix = find(y=x);
fprintf('Percent error of pixels of the received image = %f%%\n\n', ...
length(err_pix)/length(x)*100)
fprintf('##########################################\n')
fprintf('#******** END of OFDM Simulation ********#\n')
125 fprintf('##########################################\n\n')
% ************* PARAMETERS INITIALIZATION ************* %
% This file configures parameters for the OFDM system.
% input/output file names file_in = [];
while isempty(file_in)
file_in = input('source data filename: ', 's');
if exist([pwd '/' file_in],'file')=2
fprintf ...
('"%s" does not exist in current directory.\n', file_in);
file_in = [];
end end file_out = [file_in(1:length(file_in)-4) '_OFDM.bmp'];
disp(['Output file will be: ' file_out])
% size of Inverse Fast Fourier Transform (must be power of 2)
ifft_size = 0.1; % force into the while loop below while (isempty(ifft_size) || ...
(rem(log2(ifft_size),1) = 0 || ifft_size < 8))
ifft_size = input('IFFT size: ');
if (isempty(ifft_size) || ...
(rem(log2(ifft_size),1) = 0 || ifft_size < 8))
disp('IFFT size must be at least 8 and power of 2.')
end end
% number of carriers carrier_count = ifft_size; % force into the while loop below while (isempty(carrier_count) || ...
(carrier_count>(ifft_size/2-2)) || carrier_count<2)
carrier_count = input('Number of carriers: ');
if (isempty(carrier_count) || (carrier_count > (ifft_size/2-2)))
disp('Must NOT be greater than ("IFFT size"/2-2)')
end end
% bits per symbol (1 = BPSK, 2=QPSK, 4=16PSK, 8=256PSK)
symb_size = 0; % force into the while loop below while (isempty(symb_size) || ...
(symb_size=1 && symb_size=2 && symb_size=4 && symb_size=8))
symb_size = input...
('Modulation(1=BPSK, 2=QPSK, 4=16PSK, 8=256PSK): ');
if (isempty(symb_size) || ...
(symb_size=1&&symb_size=2&&symb_size=4&&symb_size=8))
disp('Only 1, 2, 4, or 8 can be choosen')
end end
126
% channel clipping in dB
clipping = [];
while isempty(clipping)
clipping = input('Amplitude clipping introduced by communication channel
(in dB):');
end
% signal to noise ratio in dB
SNR_dB = [];
while isempty(SNR_dB)
SNR_dB = input('Signal-to-Noise Ratio (SNR) in dB: ');
end word_size = 8; % bits per word of source data (byte)
guard_time = ifft_size/4; % length of guard interval for each symbol period
% 25% of ifft_size
% number of symbols per carrier in each frame for transmission symb_per_frame = ceil(2^13/carrier_count);
% === Derived Parameters === %
% frame_len: length of one symbol period including guard time symb_period = ifft_size + guard_time;
% head_len: length of the header and trailer of the transmitted data head_len = symb_period*8;
% envelope: symb_period/envelope is the size of envelope detector envelope = ceil(symb_period/256)+1;
% === carriers assigned to IFFT bins === %
% spacing for carriers distributed in IFFT bins spacing = 0;
while (carrier_count*spacing) <= (ifft_size/2 - 2)
spacing = spacing + 1;
end spacing = spacing - 1;
% spead out carriers into IFFT bins accordingly midFreq = ifft_size/4;
first_carrier = midFreq - round((carrier_count-1)*spacing/2);
last_carrier = midFreq + floor((carrier_count-1)*spacing/2);
carriers = [first_carrier:spacing:last_carrier] + 1;
conj_carriers = ifft_size - carriers + 2;
127
% ************* FUNCTION: ofdm_base_convert() ************* %
% This function converts data from one base to another.
% "Base" refers to number of bits the symbol/word uses to represent data.
function data_out = ofdm_base_convert(data_in, base, new_base)
% if new base is in a higer order than the current base,
% make the size of data in current base a multiple of its new base if new_base>base data_in = data_in(1:...
floor(length(data_in)/(new_base/base))*(new_base/base));
end
% base to binary for k=1:base binary_matrix(k,:) = floor(data_in/2^(base-k));
data_in = rem(data_in,2^(base-k));
end
% format the binary matrix to fit dimensions of the new base newbase_matrix = reshape(binary_matrix, new_base, ...
size(binary_matrix,1)*size(binary_matrix,2)/new_base);
% binary to new_base data_out = zeros(1, size(newbase_matrix,2));
for k=1:new_base data_out = data_out + newbase_matrix(k,:)*(2^(new_base-k));
end
% ************* FUNCTION: ofdm_modulation() ************* %
% This function performance the OFDM modulation before data transmission.
function signal_tx = ofdm_modulate(data_tx, ifft_size, carriers, ...
conj_carriers, carrier_count, symb_size, guard_time, fig)
% symbols per carrier for this frame carrier_symb_count = ceil(length(data_tx)/carrier_count);
% append zeros to data with a length not multiple of number of carriers if length(data_tx)/carrier_count = carrier_symb_count,
padding = zeros(1, carrier_symb_count*carrier_count);
padding(1:length(data_tx)) = data_tx;
data_tx = padding;
end
% serial to parellel: each column represents a carrier data_tx_matrix = reshape(data_tx, carrier_count, carrier_symb_count)';
% --------------------------------- %
% ##### Differential Encoding ##### %
% --------------------------------- %
% an additional row and include reference point carrier_symb_count = size(data_tx_matrix,1) + 1;
1 2 3 4 5 6 7
1
П
од
п.
и
д
ат
а
И
нв
.
д
уб
л
.
В
за
м
.и
нв
.
П
од
п.
и
д
ат
а
42
5
В
ер
но
(
)
Н
.к
он
т
р
.
И
нв
.
по
дл
.
ф.2.106-5
Копировал
Формат А4
П
ер
в.
п
ри
м
ен
.
С
пр
ав
.
(
)
Листов
Примечание
Кол.
Наименование
Поз. обо-
значение
З
о
н
а
Приемопередатчик OFDM
Перечень элементов
ПГУ 1.11.05.01.10EР114
2
1 150 пФ-50В-NPO-1206+/-5%
1 1
2 2
2
С1, C2
С5
С6, С7
С8, С9
С10
С11
С12, С13
С14, С15 2
2
Кравченко
X1
Розетка 34000000-04 1
X2
Розетка СНЦ23-4/18В-1В ГЕ0.364.241ТУ
1
B1
Резонатор кварцевый MC-306 128МГц
В3 1
1
TR2
С21, С22 150 пкФ-50В-NPO-1206+/-5%
2 4
С23... С26 0,1 мкФ-50В-NPO-1206+/-5%
С16...С20 0,1 мкФ-50В-NPO-1206+/-5%
5
Конденсаторы
B2
Резонатор кварцевый HC-49U 4664МГц
Резонатор кварцевый MC-306 128МГц
1 1
1
TR1
Трансформатор четвертьволновый
Трансформатор питания ТП124-5
РК-50-9
C3, С4 0,1 мкФ-50В-NPO-1206+/-5%
2 12 пкФ-50В-NPO-1206+/-5%
0,1 мкФ-50В-NPO-1206+/-5%
10 мкФ-16В-В +/-10% (танталовый)
0,1 мкФ-50В-NPO-1206+/-5%
100 мкФ-16В-Е+/-10% (танталовый)
0,1 мкФ-50В-NPO-1206+/-5%
10 мкФ-16В-В +/-10% (танталовый)
С27... С30 12 пкФ-50В-NPO-1206+/-5%
4
С31, С32 0,1 мкФ-50В-NPO-1206+/-5%
2
117
118
119
ПРИЛОЖЕНИЕ Е
ЛИСТИНГ ПРОГРАММЫ MATLAB
ДЛЯ ПЕРЕДАЧИ И ПРИЕМА ИНФОРМАЦИИ
120
% *************** MAIN PROGRAM FILE *************** %
% This is the OFDM simulation program's main file.
% It requires a 256-grayscale bitmap file (*.bmp image file) as data source
% and the following 5 script and function m-files to work:
% ofdm_parameters.m, ofdm_base_convert.m, ofdm_modulate.m,
% ofdm_frame_detect.m, ofdm_demod.m
% ####################################################### %
% ************* OFDM SYSTEM INITIALIZATION: ************* %
% **** setting up parameters & obtaining source data **** %
% ####################################################### %
% Turn off exact-match warning to allow case-insensitive input files warning('off','MATLAB:dispatcher:InexactMatch');
clear all; % clear all previous data in MATLAB workspace close all; % close all previously opened figures and graphs fprintf('\n\n##########################################\n')
fprintf('#*********** OFDM Simulation ************#\n')
fprintf('##########################################\n\n')
% invoking ofdm_parameters.m script to set OFDM system parameters ofdm_parameters;
% save parameters for receiver save('ofdm_parameters');
% read data from input file x = imread(file_in);
% arrange data read from image for OFDM processing h = size(x,1);
w = size(x,2);
x = reshape(x,1,w*h);
baseband_tx = double(x);
% convert original data word size (bits/word) to symbol size (bits/symbol)
% symbol size (bits/symbol) is determined by choice of modulation method baseband_tx = ofdm_base_convert(baseband_tx, word_size, symb_size);
% save original baseband data for error calculation later save('err_calc.mat', 'baseband_tx');
121
% ####################################################### %
% ******************* OFDM TRANSMITTER ****************** %
% ####################################################### %
tic; % start stopwatch
% generate header and trailer (an exact copy of the header)
f = 0.25;
header = sin(0:f*2*pi:f*2*pi*(head_len-1));
f=f/(pi*2/3);
header = header+sin(0:f*2*pi:f*2*pi*(head_len-1));
% arrange data into frames and transmit frame_guard = zeros(1, symb_period);
time_wave_tx = [];
symb_per_carrier = ceil(length(baseband_tx)/carrier_count);
fig = 1;
if (symb_per_carrier > symb_per_frame) % === multiple frames === %
power = 0;
while isempty(baseband_tx)
% number of symbols per frame frame_len = min(symb_per_frame*carrier_count,length(baseband_tx));
frame_data = baseband_tx(1:frame_len);
% update the yet-to-modulate data baseband_tx = baseband_tx((frame_len+1):(length(baseband_tx)));
% OFDM modulation time_signal_tx = ofdm_modulate(frame_data,ifft_size,carriers,...
conj_carriers, carrier_count, symb_size, guard_time, fig);
fig = 0; %indicate that ofdm_modulate() has already generated plots
% add a frame guard to each frame of modulated signal time_wave_tx = [time_wave_tx frame_guard time_signal_tx];
frame_power = var(time_signal_tx);
end
% scale the header to match signal level power = power + frame_power;
% The OFDM modulated signal for transmission time_wave_tx = [power*header time_wave_tx frame_guard power*header];
else % === single frame === %
% OFDM modulation time_signal_tx = ofdm_modulate(baseband_tx,ifft_size,carriers,...
conj_carriers, carrier_count, symb_size, guard_time, fig);
% calculate the signal power to scale the header power = var(time_signal_tx);
% The OFDM modulated signal for transmission time_wave_tx = ...
[power*header frame_guard time_signal_tx frame_guard power*header];
end
% show summary of the OFDM transmission modeling peak = max(abs(time_wave_tx(head_len+1:length(time_wave_tx)-head_len)));
sig_rms = std(time_wave_tx(head_len+1:length(time_wave_tx)-head_len));
peak_rms_ratio = (20*log10(peak/sig_rms));
fprintf('\nSummary of the OFDM transmission and channel modeling:\n')
fprintf('Peak to RMS power ratio at entrance of channel is: %f dB\n', ...
peak_rms_ratio)
122
% ####################################################### %
% **************** COMMUNICATION CHANNEL **************** %
% ####################################################### %
% ===== signal clipping ===== %
clipped_peak = (10^(0-(clipping/20)))*max(abs(time_wave_tx));
time_wave_tx(find(abs(time_wave_tx)>=clipped_peak))...
= clipped_peak.*time_wave_tx(find(abs(time_wave_tx)>=clipped_peak))...
./abs(time_wave_tx(find(abs(time_wave_tx)>=clipped_peak)));
% ===== channel noise ===== %
power = var(time_wave_tx); % Gaussian (AWGN)
SNR_linear = 10^(SNR_dB/10);
noise_factor = sqrt(power/SNR_linear);
noise = randn(1,length(time_wave_tx)) * noise_factor;
time_wave_rx = time_wave_tx + noise;
% show summary of the OFDM channel modeling peak = max(abs(time_wave_rx(head_len+1:length(time_wave_rx)-head_len)));
sig_rms = std(time_wave_rx(head_len+1:length(time_wave_rx)-head_len));
peak_rms_ratio = (20*log10(peak/sig_rms));
fprintf('Peak to RMS power ratio at exit of channel is: %f dB\n', ...
peak_rms_ratio)
% Save the signal to be received save('received.mat', 'time_wave_rx', 'h', 'w');
fprintf('#******** OFDM data transmitted in %f seconds ********#\n\n', toc)
% ####################################################### %
% ********************* OFDM RECEIVER ******************* %
% ####################################################### %
disp('Press any key to let OFDM RECEIVER proceed...')
pause;
clear all; % flush all data stored in memory previously tic; % start stopwatch
% invoking ofdm_parameters.m script to set OFDM system parameters load('ofdm_parameters');
% receive data load('received.mat');
time_wave_rx = time_wave_rx.';
end_x = length(time_wave_rx);
start_x = 1;
data = [];
phase = [];
last_frame = 0;
unpad = 0;
if rem(w*h, carrier_count)=0
unpad = carrier_count - rem(w*h, carrier_count);
end num_frame=ceil((h*w)*(word_size/symb_size)/(symb_per_frame*carrier_count));
fig = 0;
123 for k = 1:num_frame if k==1 || k==num_frame || rem(k,max(floor(num_frame/10),1))==0
fprintf('Demodulating Frame #%d\n',k)
end
% pick appropriate trunks of time signal to detect data frame if k==1
time_wave = time_wave_rx(start_x:min(end_x, ...
(head_len+symb_period*((symb_per_frame+1)/2+1))));
else time_wave = time_wave_rx(start_x:min(end_x, ...
((start_x-1) + (symb_period*((symb_per_frame+1)/2+1)))));
end
% detect the data frame that only contains the useful information frame_start = ...
ofdm_frame_detect(time_wave, symb_period, envelope, start_x);
if k==num_frame last_frame = 1;
frame_end = min(end_x, (frame_start-1) + symb_period*...
(1+ceil(rem(w*h,carrier_count*symb_per_frame)/carrier_count)));
else frame_end=min(frame_start-1+(symb_per_frame+1)*symb_period, end_x);
end
% take the time signal abstracted from this frame to demodulate time_wave = time_wave_rx(frame_start:frame_end);
% update the label for leftover signal start_x = frame_end - symb_period;
if k==ceil(num_frame/2)
fig = 1;
end
% demodulate the received time signal
[data_rx, phase_rx] = ofdm_demod...
(time_wave, ifft_size, carriers, conj_carriers, ...
guard_time, symb_size, word_size, last_frame, unpad, fig);
if fig==1
fig = 0; % indicate that ofdm_demod() has already generated plots end phase = [phase phase_rx];
data = [data data_rx];
end phase_rx = phase; % decoded phase data_rx = data; % received data
% convert symbol size (bits/symbol) to file word size (bits/byte) as needed data_out = ofdm_base_convert(data_rx, symb_size, word_size);
fprintf('#********** OFDM data received in %f seconds *********#\n\n', toc)
% ####################################################### %
% ********************** DATA OUTPUT ******************** %
% ####################################################### %
% patch or trim the data to fit a w-by-h image if length(data_out)>(w*h) % trim extra data data_out = data_out(1:(w*h));
elseif length(data_out)<(w*h) % patch a partially missing row buff_h = h;
h = ceil(length(data_out)/w);
% if one or more rows of pixels are missing, show a message to indicate if h=buff_h disp('WARNING: Output image smaller than original')
disp(' due to data loss in transmission.')
124 end
% to make the patch nearly seamless,
% make each patched pixel the same color as the one right above it if length(data_out)=(w*h)
for k=1:(w*h-length(data_out))
mend(k)=data_out(length(data_out)-w+k);
end data_out = [data_out mend];
end end
% format the demodulated data to reconstruct a bitmap image data_out = reshape(data_out, w, h)';
data_out = uint8(data_out);
% save the output image to a bitmap (*.bmp) file imwrite(data_out, file_out, 'bmp');
% ####################################################### %
% ****************** ERROR CALCULATIONS ***************** %
% ####################################################### %
% collect original data before modulation for error calculations load('err_calc.mat');
fprintf('\n#**************** Summary of Errors ****************#\n')
% Let received and original data match size and calculate data loss rate if length(data_rx)>length(baseband_tx)
data_rx = data_rx(1:length(baseband_tx));
phase_rx = phase_rx(1:length(baseband_tx));
elseif length(data_rx) fprintf('Data loss in this communication = %f%% (%d out of %d)\n', ...
(length(baseband_tx)-length(data_rx))/length(baseband_tx)*100, ...
length(baseband_tx)-length(data_rx), length(baseband_tx))
end
% find errors errors = find(baseband_tx(1:length(data_rx))=data_rx);
fprintf('Total number of errors = %d (out of %d)\n', ...
length(errors), length(data_rx))
% Bit Error Rate fprintf('Bit Error Rate (BER) = %f%%\n',length(errors)/length(data_rx)*100)
% find phase error in degrees and translate to -180 to +180 interval phase_tx = baseband_tx*360/(2^symb_size);
phase_err = (phase_rx - phase_tx(1:length(phase_rx)));
phase_err(find(phase_err>=180)) = phase_err(find(phase_err>=180))-360;
phase_err(find(phase_err<=-180)) = phase_err(find(phase_err<=-180))+360;
fprintf('Average Phase Error = %f (degree)\n', mean(abs(phase_err)))
% Error pixels x = ofdm_base_convert(baseband_tx, symb_size, word_size);
x = uint8(x);
x = x(1:(size(data_out,1)*size(data_out,2)));
y = reshape(data_out', 1, length(x));
err_pix = find(y=x);
fprintf('Percent error of pixels of the received image = %f%%\n\n', ...
length(err_pix)/length(x)*100)
fprintf('##########################################\n')
fprintf('#******** END of OFDM Simulation ********#\n')
125 fprintf('##########################################\n\n')
% ************* PARAMETERS INITIALIZATION ************* %
% This file configures parameters for the OFDM system.
% input/output file names file_in = [];
while isempty(file_in)
file_in = input('source data filename: ', 's');
if exist([pwd '/' file_in],'file')=2
fprintf ...
('"%s" does not exist in current directory.\n', file_in);
file_in = [];
end end file_out = [file_in(1:length(file_in)-4) '_OFDM.bmp'];
disp(['Output file will be: ' file_out])
% size of Inverse Fast Fourier Transform (must be power of 2)
ifft_size = 0.1; % force into the while loop below while (isempty(ifft_size) || ...
(rem(log2(ifft_size),1) = 0 || ifft_size < 8))
ifft_size = input('IFFT size: ');
if (isempty(ifft_size) || ...
(rem(log2(ifft_size),1) = 0 || ifft_size < 8))
disp('IFFT size must be at least 8 and power of 2.')
end end
% number of carriers carrier_count = ifft_size; % force into the while loop below while (isempty(carrier_count) || ...
(carrier_count>(ifft_size/2-2)) || carrier_count<2)
carrier_count = input('Number of carriers: ');
if (isempty(carrier_count) || (carrier_count > (ifft_size/2-2)))
disp('Must NOT be greater than ("IFFT size"/2-2)')
end end
% bits per symbol (1 = BPSK, 2=QPSK, 4=16PSK, 8=256PSK)
symb_size = 0; % force into the while loop below while (isempty(symb_size) || ...
(symb_size=1 && symb_size=2 && symb_size=4 && symb_size=8))
symb_size = input...
('Modulation(1=BPSK, 2=QPSK, 4=16PSK, 8=256PSK): ');
if (isempty(symb_size) || ...
(symb_size=1&&symb_size=2&&symb_size=4&&symb_size=8))
disp('Only 1, 2, 4, or 8 can be choosen')
end end
126
% channel clipping in dB
clipping = [];
while isempty(clipping)
clipping = input('Amplitude clipping introduced by communication channel
(in dB):');
end
% signal to noise ratio in dB
SNR_dB = [];
while isempty(SNR_dB)
SNR_dB = input('Signal-to-Noise Ratio (SNR) in dB: ');
end word_size = 8; % bits per word of source data (byte)
guard_time = ifft_size/4; % length of guard interval for each symbol period
% 25% of ifft_size
% number of symbols per carrier in each frame for transmission symb_per_frame = ceil(2^13/carrier_count);
% === Derived Parameters === %
% frame_len: length of one symbol period including guard time symb_period = ifft_size + guard_time;
% head_len: length of the header and trailer of the transmitted data head_len = symb_period*8;
% envelope: symb_period/envelope is the size of envelope detector envelope = ceil(symb_period/256)+1;
% === carriers assigned to IFFT bins === %
% spacing for carriers distributed in IFFT bins spacing = 0;
while (carrier_count*spacing) <= (ifft_size/2 - 2)
spacing = spacing + 1;
end spacing = spacing - 1;
% spead out carriers into IFFT bins accordingly midFreq = ifft_size/4;
first_carrier = midFreq - round((carrier_count-1)*spacing/2);
last_carrier = midFreq + floor((carrier_count-1)*spacing/2);
carriers = [first_carrier:spacing:last_carrier] + 1;
conj_carriers = ifft_size - carriers + 2;
127
% ************* FUNCTION: ofdm_base_convert() ************* %
% This function converts data from one base to another.
% "Base" refers to number of bits the symbol/word uses to represent data.
function data_out = ofdm_base_convert(data_in, base, new_base)
% if new base is in a higer order than the current base,
% make the size of data in current base a multiple of its new base if new_base>base data_in = data_in(1:...
floor(length(data_in)/(new_base/base))*(new_base/base));
end
% base to binary for k=1:base binary_matrix(k,:) = floor(data_in/2^(base-k));
data_in = rem(data_in,2^(base-k));
end
% format the binary matrix to fit dimensions of the new base newbase_matrix = reshape(binary_matrix, new_base, ...
size(binary_matrix,1)*size(binary_matrix,2)/new_base);
% binary to new_base data_out = zeros(1, size(newbase_matrix,2));
for k=1:new_base data_out = data_out + newbase_matrix(k,:)*(2^(new_base-k));
end
% ************* FUNCTION: ofdm_modulation() ************* %
% This function performance the OFDM modulation before data transmission.
function signal_tx = ofdm_modulate(data_tx, ifft_size, carriers, ...
conj_carriers, carrier_count, symb_size, guard_time, fig)
% symbols per carrier for this frame carrier_symb_count = ceil(length(data_tx)/carrier_count);
% append zeros to data with a length not multiple of number of carriers if length(data_tx)/carrier_count = carrier_symb_count,
padding = zeros(1, carrier_symb_count*carrier_count);
padding(1:length(data_tx)) = data_tx;
data_tx = padding;
end
% serial to parellel: each column represents a carrier data_tx_matrix = reshape(data_tx, carrier_count, carrier_symb_count)';
% --------------------------------- %
% ##### Differential Encoding ##### %
% --------------------------------- %
% an additional row and include reference point carrier_symb_count = size(data_tx_matrix,1) + 1;
1 2 3 4 5 6 7
1
П
од
п.
и
д
ат
а
И
нв
.
д
уб
л
.
В
за
м
.и
нв
.
П
од
п.
и
д
ат
а
42
5
В
ер
но
(
)
Н
.к
он
т
р
.
И
нв
.
по
дл
.
ф.2.106-5
Копировал
Формат А4
П
ер
в.
п
ри
м
ен
.
С
пр
ав
.
(
)
Листов
Примечание
Кол.
Наименование
Поз. обо-
значение
З
о
н
а
Приемопередатчик OFDM
Перечень элементов
ПГУ 1.11.05.01.10EР114
2
1 150 пФ-50В-NPO-1206+/-5%
1 1
2 2
2
С1, C2
С5
С6, С7
С8, С9
С10
С11
С12, С13
С14, С15 2
2
Кравченко
X1
Розетка 34000000-04 1
X2
Розетка СНЦ23-4/18В-1В ГЕ0.364.241ТУ
1
B1
Резонатор кварцевый MC-306 128МГц
В3 1
1
TR2
С21, С22 150 пкФ-50В-NPO-1206+/-5%
2 4
С23... С26 0,1 мкФ-50В-NPO-1206+/-5%
С16...С20 0,1 мкФ-50В-NPO-1206+/-5%
5
Конденсаторы
B2
Резонатор кварцевый HC-49U 4664МГц
Резонатор кварцевый MC-306 128МГц
1 1
1
TR1
Трансформатор четвертьволновый
Трансформатор питания ТП124-5
РК-50-9
C3, С4 0,1 мкФ-50В-NPO-1206+/-5%
2 12 пкФ-50В-NPO-1206+/-5%
0,1 мкФ-50В-NPO-1206+/-5%
10 мкФ-16В-В +/-10% (танталовый)
0,1 мкФ-50В-NPO-1206+/-5%
100 мкФ-16В-Е+/-10% (танталовый)
0,1 мкФ-50В-NPO-1206+/-5%
10 мкФ-16В-В +/-10% (танталовый)
С27... С30 12 пкФ-50В-NPO-1206+/-5%
4
С31, С32 0,1 мкФ-50В-NPO-1206+/-5%
2
117
118
119
ПРИЛОЖЕНИЕ Е
ЛИСТИНГ ПРОГРАММЫ MATLAB
ДЛЯ ПЕРЕДАЧИ И ПРИЕМА ИНФОРМАЦИИ
120
% *************** MAIN PROGRAM FILE *************** %
% This is the OFDM simulation program's main file.
% It requires a 256-grayscale bitmap file (*.bmp image file) as data source
% and the following 5 script and function m-files to work:
% ofdm_parameters.m, ofdm_base_convert.m, ofdm_modulate.m,
% ofdm_frame_detect.m, ofdm_demod.m
% ####################################################### %
% ************* OFDM SYSTEM INITIALIZATION: ************* %
% **** setting up parameters & obtaining source data **** %
% ####################################################### %
% Turn off exact-match warning to allow case-insensitive input files warning('off','MATLAB:dispatcher:InexactMatch');
clear all; % clear all previous data in MATLAB workspace close all; % close all previously opened figures and graphs fprintf('\n\n##########################################\n')
fprintf('#*********** OFDM Simulation ************#\n')
fprintf('##########################################\n\n')
% invoking ofdm_parameters.m script to set OFDM system parameters ofdm_parameters;
% save parameters for receiver save('ofdm_parameters');
% read data from input file x = imread(file_in);
% arrange data read from image for OFDM processing h = size(x,1);
w = size(x,2);
x = reshape(x,1,w*h);
baseband_tx = double(x);
% convert original data word size (bits/word) to symbol size (bits/symbol)
% symbol size (bits/symbol) is determined by choice of modulation method baseband_tx = ofdm_base_convert(baseband_tx, word_size, symb_size);
% save original baseband data for error calculation later save('err_calc.mat', 'baseband_tx');
121
% ####################################################### %
% ******************* OFDM TRANSMITTER ****************** %
% ####################################################### %
tic; % start stopwatch
% generate header and trailer (an exact copy of the header)
f = 0.25;
header = sin(0:f*2*pi:f*2*pi*(head_len-1));
f=f/(pi*2/3);
header = header+sin(0:f*2*pi:f*2*pi*(head_len-1));
% arrange data into frames and transmit frame_guard = zeros(1, symb_period);
time_wave_tx = [];
symb_per_carrier = ceil(length(baseband_tx)/carrier_count);
fig = 1;
if (symb_per_carrier > symb_per_frame) % === multiple frames === %
power = 0;
while isempty(baseband_tx)
% number of symbols per frame frame_len = min(symb_per_frame*carrier_count,length(baseband_tx));
frame_data = baseband_tx(1:frame_len);
% update the yet-to-modulate data baseband_tx = baseband_tx((frame_len+1):(length(baseband_tx)));
% OFDM modulation time_signal_tx = ofdm_modulate(frame_data,ifft_size,carriers,...
conj_carriers, carrier_count, symb_size, guard_time, fig);
fig = 0; %indicate that ofdm_modulate() has already generated plots
% add a frame guard to each frame of modulated signal time_wave_tx = [time_wave_tx frame_guard time_signal_tx];
frame_power = var(time_signal_tx);
end
% scale the header to match signal level power = power + frame_power;
% The OFDM modulated signal for transmission time_wave_tx = [power*header time_wave_tx frame_guard power*header];
else % === single frame === %
% OFDM modulation time_signal_tx = ofdm_modulate(baseband_tx,ifft_size,carriers,...
conj_carriers, carrier_count, symb_size, guard_time, fig);
% calculate the signal power to scale the header power = var(time_signal_tx);
% The OFDM modulated signal for transmission time_wave_tx = ...
[power*header frame_guard time_signal_tx frame_guard power*header];
end
% show summary of the OFDM transmission modeling peak = max(abs(time_wave_tx(head_len+1:length(time_wave_tx)-head_len)));
sig_rms = std(time_wave_tx(head_len+1:length(time_wave_tx)-head_len));
peak_rms_ratio = (20*log10(peak/sig_rms));
fprintf('\nSummary of the OFDM transmission and channel modeling:\n')
fprintf('Peak to RMS power ratio at entrance of channel is: %f dB\n', ...
peak_rms_ratio)
122
% ####################################################### %
% **************** COMMUNICATION CHANNEL **************** %
% ####################################################### %
% ===== signal clipping ===== %
clipped_peak = (10^(0-(clipping/20)))*max(abs(time_wave_tx));
time_wave_tx(find(abs(time_wave_tx)>=clipped_peak))...
= clipped_peak.*time_wave_tx(find(abs(time_wave_tx)>=clipped_peak))...
./abs(time_wave_tx(find(abs(time_wave_tx)>=clipped_peak)));
% ===== channel noise ===== %
power = var(time_wave_tx); % Gaussian (AWGN)
SNR_linear = 10^(SNR_dB/10);
noise_factor = sqrt(power/SNR_linear);
noise = randn(1,length(time_wave_tx)) * noise_factor;
time_wave_rx = time_wave_tx + noise;
% show summary of the OFDM channel modeling peak = max(abs(time_wave_rx(head_len+1:length(time_wave_rx)-head_len)));
sig_rms = std(time_wave_rx(head_len+1:length(time_wave_rx)-head_len));
peak_rms_ratio = (20*log10(peak/sig_rms));
fprintf('Peak to RMS power ratio at exit of channel is: %f dB\n', ...
peak_rms_ratio)
% Save the signal to be received save('received.mat', 'time_wave_rx', 'h', 'w');
fprintf('#******** OFDM data transmitted in %f seconds ********#\n\n', toc)
% ####################################################### %
% ********************* OFDM RECEIVER ******************* %
% ####################################################### %
disp('Press any key to let OFDM RECEIVER proceed...')
pause;
clear all; % flush all data stored in memory previously tic; % start stopwatch
% invoking ofdm_parameters.m script to set OFDM system parameters load('ofdm_parameters');
% receive data load('received.mat');
time_wave_rx = time_wave_rx.';
end_x = length(time_wave_rx);
start_x = 1;
data = [];
phase = [];
last_frame = 0;
unpad = 0;
if rem(w*h, carrier_count)=0
unpad = carrier_count - rem(w*h, carrier_count);
end num_frame=ceil((h*w)*(word_size/symb_size)/(symb_per_frame*carrier_count));
fig = 0;
123 for k = 1:num_frame if k==1 || k==num_frame || rem(k,max(floor(num_frame/10),1))==0
fprintf('Demodulating Frame #%d\n',k)
end
% pick appropriate trunks of time signal to detect data frame if k==1
time_wave = time_wave_rx(start_x:min(end_x, ...
(head_len+symb_period*((symb_per_frame+1)/2+1))));
else time_wave = time_wave_rx(start_x:min(end_x, ...
((start_x-1) + (symb_period*((symb_per_frame+1)/2+1)))));
end
% detect the data frame that only contains the useful information frame_start = ...
ofdm_frame_detect(time_wave, symb_period, envelope, start_x);
if k==num_frame last_frame = 1;
frame_end = min(end_x, (frame_start-1) + symb_period*...
(1+ceil(rem(w*h,carrier_count*symb_per_frame)/carrier_count)));
else frame_end=min(frame_start-1+(symb_per_frame+1)*symb_period, end_x);
end
% take the time signal abstracted from this frame to demodulate time_wave = time_wave_rx(frame_start:frame_end);
% update the label for leftover signal start_x = frame_end - symb_period;
if k==ceil(num_frame/2)
fig = 1;
end
% demodulate the received time signal
[data_rx, phase_rx] = ofdm_demod...
(time_wave, ifft_size, carriers, conj_carriers, ...
guard_time, symb_size, word_size, last_frame, unpad, fig);
if fig==1
fig = 0; % indicate that ofdm_demod() has already generated plots end phase = [phase phase_rx];
data = [data data_rx];
end phase_rx = phase; % decoded phase data_rx = data; % received data
% convert symbol size (bits/symbol) to file word size (bits/byte) as needed data_out = ofdm_base_convert(data_rx, symb_size, word_size);
fprintf('#********** OFDM data received in %f seconds *********#\n\n', toc)
% ####################################################### %
% ********************** DATA OUTPUT ******************** %
% ####################################################### %
% patch or trim the data to fit a w-by-h image if length(data_out)>(w*h) % trim extra data data_out = data_out(1:(w*h));
elseif length(data_out)<(w*h) % patch a partially missing row buff_h = h;
h = ceil(length(data_out)/w);
% if one or more rows of pixels are missing, show a message to indicate if h=buff_h disp('WARNING: Output image smaller than original')
disp(' due to data loss in transmission.')
124 end
% to make the patch nearly seamless,
% make each patched pixel the same color as the one right above it if length(data_out)=(w*h)
for k=1:(w*h-length(data_out))
mend(k)=data_out(length(data_out)-w+k);
end data_out = [data_out mend];
end end
% format the demodulated data to reconstruct a bitmap image data_out = reshape(data_out, w, h)';
data_out = uint8(data_out);
% save the output image to a bitmap (*.bmp) file imwrite(data_out, file_out, 'bmp');
% ####################################################### %
% ****************** ERROR CALCULATIONS ***************** %
% ####################################################### %
% collect original data before modulation for error calculations load('err_calc.mat');
fprintf('\n#**************** Summary of Errors ****************#\n')
% Let received and original data match size and calculate data loss rate if length(data_rx)>length(baseband_tx)
data_rx = data_rx(1:length(baseband_tx));
phase_rx = phase_rx(1:length(baseband_tx));
elseif length(data_rx) fprintf('Data loss in this communication = %f%% (%d out of %d)\n', ...
(length(baseband_tx)-length(data_rx))/length(baseband_tx)*100, ...
length(baseband_tx)-length(data_rx), length(baseband_tx))
end
% find errors errors = find(baseband_tx(1:length(data_rx))=data_rx);
fprintf('Total number of errors = %d (out of %d)\n', ...
length(errors), length(data_rx))
% Bit Error Rate fprintf('Bit Error Rate (BER) = %f%%\n',length(errors)/length(data_rx)*100)
% find phase error in degrees and translate to -180 to +180 interval phase_tx = baseband_tx*360/(2^symb_size);
phase_err = (phase_rx - phase_tx(1:length(phase_rx)));
phase_err(find(phase_err>=180)) = phase_err(find(phase_err>=180))-360;
phase_err(find(phase_err<=-180)) = phase_err(find(phase_err<=-180))+360;
fprintf('Average Phase Error = %f (degree)\n', mean(abs(phase_err)))
% Error pixels x = ofdm_base_convert(baseband_tx, symb_size, word_size);
x = uint8(x);
x = x(1:(size(data_out,1)*size(data_out,2)));
y = reshape(data_out', 1, length(x));
err_pix = find(y=x);
fprintf('Percent error of pixels of the received image = %f%%\n\n', ...
length(err_pix)/length(x)*100)
fprintf('##########################################\n')
fprintf('#******** END of OFDM Simulation ********#\n')
125 fprintf('##########################################\n\n')
% ************* PARAMETERS INITIALIZATION ************* %
% This file configures parameters for the OFDM system.
% input/output file names file_in = [];
while isempty(file_in)
file_in = input('source data filename: ', 's');
if exist([pwd '/' file_in],'file')=2
fprintf ...
('"%s" does not exist in current directory.\n', file_in);
file_in = [];
end end file_out = [file_in(1:length(file_in)-4) '_OFDM.bmp'];
disp(['Output file will be: ' file_out])
% size of Inverse Fast Fourier Transform (must be power of 2)
ifft_size = 0.1; % force into the while loop below while (isempty(ifft_size) || ...
(rem(log2(ifft_size),1) = 0 || ifft_size < 8))
ifft_size = input('IFFT size: ');
if (isempty(ifft_size) || ...
(rem(log2(ifft_size),1) = 0 || ifft_size < 8))
disp('IFFT size must be at least 8 and power of 2.')
end end
% number of carriers carrier_count = ifft_size; % force into the while loop below while (isempty(carrier_count) || ...
(carrier_count>(ifft_size/2-2)) || carrier_count<2)
carrier_count = input('Number of carriers: ');
if (isempty(carrier_count) || (carrier_count > (ifft_size/2-2)))
disp('Must NOT be greater than ("IFFT size"/2-2)')
end end
% bits per symbol (1 = BPSK, 2=QPSK, 4=16PSK, 8=256PSK)
symb_size = 0; % force into the while loop below while (isempty(symb_size) || ...
(symb_size=1 && symb_size=2 && symb_size=4 && symb_size=8))
symb_size = input...
('Modulation(1=BPSK, 2=QPSK, 4=16PSK, 8=256PSK): ');
if (isempty(symb_size) || ...
(symb_size=1&&symb_size=2&&symb_size=4&&symb_size=8))
disp('Only 1, 2, 4, or 8 can be choosen')
end end
126
% channel clipping in dB
clipping = [];
while isempty(clipping)
clipping = input('Amplitude clipping introduced by communication channel
(in dB):');
end
% signal to noise ratio in dB
SNR_dB = [];
while isempty(SNR_dB)
SNR_dB = input('Signal-to-Noise Ratio (SNR) in dB: ');
end word_size = 8; % bits per word of source data (byte)
guard_time = ifft_size/4; % length of guard interval for each symbol period
% 25% of ifft_size
% number of symbols per carrier in each frame for transmission symb_per_frame = ceil(2^13/carrier_count);
% === Derived Parameters === %
% frame_len: length of one symbol period including guard time symb_period = ifft_size + guard_time;
% head_len: length of the header and trailer of the transmitted data head_len = symb_period*8;
% envelope: symb_period/envelope is the size of envelope detector envelope = ceil(symb_period/256)+1;
% === carriers assigned to IFFT bins === %
% spacing for carriers distributed in IFFT bins spacing = 0;
while (carrier_count*spacing) <= (ifft_size/2 - 2)
spacing = spacing + 1;
end spacing = spacing - 1;
% spead out carriers into IFFT bins accordingly midFreq = ifft_size/4;
first_carrier = midFreq - round((carrier_count-1)*spacing/2);
last_carrier = midFreq + floor((carrier_count-1)*spacing/2);
carriers = [first_carrier:spacing:last_carrier] + 1;
conj_carriers = ifft_size - carriers + 2;
127
% ************* FUNCTION: ofdm_base_convert() ************* %
% This function converts data from one base to another.
% "Base" refers to number of bits the symbol/word uses to represent data.
function data_out = ofdm_base_convert(data_in, base, new_base)
% if new base is in a higer order than the current base,
% make the size of data in current base a multiple of its new base if new_base>base data_in = data_in(1:...
floor(length(data_in)/(new_base/base))*(new_base/base));
end
% base to binary for k=1:base binary_matrix(k,:) = floor(data_in/2^(base-k));
data_in = rem(data_in,2^(base-k));
end
% format the binary matrix to fit dimensions of the new base newbase_matrix = reshape(binary_matrix, new_base, ...
size(binary_matrix,1)*size(binary_matrix,2)/new_base);
% binary to new_base data_out = zeros(1, size(newbase_matrix,2));
for k=1:new_base data_out = data_out + newbase_matrix(k,:)*(2^(new_base-k));
end
% ************* FUNCTION: ofdm_modulation() ************* %
% This function performance the OFDM modulation before data transmission.
function signal_tx = ofdm_modulate(data_tx, ifft_size, carriers, ...
conj_carriers, carrier_count, symb_size, guard_time, fig)
% symbols per carrier for this frame carrier_symb_count = ceil(length(data_tx)/carrier_count);
% append zeros to data with a length not multiple of number of carriers if length(data_tx)/carrier_count = carrier_symb_count,
padding = zeros(1, carrier_symb_count*carrier_count);
padding(1:length(data_tx)) = data_tx;
data_tx = padding;
end
% serial to parellel: each column represents a carrier data_tx_matrix = reshape(data_tx, carrier_count, carrier_symb_count)';
% --------------------------------- %
% ##### Differential Encoding ##### %
% --------------------------------- %
% an additional row and include reference point carrier_symb_count = size(data_tx_matrix,1) + 1;
1 2 3 4 5 6 7
1
П
од
п.
и
д
ат
а
И
нв
.
д
уб
л
.
В
за
м
.и
нв
.
П
од
п.
и
д
ат
а
42
5
В
ер
но
(
)
Н
.к
он
т
р
.
И
нв
.
по
дл
.
ф.2.106-5
Копировал
Формат А4
П
ер
в.
п
ри
м
ен
.
С
пр
ав
.
(
)
Листов
Примечание
Кол.
Наименование
Поз. обо-
значение
З
о
н
а
Приемопередатчик OFDM
Перечень элементов
ПГУ 1.11.05.01.10EР114
2
1 150 пФ-50В-NPO-1206+/-5%
1 1
2 2
2
С1, C2
С5
С6, С7
С8, С9
С10
С11
С12, С13
С14, С15 2
2
Кравченко
X1
Розетка 34000000-04 1
X2
Розетка СНЦ23-4/18В-1В ГЕ0.364.241ТУ
1
B1
Резонатор кварцевый MC-306 128МГц
В3 1
1
TR2
С21, С22 150 пкФ-50В-NPO-1206+/-5%
2 4
С23... С26 0,1 мкФ-50В-NPO-1206+/-5%
С16...С20 0,1 мкФ-50В-NPO-1206+/-5%
5
Конденсаторы
B2
Резонатор кварцевый HC-49U 4664МГц
Резонатор кварцевый MC-306 128МГц
1 1
1
TR1
Трансформатор четвертьволновый
Трансформатор питания ТП124-5
РК-50-9
C3, С4 0,1 мкФ-50В-NPO-1206+/-5%
2 12 пкФ-50В-NPO-1206+/-5%
0,1 мкФ-50В-NPO-1206+/-5%
10 мкФ-16В-В +/-10% (танталовый)
0,1 мкФ-50В-NPO-1206+/-5%
100 мкФ-16В-Е+/-10% (танталовый)
0,1 мкФ-50В-NPO-1206+/-5%
10 мкФ-16В-В +/-10% (танталовый)
С27... С30 12 пкФ-50В-NPO-1206+/-5%
4
С31, С32 0,1 мкФ-50В-NPO-1206+/-5%
2
117
118
119
ПРИЛОЖЕНИЕ Е
ЛИСТИНГ ПРОГРАММЫ MATLAB
ДЛЯ ПЕРЕДАЧИ И ПРИЕМА ИНФОРМАЦИИ
120
% *************** MAIN PROGRAM FILE *************** %
% This is the OFDM simulation program's main file.
% It requires a 256-grayscale bitmap file (*.bmp image file) as data source
% and the following 5 script and function m-files to work:
% ofdm_parameters.m, ofdm_base_convert.m, ofdm_modulate.m,
% ofdm_frame_detect.m, ofdm_demod.m
% ####################################################### %
% ************* OFDM SYSTEM INITIALIZATION: ************* %
% **** setting up parameters & obtaining source data **** %
% ####################################################### %
% Turn off exact-match warning to allow case-insensitive input files warning('off','MATLAB:dispatcher:InexactMatch');
clear all; % clear all previous data in MATLAB workspace close all; % close all previously opened figures and graphs fprintf('\n\n##########################################\n')
fprintf('#*********** OFDM Simulation ************#\n')
fprintf('##########################################\n\n')
% invoking ofdm_parameters.m script to set OFDM system parameters ofdm_parameters;
% save parameters for receiver save('ofdm_parameters');
% read data from input file x = imread(file_in);
% arrange data read from image for OFDM processing h = size(x,1);
w = size(x,2);
x = reshape(x,1,w*h);
baseband_tx = double(x);
% convert original data word size (bits/word) to symbol size (bits/symbol)
% symbol size (bits/symbol) is determined by choice of modulation method baseband_tx = ofdm_base_convert(baseband_tx, word_size, symb_size);
% save original baseband data for error calculation later save('err_calc.mat', 'baseband_tx');
121
% ####################################################### %
% ******************* OFDM TRANSMITTER ****************** %
% ####################################################### %
tic; % start stopwatch
% generate header and trailer (an exact copy of the header)
f = 0.25;
header = sin(0:f*2*pi:f*2*pi*(head_len-1));
f=f/(pi*2/3);
header = header+sin(0:f*2*pi:f*2*pi*(head_len-1));
% arrange data into frames and transmit frame_guard = zeros(1, symb_period);
time_wave_tx = [];
symb_per_carrier = ceil(length(baseband_tx)/carrier_count);
fig = 1;
if (symb_per_carrier > symb_per_frame) % === multiple frames === %
power = 0;
while isempty(baseband_tx)
% number of symbols per frame frame_len = min(symb_per_frame*carrier_count,length(baseband_tx));
frame_data = baseband_tx(1:frame_len);
% update the yet-to-modulate data baseband_tx = baseband_tx((frame_len+1):(length(baseband_tx)));
% OFDM modulation time_signal_tx = ofdm_modulate(frame_data,ifft_size,carriers,...
conj_carriers, carrier_count, symb_size, guard_time, fig);
fig = 0; %indicate that ofdm_modulate() has already generated plots
% add a frame guard to each frame of modulated signal time_wave_tx = [time_wave_tx frame_guard time_signal_tx];
frame_power = var(time_signal_tx);
end
% scale the header to match signal level power = power + frame_power;
% The OFDM modulated signal for transmission time_wave_tx = [power*header time_wave_tx frame_guard power*header];
else % === single frame === %
% OFDM modulation time_signal_tx = ofdm_modulate(baseband_tx,ifft_size,carriers,...
conj_carriers, carrier_count, symb_size, guard_time, fig);
% calculate the signal power to scale the header power = var(time_signal_tx);
% The OFDM modulated signal for transmission time_wave_tx = ...
[power*header frame_guard time_signal_tx frame_guard power*header];
end
% show summary of the OFDM transmission modeling peak = max(abs(time_wave_tx(head_len+1:length(time_wave_tx)-head_len)));
sig_rms = std(time_wave_tx(head_len+1:length(time_wave_tx)-head_len));
peak_rms_ratio = (20*log10(peak/sig_rms));
fprintf('\nSummary of the OFDM transmission and channel modeling:\n')
fprintf('Peak to RMS power ratio at entrance of channel is: %f dB\n', ...
peak_rms_ratio)
122
% ####################################################### %
% **************** COMMUNICATION CHANNEL **************** %
% ####################################################### %
% ===== signal clipping ===== %
clipped_peak = (10^(0-(clipping/20)))*max(abs(time_wave_tx));
time_wave_tx(find(abs(time_wave_tx)>=clipped_peak))...
= clipped_peak.*time_wave_tx(find(abs(time_wave_tx)>=clipped_peak))...
./abs(time_wave_tx(find(abs(time_wave_tx)>=clipped_peak)));
% ===== channel noise ===== %
power = var(time_wave_tx); % Gaussian (AWGN)
SNR_linear = 10^(SNR_dB/10);
noise_factor = sqrt(power/SNR_linear);
noise = randn(1,length(time_wave_tx)) * noise_factor;
time_wave_rx = time_wave_tx + noise;
% show summary of the OFDM channel modeling peak = max(abs(time_wave_rx(head_len+1:length(time_wave_rx)-head_len)));
sig_rms = std(time_wave_rx(head_len+1:length(time_wave_rx)-head_len));
peak_rms_ratio = (20*log10(peak/sig_rms));
fprintf('Peak to RMS power ratio at exit of channel is: %f dB\n', ...
peak_rms_ratio)
% Save the signal to be received save('received.mat', 'time_wave_rx', 'h', 'w');
fprintf('#******** OFDM data transmitted in %f seconds ********#\n\n', toc)
% ####################################################### %
% ********************* OFDM RECEIVER ******************* %
% ####################################################### %
disp('Press any key to let OFDM RECEIVER proceed...')
pause;
clear all; % flush all data stored in memory previously tic; % start stopwatch
% invoking ofdm_parameters.m script to set OFDM system parameters load('ofdm_parameters');
% receive data load('received.mat');
time_wave_rx = time_wave_rx.';
end_x = length(time_wave_rx);
start_x = 1;
data = [];
phase = [];
last_frame = 0;
unpad = 0;
if rem(w*h, carrier_count)=0
unpad = carrier_count - rem(w*h, carrier_count);
end num_frame=ceil((h*w)*(word_size/symb_size)/(symb_per_frame*carrier_count));
fig = 0;
123 for k = 1:num_frame if k==1 || k==num_frame || rem(k,max(floor(num_frame/10),1))==0
fprintf('Demodulating Frame #%d\n',k)
end
% pick appropriate trunks of time signal to detect data frame if k==1
time_wave = time_wave_rx(start_x:min(end_x, ...
(head_len+symb_period*((symb_per_frame+1)/2+1))));
else time_wave = time_wave_rx(start_x:min(end_x, ...
((start_x-1) + (symb_period*((symb_per_frame+1)/2+1)))));
end
% detect the data frame that only contains the useful information frame_start = ...
ofdm_frame_detect(time_wave, symb_period, envelope, start_x);
if k==num_frame last_frame = 1;
frame_end = min(end_x, (frame_start-1) + symb_period*...
(1+ceil(rem(w*h,carrier_count*symb_per_frame)/carrier_count)));
else frame_end=min(frame_start-1+(symb_per_frame+1)*symb_period, end_x);
end
% take the time signal abstracted from this frame to demodulate time_wave = time_wave_rx(frame_start:frame_end);
% update the label for leftover signal start_x = frame_end - symb_period;
if k==ceil(num_frame/2)
fig = 1;
end
% demodulate the received time signal
[data_rx, phase_rx] = ofdm_demod...
(time_wave, ifft_size, carriers, conj_carriers, ...
guard_time, symb_size, word_size, last_frame, unpad, fig);
if fig==1
fig = 0; % indicate that ofdm_demod() has already generated plots end phase = [phase phase_rx];
data = [data data_rx];
end phase_rx = phase; % decoded phase data_rx = data; % received data
% convert symbol size (bits/symbol) to file word size (bits/byte) as needed data_out = ofdm_base_convert(data_rx, symb_size, word_size);
fprintf('#********** OFDM data received in %f seconds *********#\n\n', toc)
% ####################################################### %
% ********************** DATA OUTPUT ******************** %
% ####################################################### %
% patch or trim the data to fit a w-by-h image if length(data_out)>(w*h) % trim extra data data_out = data_out(1:(w*h));
elseif length(data_out)<(w*h) % patch a partially missing row buff_h = h;
h = ceil(length(data_out)/w);
% if one or more rows of pixels are missing, show a message to indicate if h=buff_h disp('WARNING: Output image smaller than original')
disp(' due to data loss in transmission.')
124 end
% to make the patch nearly seamless,
% make each patched pixel the same color as the one right above it if length(data_out)=(w*h)
for k=1:(w*h-length(data_out))
mend(k)=data_out(length(data_out)-w+k);
end data_out = [data_out mend];
end end
% format the demodulated data to reconstruct a bitmap image data_out = reshape(data_out, w, h)';
data_out = uint8(data_out);
% save the output image to a bitmap (*.bmp) file imwrite(data_out, file_out, 'bmp');
% ####################################################### %
% ****************** ERROR CALCULATIONS ***************** %
% ####################################################### %
% collect original data before modulation for error calculations load('err_calc.mat');
fprintf('\n#**************** Summary of Errors ****************#\n')
% Let received and original data match size and calculate data loss rate if length(data_rx)>length(baseband_tx)
data_rx = data_rx(1:length(baseband_tx));
phase_rx = phase_rx(1:length(baseband_tx));
elseif length(data_rx) fprintf('Data loss in this communication = %f%% (%d out of %d)\n', ...
(length(baseband_tx)-length(data_rx))/length(baseband_tx)*100, ...
length(baseband_tx)-length(data_rx), length(baseband_tx))
end
% find errors errors = find(baseband_tx(1:length(data_rx))=data_rx);
fprintf('Total number of errors = %d (out of %d)\n', ...
length(errors), length(data_rx))
% Bit Error Rate fprintf('Bit Error Rate (BER) = %f%%\n',length(errors)/length(data_rx)*100)
% find phase error in degrees and translate to -180 to +180 interval phase_tx = baseband_tx*360/(2^symb_size);
phase_err = (phase_rx - phase_tx(1:length(phase_rx)));
phase_err(find(phase_err>=180)) = phase_err(find(phase_err>=180))-360;
phase_err(find(phase_err<=-180)) = phase_err(find(phase_err<=-180))+360;
fprintf('Average Phase Error = %f (degree)\n', mean(abs(phase_err)))
% Error pixels x = ofdm_base_convert(baseband_tx, symb_size, word_size);
x = uint8(x);
x = x(1:(size(data_out,1)*size(data_out,2)));
y = reshape(data_out', 1, length(x));
err_pix = find(y=x);
fprintf('Percent error of pixels of the received image = %f%%\n\n', ...
length(err_pix)/length(x)*100)
fprintf('##########################################\n')
fprintf('#******** END of OFDM Simulation ********#\n')
125 fprintf('##########################################\n\n')
% ************* PARAMETERS INITIALIZATION ************* %
% This file configures parameters for the OFDM system.
% input/output file names file_in = [];
while isempty(file_in)
file_in = input('source data filename: ', 's');
if exist([pwd '/' file_in],'file')=2
fprintf ...
('"%s" does not exist in current directory.\n', file_in);
file_in = [];
end end file_out = [file_in(1:length(file_in)-4) '_OFDM.bmp'];
disp(['Output file will be: ' file_out])
% size of Inverse Fast Fourier Transform (must be power of 2)
ifft_size = 0.1; % force into the while loop below while (isempty(ifft_size) || ...
(rem(log2(ifft_size),1) = 0 || ifft_size < 8))
ifft_size = input('IFFT size: ');
if (isempty(ifft_size) || ...
(rem(log2(ifft_size),1) = 0 || ifft_size < 8))
disp('IFFT size must be at least 8 and power of 2.')
end end
% number of carriers carrier_count = ifft_size; % force into the while loop below while (isempty(carrier_count) || ...
(carrier_count>(ifft_size/2-2)) || carrier_count<2)
carrier_count = input('Number of carriers: ');
if (isempty(carrier_count) || (carrier_count > (ifft_size/2-2)))
disp('Must NOT be greater than ("IFFT size"/2-2)')
end end
% bits per symbol (1 = BPSK, 2=QPSK, 4=16PSK, 8=256PSK)
symb_size = 0; % force into the while loop below while (isempty(symb_size) || ...
(symb_size=1 && symb_size=2 && symb_size=4 && symb_size=8))
symb_size = input...
('Modulation(1=BPSK, 2=QPSK, 4=16PSK, 8=256PSK): ');
if (isempty(symb_size) || ...
(symb_size=1&&symb_size=2&&symb_size=4&&symb_size=8))
disp('Only 1, 2, 4, or 8 can be choosen')
end end
126
% channel clipping in dB
clipping = [];
while isempty(clipping)
clipping = input('Amplitude clipping introduced by communication channel
(in dB):');
end
% signal to noise ratio in dB
SNR_dB = [];
while isempty(SNR_dB)
SNR_dB = input('Signal-to-Noise Ratio (SNR) in dB: ');
end word_size = 8; % bits per word of source data (byte)
guard_time = ifft_size/4; % length of guard interval for each symbol period
% 25% of ifft_size
% number of symbols per carrier in each frame for transmission symb_per_frame = ceil(2^13/carrier_count);
% === Derived Parameters === %
% frame_len: length of one symbol period including guard time symb_period = ifft_size + guard_time;
% head_len: length of the header and trailer of the transmitted data head_len = symb_period*8;
% envelope: symb_period/envelope is the size of envelope detector envelope = ceil(symb_period/256)+1;
% === carriers assigned to IFFT bins === %
% spacing for carriers distributed in IFFT bins spacing = 0;
while (carrier_count*spacing) <= (ifft_size/2 - 2)
spacing = spacing + 1;
end spacing = spacing - 1;
% spead out carriers into IFFT bins accordingly midFreq = ifft_size/4;
first_carrier = midFreq - round((carrier_count-1)*spacing/2);
last_carrier = midFreq + floor((carrier_count-1)*spacing/2);
carriers = [first_carrier:spacing:last_carrier] + 1;
conj_carriers = ifft_size - carriers + 2;
127
% ************* FUNCTION: ofdm_base_convert() ************* %
% This function converts data from one base to another.
% "Base" refers to number of bits the symbol/word uses to represent data.
function data_out = ofdm_base_convert(data_in, base, new_base)
% if new base is in a higer order than the current base,
% make the size of data in current base a multiple of its new base if new_base>base data_in = data_in(1:...
floor(length(data_in)/(new_base/base))*(new_base/base));
end
% base to binary for k=1:base binary_matrix(k,:) = floor(data_in/2^(base-k));
data_in = rem(data_in,2^(base-k));
end
% format the binary matrix to fit dimensions of the new base newbase_matrix = reshape(binary_matrix, new_base, ...
size(binary_matrix,1)*size(binary_matrix,2)/new_base);
% binary to new_base data_out = zeros(1, size(newbase_matrix,2));
for k=1:new_base data_out = data_out + newbase_matrix(k,:)*(2^(new_base-k));
end
% ************* FUNCTION: ofdm_modulation() ************* %
% This function performance the OFDM modulation before data transmission.
function signal_tx = ofdm_modulate(data_tx, ifft_size, carriers, ...
conj_carriers, carrier_count, symb_size, guard_time, fig)
% symbols per carrier for this frame carrier_symb_count = ceil(length(data_tx)/carrier_count);
% append zeros to data with a length not multiple of number of carriers if length(data_tx)/carrier_count = carrier_symb_count,
padding = zeros(1, carrier_symb_count*carrier_count);
padding(1:length(data_tx)) = data_tx;
data_tx = padding;
end
% serial to parellel: each column represents a carrier data_tx_matrix = reshape(data_tx, carrier_count, carrier_symb_count)';
% --------------------------------- %
% ##### Differential Encoding ##### %
% --------------------------------- %
% an additional row and include reference point carrier_symb_count = size(data_tx_matrix,1) + 1;
1 2 3 4 5 6 7
1
П
од
п.
и
д
ат
а
И
нв
.
д
уб
л
.
В
за
м
.и
нв
.
П
од
п.
и
д
ат
а
42
5
В
ер
но
(
)
Н
.к
он
т
р
.
И
нв
.
по
дл
.
ф.2.106-5
Копировал
Формат А4
П
ер
в.
п
ри
м
ен
.
С
пр
ав
.
(
)
Листов
Примечание
Кол.
Наименование
Поз. обо-
значение
З
о
н
а
Приемопередатчик OFDM
Перечень элементов
ПГУ 1.11.05.01.10EР114
2
1 150 пФ-50В-NPO-1206+/-5%
1 1
2 2
2
С1, C2
С5
С6, С7
С8, С9
С10
С11
С12, С13
С14, С15 2
2
Кравченко
X1
Розетка 34000000-04 1
X2
Розетка СНЦ23-4/18В-1В ГЕ0.364.241ТУ
1
B1
Резонатор кварцевый MC-306 128МГц
В3 1
1
TR2
С21, С22 150 пкФ-50В-NPO-1206+/-5%
2 4
С23... С26 0,1 мкФ-50В-NPO-1206+/-5%
С16...С20 0,1 мкФ-50В-NPO-1206+/-5%
5
Конденсаторы
B2
Резонатор кварцевый HC-49U 4664МГц
Резонатор кварцевый MC-306 128МГц
1 1
1
TR1
Трансформатор четвертьволновый
Трансформатор питания ТП124-5
РК-50-9
C3, С4 0,1 мкФ-50В-NPO-1206+/-5%
2 12 пкФ-50В-NPO-1206+/-5%
0,1 мкФ-50В-NPO-1206+/-5%
10 мкФ-16В-В +/-10% (танталовый)
0,1 мкФ-50В-NPO-1206+/-5%
100 мкФ-16В-Е+/-10% (танталовый)
0,1 мкФ-50В-NPO-1206+/-5%
10 мкФ-16В-В +/-10% (танталовый)
С27... С30 12 пкФ-50В-NPO-1206+/-5%
4
С31, С32 0,1 мкФ-50В-NPO-1206+/-5%
2
117
118
119
ПРИЛОЖЕНИЕ Е
ЛИСТИНГ ПРОГРАММЫ MATLAB
ДЛЯ ПЕРЕДАЧИ И ПРИЕМА ИНФОРМАЦИИ
120
% *************** MAIN PROGRAM FILE *************** %
% This is the OFDM simulation program's main file.
% It requires a 256-grayscale bitmap file (*.bmp image file) as data source
% and the following 5 script and function m-files to work:
% ofdm_parameters.m, ofdm_base_convert.m, ofdm_modulate.m,
% ofdm_frame_detect.m, ofdm_demod.m
% ####################################################### %
% ************* OFDM SYSTEM INITIALIZATION: ************* %
% **** setting up parameters & obtaining source data **** %
% ####################################################### %
% Turn off exact-match warning to allow case-insensitive input files warning('off','MATLAB:dispatcher:InexactMatch');
clear all; % clear all previous data in MATLAB workspace close all; % close all previously opened figures and graphs fprintf('\n\n##########################################\n')
fprintf('#*********** OFDM Simulation ************#\n')
fprintf('##########################################\n\n')
% invoking ofdm_parameters.m script to set OFDM system parameters ofdm_parameters;
% save parameters for receiver save('ofdm_parameters');
% read data from input file x = imread(file_in);
% arrange data read from image for OFDM processing h = size(x,1);
w = size(x,2);
x = reshape(x,1,w*h);
baseband_tx = double(x);
% convert original data word size (bits/word) to symbol size (bits/symbol)
% symbol size (bits/symbol) is determined by choice of modulation method baseband_tx = ofdm_base_convert(baseband_tx, word_size, symb_size);
% save original baseband data for error calculation later save('err_calc.mat', 'baseband_tx');
121
% ####################################################### %
% ******************* OFDM TRANSMITTER ****************** %
% ####################################################### %
tic; % start stopwatch
% generate header and trailer (an exact copy of the header)
f = 0.25;
header = sin(0:f*2*pi:f*2*pi*(head_len-1));
f=f/(pi*2/3);
header = header+sin(0:f*2*pi:f*2*pi*(head_len-1));
% arrange data into frames and transmit frame_guard = zeros(1, symb_period);
time_wave_tx = [];
symb_per_carrier = ceil(length(baseband_tx)/carrier_count);
fig = 1;
if (symb_per_carrier > symb_per_frame) % === multiple frames === %
power = 0;
while isempty(baseband_tx)
% number of symbols per frame frame_len = min(symb_per_frame*carrier_count,length(baseband_tx));
frame_data = baseband_tx(1:frame_len);
% update the yet-to-modulate data baseband_tx = baseband_tx((frame_len+1):(length(baseband_tx)));
% OFDM modulation time_signal_tx = ofdm_modulate(frame_data,ifft_size,carriers,...
conj_carriers, carrier_count, symb_size, guard_time, fig);
fig = 0; %indicate that ofdm_modulate() has already generated plots
% add a frame guard to each frame of modulated signal time_wave_tx = [time_wave_tx frame_guard time_signal_tx];
frame_power = var(time_signal_tx);
end
% scale the header to match signal level power = power + frame_power;
% The OFDM modulated signal for transmission time_wave_tx = [power*header time_wave_tx frame_guard power*header];
else % === single frame === %
% OFDM modulation time_signal_tx = ofdm_modulate(baseband_tx,ifft_size,carriers,...
conj_carriers, carrier_count, symb_size, guard_time, fig);
% calculate the signal power to scale the header power = var(time_signal_tx);
% The OFDM modulated signal for transmission time_wave_tx = ...
[power*header frame_guard time_signal_tx frame_guard power*header];
end
% show summary of the OFDM transmission modeling peak = max(abs(time_wave_tx(head_len+1:length(time_wave_tx)-head_len)));
sig_rms = std(time_wave_tx(head_len+1:length(time_wave_tx)-head_len));
peak_rms_ratio = (20*log10(peak/sig_rms));
fprintf('\nSummary of the OFDM transmission and channel modeling:\n')
fprintf('Peak to RMS power ratio at entrance of channel is: %f dB\n', ...
peak_rms_ratio)
122
% ####################################################### %
% **************** COMMUNICATION CHANNEL **************** %
% ####################################################### %
% ===== signal clipping ===== %
clipped_peak = (10^(0-(clipping/20)))*max(abs(time_wave_tx));
time_wave_tx(find(abs(time_wave_tx)>=clipped_peak))...
= clipped_peak.*time_wave_tx(find(abs(time_wave_tx)>=clipped_peak))...
./abs(time_wave_tx(find(abs(time_wave_tx)>=clipped_peak)));
% ===== channel noise ===== %
power = var(time_wave_tx); % Gaussian (AWGN)
SNR_linear = 10^(SNR_dB/10);
noise_factor = sqrt(power/SNR_linear);
noise = randn(1,length(time_wave_tx)) * noise_factor;
time_wave_rx = time_wave_tx + noise;
% show summary of the OFDM channel modeling peak = max(abs(time_wave_rx(head_len+1:length(time_wave_rx)-head_len)));
sig_rms = std(time_wave_rx(head_len+1:length(time_wave_rx)-head_len));
peak_rms_ratio = (20*log10(peak/sig_rms));
fprintf('Peak to RMS power ratio at exit of channel is: %f dB\n', ...
peak_rms_ratio)
% Save the signal to be received save('received.mat', 'time_wave_rx', 'h', 'w');
fprintf('#******** OFDM data transmitted in %f seconds ********#\n\n', toc)
% ####################################################### %
% ********************* OFDM RECEIVER ******************* %
% ####################################################### %
disp('Press any key to let OFDM RECEIVER proceed...')
pause;
clear all; % flush all data stored in memory previously tic; % start stopwatch
% invoking ofdm_parameters.m script to set OFDM system parameters load('ofdm_parameters');
% receive data load('received.mat');
time_wave_rx = time_wave_rx.';
end_x = length(time_wave_rx);
start_x = 1;
data = [];
phase = [];
last_frame = 0;
unpad = 0;
if rem(w*h, carrier_count)=0
unpad = carrier_count - rem(w*h, carrier_count);
end num_frame=ceil((h*w)*(word_size/symb_size)/(symb_per_frame*carrier_count));
fig = 0;
123 for k = 1:num_frame if k==1 || k==num_frame || rem(k,max(floor(num_frame/10),1))==0
fprintf('Demodulating Frame #%d\n',k)
end
% pick appropriate trunks of time signal to detect data frame if k==1
time_wave = time_wave_rx(start_x:min(end_x, ...
(head_len+symb_period*((symb_per_frame+1)/2+1))));
else time_wave = time_wave_rx(start_x:min(end_x, ...
((start_x-1) + (symb_period*((symb_per_frame+1)/2+1)))));
end
% detect the data frame that only contains the useful information frame_start = ...
ofdm_frame_detect(time_wave, symb_period, envelope, start_x);
if k==num_frame last_frame = 1;
frame_end = min(end_x, (frame_start-1) + symb_period*...
(1+ceil(rem(w*h,carrier_count*symb_per_frame)/carrier_count)));
else frame_end=min(frame_start-1+(symb_per_frame+1)*symb_period, end_x);
end
% take the time signal abstracted from this frame to demodulate time_wave = time_wave_rx(frame_start:frame_end);
% update the label for leftover signal start_x = frame_end - symb_period;
if k==ceil(num_frame/2)
fig = 1;
end
% demodulate the received time signal
[data_rx, phase_rx] = ofdm_demod...
(time_wave, ifft_size, carriers, conj_carriers, ...
guard_time, symb_size, word_size, last_frame, unpad, fig);
if fig==1
fig = 0; % indicate that ofdm_demod() has already generated plots end phase = [phase phase_rx];
data = [data data_rx];
end phase_rx = phase; % decoded phase data_rx = data; % received data
% convert symbol size (bits/symbol) to file word size (bits/byte) as needed data_out = ofdm_base_convert(data_rx, symb_size, word_size);
fprintf('#********** OFDM data received in %f seconds *********#\n\n', toc)
% ####################################################### %
% ********************** DATA OUTPUT ******************** %
% ####################################################### %
% patch or trim the data to fit a w-by-h image if length(data_out)>(w*h) % trim extra data data_out = data_out(1:(w*h));
elseif length(data_out)<(w*h) % patch a partially missing row buff_h = h;
h = ceil(length(data_out)/w);
% if one or more rows of pixels are missing, show a message to indicate if h=buff_h disp('WARNING: Output image smaller than original')
disp(' due to data loss in transmission.')
124 end
% to make the patch nearly seamless,
% make each patched pixel the same color as the one right above it if length(data_out)=(w*h)
for k=1:(w*h-length(data_out))
mend(k)=data_out(length(data_out)-w+k);
end data_out = [data_out mend];
end end
% format the demodulated data to reconstruct a bitmap image data_out = reshape(data_out, w, h)';
data_out = uint8(data_out);
% save the output image to a bitmap (*.bmp) file imwrite(data_out, file_out, 'bmp');
% ####################################################### %
% ****************** ERROR CALCULATIONS ***************** %
% ####################################################### %
% collect original data before modulation for error calculations load('err_calc.mat');
fprintf('\n#**************** Summary of Errors ****************#\n')
% Let received and original data match size and calculate data loss rate if length(data_rx)>length(baseband_tx)
data_rx = data_rx(1:length(baseband_tx));
phase_rx = phase_rx(1:length(baseband_tx));
elseif length(data_rx) fprintf('Data loss in this communication = %f%% (%d out of %d)\n', ...
(length(baseband_tx)-length(data_rx))/length(baseband_tx)*100, ...
length(baseband_tx)-length(data_rx), length(baseband_tx))
end
% find errors errors = find(baseband_tx(1:length(data_rx))=data_rx);
fprintf('Total number of errors = %d (out of %d)\n', ...
length(errors), length(data_rx))
% Bit Error Rate fprintf('Bit Error Rate (BER) = %f%%\n',length(errors)/length(data_rx)*100)
% find phase error in degrees and translate to -180 to +180 interval phase_tx = baseband_tx*360/(2^symb_size);
phase_err = (phase_rx - phase_tx(1:length(phase_rx)));
phase_err(find(phase_err>=180)) = phase_err(find(phase_err>=180))-360;
phase_err(find(phase_err<=-180)) = phase_err(find(phase_err<=-180))+360;
fprintf('Average Phase Error = %f (degree)\n', mean(abs(phase_err)))
% Error pixels x = ofdm_base_convert(baseband_tx, symb_size, word_size);
x = uint8(x);
x = x(1:(size(data_out,1)*size(data_out,2)));
y = reshape(data_out', 1, length(x));
err_pix = find(y=x);
fprintf('Percent error of pixels of the received image = %f%%\n\n', ...
length(err_pix)/length(x)*100)
fprintf('##########################################\n')
fprintf('#******** END of OFDM Simulation ********#\n')
125 fprintf('##########################################\n\n')
% ************* PARAMETERS INITIALIZATION ************* %
% This file configures parameters for the OFDM system.
% input/output file names file_in = [];
while isempty(file_in)
file_in = input('source data filename: ', 's');
if exist([pwd '/' file_in],'file')=2
fprintf ...
('"%s" does not exist in current directory.\n', file_in);
file_in = [];
end end file_out = [file_in(1:length(file_in)-4) '_OFDM.bmp'];
disp(['Output file will be: ' file_out])
% size of Inverse Fast Fourier Transform (must be power of 2)
ifft_size = 0.1; % force into the while loop below while (isempty(ifft_size) || ...
(rem(log2(ifft_size),1) = 0 || ifft_size < 8))
ifft_size = input('IFFT size: ');
if (isempty(ifft_size) || ...
(rem(log2(ifft_size),1) = 0 || ifft_size < 8))
disp('IFFT size must be at least 8 and power of 2.')
end end
% number of carriers carrier_count = ifft_size; % force into the while loop below while (isempty(carrier_count) || ...
(carrier_count>(ifft_size/2-2)) || carrier_count<2)
carrier_count = input('Number of carriers: ');
if (isempty(carrier_count) || (carrier_count > (ifft_size/2-2)))
disp('Must NOT be greater than ("IFFT size"/2-2)')
end end
% bits per symbol (1 = BPSK, 2=QPSK, 4=16PSK, 8=256PSK)
symb_size = 0; % force into the while loop below while (isempty(symb_size) || ...
(symb_size=1 && symb_size=2 && symb_size=4 && symb_size=8))
symb_size = input...
('Modulation(1=BPSK, 2=QPSK, 4=16PSK, 8=256PSK): ');
if (isempty(symb_size) || ...
(symb_size=1&&symb_size=2&&symb_size=4&&symb_size=8))
disp('Only 1, 2, 4, or 8 can be choosen')
end end
126
% channel clipping in dB
clipping = [];
while isempty(clipping)
clipping = input('Amplitude clipping introduced by communication channel
(in dB):');
end
% signal to noise ratio in dB
SNR_dB = [];
while isempty(SNR_dB)
SNR_dB = input('Signal-to-Noise Ratio (SNR) in dB: ');
end word_size = 8; % bits per word of source data (byte)
guard_time = ifft_size/4; % length of guard interval for each symbol period
% 25% of ifft_size
% number of symbols per carrier in each frame for transmission symb_per_frame = ceil(2^13/carrier_count);
% === Derived Parameters === %
% frame_len: length of one symbol period including guard time symb_period = ifft_size + guard_time;
% head_len: length of the header and trailer of the transmitted data head_len = symb_period*8;
% envelope: symb_period/envelope is the size of envelope detector envelope = ceil(symb_period/256)+1;
% === carriers assigned to IFFT bins === %
% spacing for carriers distributed in IFFT bins spacing = 0;
while (carrier_count*spacing) <= (ifft_size/2 - 2)
spacing = spacing + 1;
end spacing = spacing - 1;
% spead out carriers into IFFT bins accordingly midFreq = ifft_size/4;
first_carrier = midFreq - round((carrier_count-1)*spacing/2);
last_carrier = midFreq + floor((carrier_count-1)*spacing/2);
carriers = [first_carrier:spacing:last_carrier] + 1;
conj_carriers = ifft_size - carriers + 2;
127
% ************* FUNCTION: ofdm_base_convert() ************* %
% This function converts data from one base to another.
% "Base" refers to number of bits the symbol/word uses to represent data.
function data_out = ofdm_base_convert(data_in, base, new_base)
% if new base is in a higer order than the current base,
% make the size of data in current base a multiple of its new base if new_base>base data_in = data_in(1:...
floor(length(data_in)/(new_base/base))*(new_base/base));
end
% base to binary for k=1:base binary_matrix(k,:) = floor(data_in/2^(base-k));
data_in = rem(data_in,2^(base-k));
end
% format the binary matrix to fit dimensions of the new base newbase_matrix = reshape(binary_matrix, new_base, ...
size(binary_matrix,1)*size(binary_matrix,2)/new_base);
% binary to new_base data_out = zeros(1, size(newbase_matrix,2));
for k=1:new_base data_out = data_out + newbase_matrix(k,:)*(2^(new_base-k));
end
% ************* FUNCTION: ofdm_modulation() ************* %
% This function performance the OFDM modulation before data transmission.
function signal_tx = ofdm_modulate(data_tx, ifft_size, carriers, ...
conj_carriers, carrier_count, symb_size, guard_time, fig)
% symbols per carrier for this frame carrier_symb_count = ceil(length(data_tx)/carrier_count);
% append zeros to data with a length not multiple of number of carriers if length(data_tx)/carrier_count = carrier_symb_count,
padding = zeros(1, carrier_symb_count*carrier_count);
padding(1:length(data_tx)) = data_tx;
data_tx = padding;
end
% serial to parellel: each column represents a carrier data_tx_matrix = reshape(data_tx, carrier_count, carrier_symb_count)';
% --------------------------------- %
% ##### Differential Encoding ##### %
% --------------------------------- %
% an additional row and include reference point carrier_symb_count = size(data_tx_matrix,1) + 1;
1 2 3 4 5 6 7
1
П
од
п.
и
д
ат
а
И
нв
.
д
уб
л
.
В
за
м
.и
нв
.
П
од
п.
и
д
ат
а
42
5
В
ер
но
(
)
Н
.к
он
т
р
.
И
нв
.
по
дл
.
ф.2.106-5
Копировал
Формат А4
П
ер
в.
п
ри
м
ен
.
С
пр
ав
.
(
)
Листов
Примечание
Кол.
Наименование
Поз. обо-
значение
З
о
н
а
Приемопередатчик OFDM
Перечень элементов
ПГУ 1.11.05.01.10EР114
2
1 150 пФ-50В-NPO-1206+/-5%
1 1
2 2
2
С1, C2
С5
С6, С7
С8, С9
С10
С11
С12, С13
С14, С15 2
2
Кравченко
X1
Розетка 34000000-04 1
X2
Розетка СНЦ23-4/18В-1В ГЕ0.364.241ТУ
1
B1
Резонатор кварцевый MC-306 128МГц
В3 1
1
TR2
С21, С22 150 пкФ-50В-NPO-1206+/-5%
2 4
С23... С26 0,1 мкФ-50В-NPO-1206+/-5%
С16...С20 0,1 мкФ-50В-NPO-1206+/-5%
5
Конденсаторы
B2
Резонатор кварцевый HC-49U 4664МГц
Резонатор кварцевый MC-306 128МГц
1 1
1
TR1
Трансформатор четвертьволновый
Трансформатор питания ТП124-5
РК-50-9
C3, С4 0,1 мкФ-50В-NPO-1206+/-5%
2 12 пкФ-50В-NPO-1206+/-5%
0,1 мкФ-50В-NPO-1206+/-5%
10 мкФ-16В-В +/-10% (танталовый)
0,1 мкФ-50В-NPO-1206+/-5%
100 мкФ-16В-Е+/-10% (танталовый)
0,1 мкФ-50В-NPO-1206+/-5%
10 мкФ-16В-В +/-10% (танталовый)
С27... С30 12 пкФ-50В-NPO-1206+/-5%
4
С31, С32 0,1 мкФ-50В-NPO-1206+/-5%
2
117
118
119
ПРИЛОЖЕНИЕ Е
ЛИСТИНГ ПРОГРАММЫ MATLAB
ДЛЯ ПЕРЕДАЧИ И ПРИЕМА ИНФОРМАЦИИ
120
% *************** MAIN PROGRAM FILE *************** %
% This is the OFDM simulation program's main file.
% It requires a 256-grayscale bitmap file (*.bmp image file) as data source
% and the following 5 script and function m-files to work:
% ofdm_parameters.m, ofdm_base_convert.m, ofdm_modulate.m,
% ofdm_frame_detect.m, ofdm_demod.m
% ####################################################### %
% ************* OFDM SYSTEM INITIALIZATION: ************* %
% **** setting up parameters & obtaining source data **** %
% ####################################################### %
% Turn off exact-match warning to allow case-insensitive input files warning('off','MATLAB:dispatcher:InexactMatch');
clear all; % clear all previous data in MATLAB workspace close all; % close all previously opened figures and graphs fprintf('\n\n##########################################\n')
fprintf('#*********** OFDM Simulation ************#\n')
fprintf('##########################################\n\n')
% invoking ofdm_parameters.m script to set OFDM system parameters ofdm_parameters;
% save parameters for receiver save('ofdm_parameters');
% read data from input file x = imread(file_in);
% arrange data read from image for OFDM processing h = size(x,1);
w = size(x,2);
x = reshape(x,1,w*h);
baseband_tx = double(x);
% convert original data word size (bits/word) to symbol size (bits/symbol)
% symbol size (bits/symbol) is determined by choice of modulation method baseband_tx = ofdm_base_convert(baseband_tx, word_size, symb_size);
% save original baseband data for error calculation later save('err_calc.mat', 'baseband_tx');
121
% ####################################################### %
% ******************* OFDM TRANSMITTER ****************** %
% ####################################################### %
tic; % start stopwatch
% generate header and trailer (an exact copy of the header)
f = 0.25;
header = sin(0:f*2*pi:f*2*pi*(head_len-1));
f=f/(pi*2/3);
header = header+sin(0:f*2*pi:f*2*pi*(head_len-1));
% arrange data into frames and transmit frame_guard = zeros(1, symb_period);
time_wave_tx = [];
symb_per_carrier = ceil(length(baseband_tx)/carrier_count);
fig = 1;
if (symb_per_carrier > symb_per_frame) % === multiple frames === %
power = 0;
while isempty(baseband_tx)
% number of symbols per frame frame_len = min(symb_per_frame*carrier_count,length(baseband_tx));
frame_data = baseband_tx(1:frame_len);
% update the yet-to-modulate data baseband_tx = baseband_tx((frame_len+1):(length(baseband_tx)));
% OFDM modulation time_signal_tx = ofdm_modulate(frame_data,ifft_size,carriers,...
conj_carriers, carrier_count, symb_size, guard_time, fig);
fig = 0; %indicate that ofdm_modulate() has already generated plots
% add a frame guard to each frame of modulated signal time_wave_tx = [time_wave_tx frame_guard time_signal_tx];
frame_power = var(time_signal_tx);
end
% scale the header to match signal level power = power + frame_power;
% The OFDM modulated signal for transmission time_wave_tx = [power*header time_wave_tx frame_guard power*header];
else % === single frame === %
% OFDM modulation time_signal_tx = ofdm_modulate(baseband_tx,ifft_size,carriers,...
conj_carriers, carrier_count, symb_size, guard_time, fig);
% calculate the signal power to scale the header power = var(time_signal_tx);
% The OFDM modulated signal for transmission time_wave_tx = ...
[power*header frame_guard time_signal_tx frame_guard power*header];
end
% show summary of the OFDM transmission modeling peak = max(abs(time_wave_tx(head_len+1:length(time_wave_tx)-head_len)));
sig_rms = std(time_wave_tx(head_len+1:length(time_wave_tx)-head_len));
peak_rms_ratio = (20*log10(peak/sig_rms));
fprintf('\nSummary of the OFDM transmission and channel modeling:\n')
fprintf('Peak to RMS power ratio at entrance of channel is: %f dB\n', ...
peak_rms_ratio)
122
% ####################################################### %
% **************** COMMUNICATION CHANNEL **************** %
% ####################################################### %
% ===== signal clipping ===== %
clipped_peak = (10^(0-(clipping/20)))*max(abs(time_wave_tx));
time_wave_tx(find(abs(time_wave_tx)>=clipped_peak))...
= clipped_peak.*time_wave_tx(find(abs(time_wave_tx)>=clipped_peak))...
./abs(time_wave_tx(find(abs(time_wave_tx)>=clipped_peak)));
% ===== channel noise ===== %
power = var(time_wave_tx); % Gaussian (AWGN)
SNR_linear = 10^(SNR_dB/10);
noise_factor = sqrt(power/SNR_linear);
noise = randn(1,length(time_wave_tx)) * noise_factor;
time_wave_rx = time_wave_tx + noise;
% show summary of the OFDM channel modeling peak = max(abs(time_wave_rx(head_len+1:length(time_wave_rx)-head_len)));
sig_rms = std(time_wave_rx(head_len+1:length(time_wave_rx)-head_len));
peak_rms_ratio = (20*log10(peak/sig_rms));
fprintf('Peak to RMS power ratio at exit of channel is: %f dB\n', ...
peak_rms_ratio)
% Save the signal to be received save('received.mat', 'time_wave_rx', 'h', 'w');
fprintf('#******** OFDM data transmitted in %f seconds ********#\n\n', toc)
% ####################################################### %
% ********************* OFDM RECEIVER ******************* %
% ####################################################### %
disp('Press any key to let OFDM RECEIVER proceed...')
pause;
clear all; % flush all data stored in memory previously tic; % start stopwatch
% invoking ofdm_parameters.m script to set OFDM system parameters load('ofdm_parameters');
% receive data load('received.mat');
time_wave_rx = time_wave_rx.';
end_x = length(time_wave_rx);
start_x = 1;
data = [];
phase = [];
last_frame = 0;
unpad = 0;
if rem(w*h, carrier_count)=0
unpad = carrier_count - rem(w*h, carrier_count);
end num_frame=ceil((h*w)*(word_size/symb_size)/(symb_per_frame*carrier_count));
fig = 0;
123 for k = 1:num_frame if k==1 || k==num_frame || rem(k,max(floor(num_frame/10),1))==0
fprintf('Demodulating Frame #%d\n',k)
end
% pick appropriate trunks of time signal to detect data frame if k==1
time_wave = time_wave_rx(start_x:min(end_x, ...
(head_len+symb_period*((symb_per_frame+1)/2+1))));
else time_wave = time_wave_rx(start_x:min(end_x, ...
((start_x-1) + (symb_period*((symb_per_frame+1)/2+1)))));
end
% detect the data frame that only contains the useful information frame_start = ...
ofdm_frame_detect(time_wave, symb_period, envelope, start_x);
if k==num_frame last_frame = 1;
frame_end = min(end_x, (frame_start-1) + symb_period*...
(1+ceil(rem(w*h,carrier_count*symb_per_frame)/carrier_count)));
else frame_end=min(frame_start-1+(symb_per_frame+1)*symb_period, end_x);
end
% take the time signal abstracted from this frame to demodulate time_wave = time_wave_rx(frame_start:frame_end);
% update the label for leftover signal start_x = frame_end - symb_period;
if k==ceil(num_frame/2)
fig = 1;
end
% demodulate the received time signal
[data_rx, phase_rx] = ofdm_demod...
(time_wave, ifft_size, carriers, conj_carriers, ...
guard_time, symb_size, word_size, last_frame, unpad, fig);
if fig==1
fig = 0; % indicate that ofdm_demod() has already generated plots end phase = [phase phase_rx];
data = [data data_rx];
end phase_rx = phase; % decoded phase data_rx = data; % received data
% convert symbol size (bits/symbol) to file word size (bits/byte) as needed data_out = ofdm_base_convert(data_rx, symb_size, word_size);
fprintf('#********** OFDM data received in %f seconds *********#\n\n', toc)
% ####################################################### %
% ********************** DATA OUTPUT ******************** %
% ####################################################### %
% patch or trim the data to fit a w-by-h image if length(data_out)>(w*h) % trim extra data data_out = data_out(1:(w*h));
elseif length(data_out)<(w*h) % patch a partially missing row buff_h = h;
h = ceil(length(data_out)/w);
% if one or more rows of pixels are missing, show a message to indicate if h=buff_h disp('WARNING: Output image smaller than original')
disp(' due to data loss in transmission.')
124 end
% to make the patch nearly seamless,
% make each patched pixel the same color as the one right above it if length(data_out)=(w*h)
for k=1:(w*h-length(data_out))
mend(k)=data_out(length(data_out)-w+k);
end data_out = [data_out mend];
end end
% format the demodulated data to reconstruct a bitmap image data_out = reshape(data_out, w, h)';
data_out = uint8(data_out);
% save the output image to a bitmap (*.bmp) file imwrite(data_out, file_out, 'bmp');
% ####################################################### %
% ****************** ERROR CALCULATIONS ***************** %
% ####################################################### %
% collect original data before modulation for error calculations load('err_calc.mat');
fprintf('\n#**************** Summary of Errors ****************#\n')
% Let received and original data match size and calculate data loss rate if length(data_rx)>length(baseband_tx)
data_rx = data_rx(1:length(baseband_tx));
phase_rx = phase_rx(1:length(baseband_tx));
elseif length(data_rx) fprintf('Data loss in this communication = %f%% (%d out of %d)\n', ...
(length(baseband_tx)-length(data_rx))/length(baseband_tx)*100, ...
length(baseband_tx)-length(data_rx), length(baseband_tx))
end
% find errors errors = find(baseband_tx(1:length(data_rx))=data_rx);
fprintf('Total number of errors = %d (out of %d)\n', ...
length(errors), length(data_rx))
% Bit Error Rate fprintf('Bit Error Rate (BER) = %f%%\n',length(errors)/length(data_rx)*100)
% find phase error in degrees and translate to -180 to +180 interval phase_tx = baseband_tx*360/(2^symb_size);
phase_err = (phase_rx - phase_tx(1:length(phase_rx)));
phase_err(find(phase_err>=180)) = phase_err(find(phase_err>=180))-360;
phase_err(find(phase_err<=-180)) = phase_err(find(phase_err<=-180))+360;
fprintf('Average Phase Error = %f (degree)\n', mean(abs(phase_err)))
% Error pixels x = ofdm_base_convert(baseband_tx, symb_size, word_size);
x = uint8(x);
x = x(1:(size(data_out,1)*size(data_out,2)));
y = reshape(data_out', 1, length(x));
err_pix = find(y=x);
fprintf('Percent error of pixels of the received image = %f%%\n\n', ...
length(err_pix)/length(x)*100)
fprintf('##########################################\n')
fprintf('#******** END of OFDM Simulation ********#\n')
125 fprintf('##########################################\n\n')
% ************* PARAMETERS INITIALIZATION ************* %
% This file configures parameters for the OFDM system.
% input/output file names file_in = [];
while isempty(file_in)
file_in = input('source data filename: ', 's');
if exist([pwd '/' file_in],'file')=2
fprintf ...
('"%s" does not exist in current directory.\n', file_in);
file_in = [];
end end file_out = [file_in(1:length(file_in)-4) '_OFDM.bmp'];
disp(['Output file will be: ' file_out])
% size of Inverse Fast Fourier Transform (must be power of 2)
ifft_size = 0.1; % force into the while loop below while (isempty(ifft_size) || ...
(rem(log2(ifft_size),1) = 0 || ifft_size < 8))
ifft_size = input('IFFT size: ');
if (isempty(ifft_size) || ...
(rem(log2(ifft_size),1) = 0 || ifft_size < 8))
disp('IFFT size must be at least 8 and power of 2.')
end end
% number of carriers carrier_count = ifft_size; % force into the while loop below while (isempty(carrier_count) || ...
(carrier_count>(ifft_size/2-2)) || carrier_count<2)
carrier_count = input('Number of carriers: ');
if (isempty(carrier_count) || (carrier_count > (ifft_size/2-2)))
disp('Must NOT be greater than ("IFFT size"/2-2)')
end end
% bits per symbol (1 = BPSK, 2=QPSK, 4=16PSK, 8=256PSK)
symb_size = 0; % force into the while loop below while (isempty(symb_size) || ...
(symb_size=1 && symb_size=2 && symb_size=4 && symb_size=8))
symb_size = input...
('Modulation(1=BPSK, 2=QPSK, 4=16PSK, 8=256PSK): ');
if (isempty(symb_size) || ...
(symb_size=1&&symb_size=2&&symb_size=4&&symb_size=8))
disp('Only 1, 2, 4, or 8 can be choosen')
end end
126
% channel clipping in dB
clipping = [];
while isempty(clipping)
clipping = input('Amplitude clipping introduced by communication channel
(in dB):');
end
% signal to noise ratio in dB
SNR_dB = [];
while isempty(SNR_dB)
SNR_dB = input('Signal-to-Noise Ratio (SNR) in dB: ');
end word_size = 8; % bits per word of source data (byte)
guard_time = ifft_size/4; % length of guard interval for each symbol period
% 25% of ifft_size
% number of symbols per carrier in each frame for transmission symb_per_frame = ceil(2^13/carrier_count);
% === Derived Parameters === %
% frame_len: length of one symbol period including guard time symb_period = ifft_size + guard_time;
% head_len: length of the header and trailer of the transmitted data head_len = symb_period*8;
% envelope: symb_period/envelope is the size of envelope detector envelope = ceil(symb_period/256)+1;
% === carriers assigned to IFFT bins === %
% spacing for carriers distributed in IFFT bins spacing = 0;
while (carrier_count*spacing) <= (ifft_size/2 - 2)
spacing = spacing + 1;
end spacing = spacing - 1;
% spead out carriers into IFFT bins accordingly midFreq = ifft_size/4;
first_carrier = midFreq - round((carrier_count-1)*spacing/2);
last_carrier = midFreq + floor((carrier_count-1)*spacing/2);
carriers = [first_carrier:spacing:last_carrier] + 1;
conj_carriers = ifft_size - carriers + 2;
127
% ************* FUNCTION: ofdm_base_convert() ************* %
% This function converts data from one base to another.
% "Base" refers to number of bits the symbol/word uses to represent data.
function data_out = ofdm_base_convert(data_in, base, new_base)
% if new base is in a higer order than the current base,
% make the size of data in current base a multiple of its new base if new_base>base data_in = data_in(1:...
floor(length(data_in)/(new_base/base))*(new_base/base));
end
% base to binary for k=1:base binary_matrix(k,:) = floor(data_in/2^(base-k));
data_in = rem(data_in,2^(base-k));
end
% format the binary matrix to fit dimensions of the new base newbase_matrix = reshape(binary_matrix, new_base, ...
size(binary_matrix,1)*size(binary_matrix,2)/new_base);
% binary to new_base data_out = zeros(1, size(newbase_matrix,2));
for k=1:new_base data_out = data_out + newbase_matrix(k,:)*(2^(new_base-k));
end
% ************* FUNCTION: ofdm_modulation() ************* %
% This function performance the OFDM modulation before data transmission.
function signal_tx = ofdm_modulate(data_tx, ifft_size, carriers, ...
conj_carriers, carrier_count, symb_size, guard_time, fig)
% symbols per carrier for this frame carrier_symb_count = ceil(length(data_tx)/carrier_count);
% append zeros to data with a length not multiple of number of carriers if length(data_tx)/carrier_count = carrier_symb_count,
padding = zeros(1, carrier_symb_count*carrier_count);
padding(1:length(data_tx)) = data_tx;
data_tx = padding;
end
% serial to parellel: each column represents a carrier data_tx_matrix = reshape(data_tx, carrier_count, carrier_symb_count)';
% --------------------------------- %
% ##### Differential Encoding ##### %
% --------------------------------- %
% an additional row and include reference point carrier_symb_count = size(data_tx_matrix,1) + 1;
1 2 3 4 5 6 7
1
П
од
п.
и
д
ат
а
И
нв
.
д
уб
л
.
В
за
м
.и
нв
.
П
од
п.
и
д
ат
а
42
5
В
ер
но
(
)
Н
.к
он
т
р
.
И
нв
.
по
дл
.
ф.2.106-5
Копировал
Формат А4
П
ер
в.
п
ри
м
ен
.
С
пр
ав
.
(
)
Листов
Примечание
Кол.
Наименование
Поз. обо-
значение
З
о
н
а
Приемопередатчик OFDM
Перечень элементов
ПГУ 1.11.05.01.10EР114
2
1 150 пФ-50В-NPO-1206+/-5%
1 1
2 2
2
С1, C2
С5
С6, С7
С8, С9
С10
С11
С12, С13
С14, С15 2
2
Кравченко
X1
Розетка 34000000-04 1
X2
Розетка СНЦ23-4/18В-1В ГЕ0.364.241ТУ
1
B1
Резонатор кварцевый MC-306 128МГц
В3 1
1
TR2
С21, С22 150 пкФ-50В-NPO-1206+/-5%
2 4
С23... С26 0,1 мкФ-50В-NPO-1206+/-5%
С16...С20 0,1 мкФ-50В-NPO-1206+/-5%
5
Конденсаторы
B2
Резонатор кварцевый HC-49U 4664МГц
Резонатор кварцевый MC-306 128МГц
1 1
1
TR1
Трансформатор четвертьволновый
Трансформатор питания ТП124-5
РК-50-9
C3, С4 0,1 мкФ-50В-NPO-1206+/-5%
2 12 пкФ-50В-NPO-1206+/-5%
0,1 мкФ-50В-NPO-1206+/-5%
10 мкФ-16В-В +/-10% (танталовый)
0,1 мкФ-50В-NPO-1206+/-5%
100 мкФ-16В-Е+/-10% (танталовый)
0,1 мкФ-50В-NPO-1206+/-5%
10 мкФ-16В-В +/-10% (танталовый)
С27... С30 12 пкФ-50В-NPO-1206+/-5%
4
С31, С32 0,1 мкФ-50В-NPO-1206+/-5%
2
117
118
119
ПРИЛОЖЕНИЕ Е
ЛИСТИНГ ПРОГРАММЫ MATLAB
ДЛЯ ПЕРЕДАЧИ И ПРИЕМА ИНФОРМАЦИИ
120
% *************** MAIN PROGRAM FILE *************** %
% This is the OFDM simulation program's main file.
% It requires a 256-grayscale bitmap file (*.bmp image file) as data source
% and the following 5 script and function m-files to work:
% ofdm_parameters.m, ofdm_base_convert.m, ofdm_modulate.m,
% ofdm_frame_detect.m, ofdm_demod.m
% ####################################################### %
% ************* OFDM SYSTEM INITIALIZATION: ************* %
% **** setting up parameters & obtaining source data **** %
% ####################################################### %
% Turn off exact-match warning to allow case-insensitive input files warning('off','MATLAB:dispatcher:InexactMatch');
clear all; % clear all previous data in MATLAB workspace close all; % close all previously opened figures and graphs fprintf('\n\n##########################################\n')
fprintf('#*********** OFDM Simulation ************#\n')
fprintf('##########################################\n\n')
% invoking ofdm_parameters.m script to set OFDM system parameters ofdm_parameters;
% save parameters for receiver save('ofdm_parameters');
% read data from input file x = imread(file_in);
% arrange data read from image for OFDM processing h = size(x,1);
w = size(x,2);
x = reshape(x,1,w*h);
baseband_tx = double(x);
% convert original data word size (bits/word) to symbol size (bits/symbol)
% symbol size (bits/symbol) is determined by choice of modulation method baseband_tx = ofdm_base_convert(baseband_tx, word_size, symb_size);
% save original baseband data for error calculation later save('err_calc.mat', 'baseband_tx');
121
% ####################################################### %
% ******************* OFDM TRANSMITTER ****************** %
% ####################################################### %
tic; % start stopwatch
% generate header and trailer (an exact copy of the header)
f = 0.25;
header = sin(0:f*2*pi:f*2*pi*(head_len-1));
f=f/(pi*2/3);
header = header+sin(0:f*2*pi:f*2*pi*(head_len-1));
% arrange data into frames and transmit frame_guard = zeros(1, symb_period);
time_wave_tx = [];
symb_per_carrier = ceil(length(baseband_tx)/carrier_count);
fig = 1;
if (symb_per_carrier > symb_per_frame) % === multiple frames === %
power = 0;
while isempty(baseband_tx)
% number of symbols per frame frame_len = min(symb_per_frame*carrier_count,length(baseband_tx));
frame_data = baseband_tx(1:frame_len);
% update the yet-to-modulate data baseband_tx = baseband_tx((frame_len+1):(length(baseband_tx)));
% OFDM modulation time_signal_tx = ofdm_modulate(frame_data,ifft_size,carriers,...
conj_carriers, carrier_count, symb_size, guard_time, fig);
fig = 0; %indicate that ofdm_modulate() has already generated plots
% add a frame guard to each frame of modulated signal time_wave_tx = [time_wave_tx frame_guard time_signal_tx];
frame_power = var(time_signal_tx);
end
% scale the header to match signal level power = power + frame_power;
% The OFDM modulated signal for transmission time_wave_tx = [power*header time_wave_tx frame_guard power*header];
else % === single frame === %
% OFDM modulation time_signal_tx = ofdm_modulate(baseband_tx,ifft_size,carriers,...
conj_carriers, carrier_count, symb_size, guard_time, fig);
% calculate the signal power to scale the header power = var(time_signal_tx);
% The OFDM modulated signal for transmission time_wave_tx = ...
[power*header frame_guard time_signal_tx frame_guard power*header];
end
% show summary of the OFDM transmission modeling peak = max(abs(time_wave_tx(head_len+1:length(time_wave_tx)-head_len)));
sig_rms = std(time_wave_tx(head_len+1:length(time_wave_tx)-head_len));
peak_rms_ratio = (20*log10(peak/sig_rms));
fprintf('\nSummary of the OFDM transmission and channel modeling:\n')
fprintf('Peak to RMS power ratio at entrance of channel is: %f dB\n', ...
peak_rms_ratio)
122
% ####################################################### %
% **************** COMMUNICATION CHANNEL **************** %
% ####################################################### %
% ===== signal clipping ===== %
clipped_peak = (10^(0-(clipping/20)))*max(abs(time_wave_tx));
time_wave_tx(find(abs(time_wave_tx)>=clipped_peak))...
= clipped_peak.*time_wave_tx(find(abs(time_wave_tx)>=clipped_peak))...
./abs(time_wave_tx(find(abs(time_wave_tx)>=clipped_peak)));
% ===== channel noise ===== %
power = var(time_wave_tx); % Gaussian (AWGN)
SNR_linear = 10^(SNR_dB/10);
noise_factor = sqrt(power/SNR_linear);
noise = randn(1,length(time_wave_tx)) * noise_factor;
time_wave_rx = time_wave_tx + noise;
% show summary of the OFDM channel modeling peak = max(abs(time_wave_rx(head_len+1:length(time_wave_rx)-head_len)));
sig_rms = std(time_wave_rx(head_len+1:length(time_wave_rx)-head_len));
peak_rms_ratio = (20*log10(peak/sig_rms));
fprintf('Peak to RMS power ratio at exit of channel is: %f dB\n', ...
peak_rms_ratio)
% Save the signal to be received save('received.mat', 'time_wave_rx', 'h', 'w');
fprintf('#******** OFDM data transmitted in %f seconds ********#\n\n', toc)
% ####################################################### %
% ********************* OFDM RECEIVER ******************* %
% ####################################################### %
disp('Press any key to let OFDM RECEIVER proceed...')
pause;
clear all; % flush all data stored in memory previously tic; % start stopwatch
% invoking ofdm_parameters.m script to set OFDM system parameters load('ofdm_parameters');
% receive data load('received.mat');
time_wave_rx = time_wave_rx.';
end_x = length(time_wave_rx);
start_x = 1;
data = [];
phase = [];
last_frame = 0;
unpad = 0;
if rem(w*h, carrier_count)=0
unpad = carrier_count - rem(w*h, carrier_count);
end num_frame=ceil((h*w)*(word_size/symb_size)/(symb_per_frame*carrier_count));
fig = 0;
123 for k = 1:num_frame if k==1 || k==num_frame || rem(k,max(floor(num_frame/10),1))==0
fprintf('Demodulating Frame #%d\n',k)
end
% pick appropriate trunks of time signal to detect data frame if k==1
time_wave = time_wave_rx(start_x:min(end_x, ...
(head_len+symb_period*((symb_per_frame+1)/2+1))));
else time_wave = time_wave_rx(start_x:min(end_x, ...
((start_x-1) + (symb_period*((symb_per_frame+1)/2+1)))));
end
% detect the data frame that only contains the useful information frame_start = ...
ofdm_frame_detect(time_wave, symb_period, envelope, start_x);
if k==num_frame last_frame = 1;
frame_end = min(end_x, (frame_start-1) + symb_period*...
(1+ceil(rem(w*h,carrier_count*symb_per_frame)/carrier_count)));
else frame_end=min(frame_start-1+(symb_per_frame+1)*symb_period, end_x);
end
% take the time signal abstracted from this frame to demodulate time_wave = time_wave_rx(frame_start:frame_end);
% update the label for leftover signal start_x = frame_end - symb_period;
if k==ceil(num_frame/2)
fig = 1;
end
% demodulate the received time signal
[data_rx, phase_rx] = ofdm_demod...
(time_wave, ifft_size, carriers, conj_carriers, ...
guard_time, symb_size, word_size, last_frame, unpad, fig);
if fig==1
fig = 0; % indicate that ofdm_demod() has already generated plots end phase = [phase phase_rx];
data = [data data_rx];
end phase_rx = phase; % decoded phase data_rx = data; % received data
% convert symbol size (bits/symbol) to file word size (bits/byte) as needed data_out = ofdm_base_convert(data_rx, symb_size, word_size);
fprintf('#********** OFDM data received in %f seconds *********#\n\n', toc)
% ####################################################### %
% ********************** DATA OUTPUT ******************** %
% ####################################################### %
% patch or trim the data to fit a w-by-h image if length(data_out)>(w*h) % trim extra data data_out = data_out(1:(w*h));
elseif length(data_out)<(w*h) % patch a partially missing row buff_h = h;
h = ceil(length(data_out)/w);
% if one or more rows of pixels are missing, show a message to indicate if h=buff_h disp('WARNING: Output image smaller than original')
disp(' due to data loss in transmission.')
124 end
% to make the patch nearly seamless,
% make each patched pixel the same color as the one right above it if length(data_out)=(w*h)
for k=1:(w*h-length(data_out))
mend(k)=data_out(length(data_out)-w+k);
end data_out = [data_out mend];
end end
% format the demodulated data to reconstruct a bitmap image data_out = reshape(data_out, w, h)';
data_out = uint8(data_out);
% save the output image to a bitmap (*.bmp) file imwrite(data_out, file_out, 'bmp');
% ####################################################### %
% ****************** ERROR CALCULATIONS ***************** %
% ####################################################### %
% collect original data before modulation for error calculations load('err_calc.mat');
fprintf('\n#**************** Summary of Errors ****************#\n')
% Let received and original data match size and calculate data loss rate if length(data_rx)>length(baseband_tx)
data_rx = data_rx(1:length(baseband_tx));
phase_rx = phase_rx(1:length(baseband_tx));
elseif length(data_rx) fprintf('Data loss in this communication = %f%% (%d out of %d)\n', ...
(length(baseband_tx)-length(data_rx))/length(baseband_tx)*100, ...
length(baseband_tx)-length(data_rx), length(baseband_tx))
end
% find errors errors = find(baseband_tx(1:length(data_rx))=data_rx);
fprintf('Total number of errors = %d (out of %d)\n', ...
length(errors), length(data_rx))
% Bit Error Rate fprintf('Bit Error Rate (BER) = %f%%\n',length(errors)/length(data_rx)*100)
% find phase error in degrees and translate to -180 to +180 interval phase_tx = baseband_tx*360/(2^symb_size);
phase_err = (phase_rx - phase_tx(1:length(phase_rx)));
phase_err(find(phase_err>=180)) = phase_err(find(phase_err>=180))-360;
phase_err(find(phase_err<=-180)) = phase_err(find(phase_err<=-180))+360;
fprintf('Average Phase Error = %f (degree)\n', mean(abs(phase_err)))
% Error pixels x = ofdm_base_convert(baseband_tx, symb_size, word_size);
x = uint8(x);
x = x(1:(size(data_out,1)*size(data_out,2)));
y = reshape(data_out', 1, length(x));
err_pix = find(y=x);
fprintf('Percent error of pixels of the received image = %f%%\n\n', ...
length(err_pix)/length(x)*100)
fprintf('##########################################\n')
fprintf('#******** END of OFDM Simulation ********#\n')
125 fprintf('##########################################\n\n')
% ************* PARAMETERS INITIALIZATION ************* %
% This file configures parameters for the OFDM system.
% input/output file names file_in = [];
while isempty(file_in)
file_in = input('source data filename: ', 's');
if exist([pwd '/' file_in],'file')=2
fprintf ...
('"%s" does not exist in current directory.\n', file_in);
file_in = [];
end end file_out = [file_in(1:length(file_in)-4) '_OFDM.bmp'];
disp(['Output file will be: ' file_out])
% size of Inverse Fast Fourier Transform (must be power of 2)
ifft_size = 0.1; % force into the while loop below while (isempty(ifft_size) || ...
(rem(log2(ifft_size),1) = 0 || ifft_size < 8))
ifft_size = input('IFFT size: ');
if (isempty(ifft_size) || ...
(rem(log2(ifft_size),1) = 0 || ifft_size < 8))
disp('IFFT size must be at least 8 and power of 2.')
end end
% number of carriers carrier_count = ifft_size; % force into the while loop below while (isempty(carrier_count) || ...
(carrier_count>(ifft_size/2-2)) || carrier_count<2)
carrier_count = input('Number of carriers: ');
if (isempty(carrier_count) || (carrier_count > (ifft_size/2-2)))
disp('Must NOT be greater than ("IFFT size"/2-2)')
end end
% bits per symbol (1 = BPSK, 2=QPSK, 4=16PSK, 8=256PSK)
symb_size = 0; % force into the while loop below while (isempty(symb_size) || ...
(symb_size=1 && symb_size=2 && symb_size=4 && symb_size=8))
symb_size = input...
('Modulation(1=BPSK, 2=QPSK, 4=16PSK, 8=256PSK): ');
if (isempty(symb_size) || ...
(symb_size=1&&symb_size=2&&symb_size=4&&symb_size=8))
disp('Only 1, 2, 4, or 8 can be choosen')
end end
126
% channel clipping in dB
clipping = [];
while isempty(clipping)
clipping = input('Amplitude clipping introduced by communication channel
(in dB):');
end
% signal to noise ratio in dB
SNR_dB = [];
while isempty(SNR_dB)
SNR_dB = input('Signal-to-Noise Ratio (SNR) in dB: ');
end word_size = 8; % bits per word of source data (byte)
guard_time = ifft_size/4; % length of guard interval for each symbol period
% 25% of ifft_size
% number of symbols per carrier in each frame for transmission symb_per_frame = ceil(2^13/carrier_count);
% === Derived Parameters === %
% frame_len: length of one symbol period including guard time symb_period = ifft_size + guard_time;
% head_len: length of the header and trailer of the transmitted data head_len = symb_period*8;
% envelope: symb_period/envelope is the size of envelope detector envelope = ceil(symb_period/256)+1;
% === carriers assigned to IFFT bins === %
% spacing for carriers distributed in IFFT bins spacing = 0;
while (carrier_count*spacing) <= (ifft_size/2 - 2)
spacing = spacing + 1;
end spacing = spacing - 1;
% spead out carriers into IFFT bins accordingly midFreq = ifft_size/4;
first_carrier = midFreq - round((carrier_count-1)*spacing/2);
last_carrier = midFreq + floor((carrier_count-1)*spacing/2);
carriers = [first_carrier:spacing:last_carrier] + 1;
conj_carriers = ifft_size - carriers + 2;
127
% ************* FUNCTION: ofdm_base_convert() ************* %
% This function converts data from one base to another.
% "Base" refers to number of bits the symbol/word uses to represent data.
function data_out = ofdm_base_convert(data_in, base, new_base)
% if new base is in a higer order than the current base,
% make the size of data in current base a multiple of its new base if new_base>base data_in = data_in(1:...
floor(length(data_in)/(new_base/base))*(new_base/base));
end
% base to binary for k=1:base binary_matrix(k,:) = floor(data_in/2^(base-k));
data_in = rem(data_in,2^(base-k));
end
% format the binary matrix to fit dimensions of the new base newbase_matrix = reshape(binary_matrix, new_base, ...
size(binary_matrix,1)*size(binary_matrix,2)/new_base);
% binary to new_base data_out = zeros(1, size(newbase_matrix,2));
for k=1:new_base data_out = data_out + newbase_matrix(k,:)*(2^(new_base-k));
end
% ************* FUNCTION: ofdm_modulation() ************* %
% This function performance the OFDM modulation before data transmission.
function signal_tx = ofdm_modulate(data_tx, ifft_size, carriers, ...
conj_carriers, carrier_count, symb_size, guard_time, fig)
% symbols per carrier for this frame carrier_symb_count = ceil(length(data_tx)/carrier_count);
% append zeros to data with a length not multiple of number of carriers if length(data_tx)/carrier_count = carrier_symb_count,
padding = zeros(1, carrier_symb_count*carrier_count);
padding(1:length(data_tx)) = data_tx;
data_tx = padding;
end
% serial to parellel: each column represents a carrier data_tx_matrix = reshape(data_tx, carrier_count, carrier_symb_count)';
% --------------------------------- %
% ##### Differential Encoding ##### %
% --------------------------------- %
% an additional row and include reference point carrier_symb_count = size(data_tx_matrix,1) + 1;
1 2 3 4 5 6 7
1
П
од
п.
и
д
ат
а
И
нв
.
д
уб
л
.
В
за
м
.и
нв
.
П
од
п.
и
д
ат
а
42
5
В
ер
но
(
)
Н
.к
он
т
р
.
И
нв
.
по
дл
.
ф.2.106-5
Копировал
Формат А4
П
ер
в.
п
ри
м
ен
.
С
пр
ав
.
(
)
Листов
Примечание
Кол.
Наименование
Поз. обо-
значение
З
о
н
а
Приемопередатчик OFDM
Перечень элементов
ПГУ 1.11.05.01.10EР114
2
1 150 пФ-50В-NPO-1206+/-5%
1 1
2 2
2
С1, C2
С5
С6, С7
С8, С9
С10
С11
С12, С13
С14, С15 2
2
Кравченко
X1
Розетка 34000000-04 1
X2
Розетка СНЦ23-4/18В-1В ГЕ0.364.241ТУ
1
B1
Резонатор кварцевый MC-306 128МГц
В3 1
1
TR2
С21, С22 150 пкФ-50В-NPO-1206+/-5%
2 4
С23... С26 0,1 мкФ-50В-NPO-1206+/-5%
С16...С20 0,1 мкФ-50В-NPO-1206+/-5%
5
Конденсаторы
B2
Резонатор кварцевый HC-49U 4664МГц
Резонатор кварцевый MC-306 128МГц
1 1
1
TR1
Трансформатор четвертьволновый
Трансформатор питания ТП124-5
РК-50-9
C3, С4 0,1 мкФ-50В-NPO-1206+/-5%
2 12 пкФ-50В-NPO-1206+/-5%
0,1 мкФ-50В-NPO-1206+/-5%
10 мкФ-16В-В +/-10% (танталовый)
0,1 мкФ-50В-NPO-1206+/-5%
100 мкФ-16В-Е+/-10% (танталовый)
0,1 мкФ-50В-NPO-1206+/-5%
10 мкФ-16В-В +/-10% (танталовый)
С27... С30 12 пкФ-50В-NPO-1206+/-5%
4
С31, С32 0,1 мкФ-50В-NPO-1206+/-5%
2
117
118
119
ПРИЛОЖЕНИЕ Е
ЛИСТИНГ ПРОГРАММЫ MATLAB
ДЛЯ ПЕРЕДАЧИ И ПРИЕМА ИНФОРМАЦИИ
120
% *************** MAIN PROGRAM FILE *************** %
% This is the OFDM simulation program's main file.
% It requires a 256-grayscale bitmap file (*.bmp image file) as data source
% and the following 5 script and function m-files to work:
% ofdm_parameters.m, ofdm_base_convert.m, ofdm_modulate.m,
% ofdm_frame_detect.m, ofdm_demod.m
% ####################################################### %
% ************* OFDM SYSTEM INITIALIZATION: ************* %
% **** setting up parameters & obtaining source data **** %
% ####################################################### %
% Turn off exact-match warning to allow case-insensitive input files warning('off','MATLAB:dispatcher:InexactMatch');
clear all; % clear all previous data in MATLAB workspace close all; % close all previously opened figures and graphs fprintf('\n\n##########################################\n')
fprintf('#*********** OFDM Simulation ************#\n')
fprintf('##########################################\n\n')
% invoking ofdm_parameters.m script to set OFDM system parameters ofdm_parameters;
% save parameters for receiver save('ofdm_parameters');
% read data from input file x = imread(file_in);
% arrange data read from image for OFDM processing h = size(x,1);
w = size(x,2);
x = reshape(x,1,w*h);
baseband_tx = double(x);
% convert original data word size (bits/word) to symbol size (bits/symbol)
% symbol size (bits/symbol) is determined by choice of modulation method baseband_tx = ofdm_base_convert(baseband_tx, word_size, symb_size);
% save original baseband data for error calculation later save('err_calc.mat', 'baseband_tx');
121
% ####################################################### %
% ******************* OFDM TRANSMITTER ****************** %
% ####################################################### %
tic; % start stopwatch
% generate header and trailer (an exact copy of the header)
f = 0.25;
header = sin(0:f*2*pi:f*2*pi*(head_len-1));
f=f/(pi*2/3);
header = header+sin(0:f*2*pi:f*2*pi*(head_len-1));
% arrange data into frames and transmit frame_guard = zeros(1, symb_period);
time_wave_tx = [];
symb_per_carrier = ceil(length(baseband_tx)/carrier_count);
fig = 1;
if (symb_per_carrier > symb_per_frame) % === multiple frames === %
power = 0;
while isempty(baseband_tx)
% number of symbols per frame frame_len = min(symb_per_frame*carrier_count,length(baseband_tx));
frame_data = baseband_tx(1:frame_len);
% update the yet-to-modulate data baseband_tx = baseband_tx((frame_len+1):(length(baseband_tx)));
% OFDM modulation time_signal_tx = ofdm_modulate(frame_data,ifft_size,carriers,...
conj_carriers, carrier_count, symb_size, guard_time, fig);
fig = 0; %indicate that ofdm_modulate() has already generated plots
% add a frame guard to each frame of modulated signal time_wave_tx = [time_wave_tx frame_guard time_signal_tx];
frame_power = var(time_signal_tx);
end
% scale the header to match signal level power = power + frame_power;
% The OFDM modulated signal for transmission time_wave_tx = [power*header time_wave_tx frame_guard power*header];
else % === single frame === %
% OFDM modulation time_signal_tx = ofdm_modulate(baseband_tx,ifft_size,carriers,...
conj_carriers, carrier_count, symb_size, guard_time, fig);
% calculate the signal power to scale the header power = var(time_signal_tx);
% The OFDM modulated signal for transmission time_wave_tx = ...
[power*header frame_guard time_signal_tx frame_guard power*header];
end
% show summary of the OFDM transmission modeling peak = max(abs(time_wave_tx(head_len+1:length(time_wave_tx)-head_len)));
sig_rms = std(time_wave_tx(head_len+1:length(time_wave_tx)-head_len));
peak_rms_ratio = (20*log10(peak/sig_rms));
fprintf('\nSummary of the OFDM transmission and channel modeling:\n')
fprintf('Peak to RMS power ratio at entrance of channel is: %f dB\n', ...
peak_rms_ratio)
122
% ####################################################### %
% **************** COMMUNICATION CHANNEL **************** %
% ####################################################### %
% ===== signal clipping ===== %
clipped_peak = (10^(0-(clipping/20)))*max(abs(time_wave_tx));
time_wave_tx(find(abs(time_wave_tx)>=clipped_peak))...
= clipped_peak.*time_wave_tx(find(abs(time_wave_tx)>=clipped_peak))...
./abs(time_wave_tx(find(abs(time_wave_tx)>=clipped_peak)));
% ===== channel noise ===== %
power = var(time_wave_tx); % Gaussian (AWGN)
SNR_linear = 10^(SNR_dB/10);
noise_factor = sqrt(power/SNR_linear);
noise = randn(1,length(time_wave_tx)) * noise_factor;
time_wave_rx = time_wave_tx + noise;
% show summary of the OFDM channel modeling peak = max(abs(time_wave_rx(head_len+1:length(time_wave_rx)-head_len)));
sig_rms = std(time_wave_rx(head_len+1:length(time_wave_rx)-head_len));
peak_rms_ratio = (20*log10(peak/sig_rms));
fprintf('Peak to RMS power ratio at exit of channel is: %f dB\n', ...
peak_rms_ratio)
% Save the signal to be received save('received.mat', 'time_wave_rx', 'h', 'w');
fprintf('#******** OFDM data transmitted in %f seconds ********#\n\n', toc)
% ####################################################### %
% ********************* OFDM RECEIVER ******************* %
% ####################################################### %
disp('Press any key to let OFDM RECEIVER proceed...')
pause;
clear all; % flush all data stored in memory previously tic; % start stopwatch
% invoking ofdm_parameters.m script to set OFDM system parameters load('ofdm_parameters');
% receive data load('received.mat');
time_wave_rx = time_wave_rx.';
end_x = length(time_wave_rx);
start_x = 1;
data = [];
phase = [];
last_frame = 0;
unpad = 0;
if rem(w*h, carrier_count)=0
unpad = carrier_count - rem(w*h, carrier_count);
end num_frame=ceil((h*w)*(word_size/symb_size)/(symb_per_frame*carrier_count));
fig = 0;
123 for k = 1:num_frame if k==1 || k==num_frame || rem(k,max(floor(num_frame/10),1))==0
fprintf('Demodulating Frame #%d\n',k)
end
% pick appropriate trunks of time signal to detect data frame if k==1
time_wave = time_wave_rx(start_x:min(end_x, ...
(head_len+symb_period*((symb_per_frame+1)/2+1))));
else time_wave = time_wave_rx(start_x:min(end_x, ...
((start_x-1) + (symb_period*((symb_per_frame+1)/2+1)))));
end
% detect the data frame that only contains the useful information frame_start = ...
ofdm_frame_detect(time_wave, symb_period, envelope, start_x);
if k==num_frame last_frame = 1;
frame_end = min(end_x, (frame_start-1) + symb_period*...
(1+ceil(rem(w*h,carrier_count*symb_per_frame)/carrier_count)));
else frame_end=min(frame_start-1+(symb_per_frame+1)*symb_period, end_x);
end
% take the time signal abstracted from this frame to demodulate time_wave = time_wave_rx(frame_start:frame_end);
% update the label for leftover signal start_x = frame_end - symb_period;
if k==ceil(num_frame/2)
fig = 1;
end
% demodulate the received time signal
[data_rx, phase_rx] = ofdm_demod...
(time_wave, ifft_size, carriers, conj_carriers, ...
guard_time, symb_size, word_size, last_frame, unpad, fig);
if fig==1
fig = 0; % indicate that ofdm_demod() has already generated plots end phase = [phase phase_rx];
data = [data data_rx];
end phase_rx = phase; % decoded phase data_rx = data; % received data
% convert symbol size (bits/symbol) to file word size (bits/byte) as needed data_out = ofdm_base_convert(data_rx, symb_size, word_size);
fprintf('#********** OFDM data received in %f seconds *********#\n\n', toc)
% ####################################################### %
% ********************** DATA OUTPUT ******************** %
% ####################################################### %
% patch or trim the data to fit a w-by-h image if length(data_out)>(w*h) % trim extra data data_out = data_out(1:(w*h));
elseif length(data_out)<(w*h) % patch a partially missing row buff_h = h;
h = ceil(length(data_out)/w);
% if one or more rows of pixels are missing, show a message to indicate if h=buff_h disp('WARNING: Output image smaller than original')
disp(' due to data loss in transmission.')
124 end
% to make the patch nearly seamless,
% make each patched pixel the same color as the one right above it if length(data_out)=(w*h)
for k=1:(w*h-length(data_out))
mend(k)=data_out(length(data_out)-w+k);
end data_out = [data_out mend];
end end
% format the demodulated data to reconstruct a bitmap image data_out = reshape(data_out, w, h)';
data_out = uint8(data_out);
% save the output image to a bitmap (*.bmp) file imwrite(data_out, file_out, 'bmp');
% ####################################################### %
% ****************** ERROR CALCULATIONS ***************** %
% ####################################################### %
% collect original data before modulation for error calculations load('err_calc.mat');
fprintf('\n#**************** Summary of Errors ****************#\n')
% Let received and original data match size and calculate data loss rate if length(data_rx)>length(baseband_tx)
data_rx = data_rx(1:length(baseband_tx));
phase_rx = phase_rx(1:length(baseband_tx));
elseif length(data_rx) fprintf('Data loss in this communication = %f%% (%d out of %d)\n', ...
(length(baseband_tx)-length(data_rx))/length(baseband_tx)*100, ...
length(baseband_tx)-length(data_rx), length(baseband_tx))
end
% find errors errors = find(baseband_tx(1:length(data_rx))=data_rx);
fprintf('Total number of errors = %d (out of %d)\n', ...
length(errors), length(data_rx))
% Bit Error Rate fprintf('Bit Error Rate (BER) = %f%%\n',length(errors)/length(data_rx)*100)
% find phase error in degrees and translate to -180 to +180 interval phase_tx = baseband_tx*360/(2^symb_size);
phase_err = (phase_rx - phase_tx(1:length(phase_rx)));
phase_err(find(phase_err>=180)) = phase_err(find(phase_err>=180))-360;
phase_err(find(phase_err<=-180)) = phase_err(find(phase_err<=-180))+360;
fprintf('Average Phase Error = %f (degree)\n', mean(abs(phase_err)))
% Error pixels x = ofdm_base_convert(baseband_tx, symb_size, word_size);
x = uint8(x);
x = x(1:(size(data_out,1)*size(data_out,2)));
y = reshape(data_out', 1, length(x));
err_pix = find(y=x);
fprintf('Percent error of pixels of the received image = %f%%\n\n', ...
length(err_pix)/length(x)*100)
fprintf('##########################################\n')
fprintf('#******** END of OFDM Simulation ********#\n')
125 fprintf('##########################################\n\n')
% ************* PARAMETERS INITIALIZATION ************* %
% This file configures parameters for the OFDM system.
% input/output file names file_in = [];
while isempty(file_in)
file_in = input('source data filename: ', 's');
if exist([pwd '/' file_in],'file')=2
fprintf ...
('"%s" does not exist in current directory.\n', file_in);
file_in = [];
end end file_out = [file_in(1:length(file_in)-4) '_OFDM.bmp'];
disp(['Output file will be: ' file_out])
% size of Inverse Fast Fourier Transform (must be power of 2)
ifft_size = 0.1; % force into the while loop below while (isempty(ifft_size) || ...
(rem(log2(ifft_size),1) = 0 || ifft_size < 8))
ifft_size = input('IFFT size: ');
if (isempty(ifft_size) || ...
(rem(log2(ifft_size),1) = 0 || ifft_size < 8))
disp('IFFT size must be at least 8 and power of 2.')
end end
% number of carriers carrier_count = ifft_size; % force into the while loop below while (isempty(carrier_count) || ...
(carrier_count>(ifft_size/2-2)) || carrier_count<2)
carrier_count = input('Number of carriers: ');
if (isempty(carrier_count) || (carrier_count > (ifft_size/2-2)))
disp('Must NOT be greater than ("IFFT size"/2-2)')
end end
% bits per symbol (1 = BPSK, 2=QPSK, 4=16PSK, 8=256PSK)
symb_size = 0; % force into the while loop below while (isempty(symb_size) || ...
(symb_size=1 && symb_size=2 && symb_size=4 && symb_size=8))
symb_size = input...
('Modulation(1=BPSK, 2=QPSK, 4=16PSK, 8=256PSK): ');
if (isempty(symb_size) || ...
(symb_size=1&&symb_size=2&&symb_size=4&&symb_size=8))
disp('Only 1, 2, 4, or 8 can be choosen')
end end
126
% channel clipping in dB
clipping = [];
while isempty(clipping)
clipping = input('Amplitude clipping introduced by communication channel
(in dB):');
end
% signal to noise ratio in dB
SNR_dB = [];
while isempty(SNR_dB)
SNR_dB = input('Signal-to-Noise Ratio (SNR) in dB: ');
end word_size = 8; % bits per word of source data (byte)
guard_time = ifft_size/4; % length of guard interval for each symbol period
% 25% of ifft_size
% number of symbols per carrier in each frame for transmission symb_per_frame = ceil(2^13/carrier_count);
% === Derived Parameters === %
% frame_len: length of one symbol period including guard time symb_period = ifft_size + guard_time;
% head_len: length of the header and trailer of the transmitted data head_len = symb_period*8;
% envelope: symb_period/envelope is the size of envelope detector envelope = ceil(symb_period/256)+1;
% === carriers assigned to IFFT bins === %
% spacing for carriers distributed in IFFT bins spacing = 0;
while (carrier_count*spacing) <= (ifft_size/2 - 2)
spacing = spacing + 1;
end spacing = spacing - 1;
% spead out carriers into IFFT bins accordingly midFreq = ifft_size/4;
first_carrier = midFreq - round((carrier_count-1)*spacing/2);
last_carrier = midFreq + floor((carrier_count-1)*spacing/2);
carriers = [first_carrier:spacing:last_carrier] + 1;
conj_carriers = ifft_size - carriers + 2;
127
% ************* FUNCTION: ofdm_base_convert() ************* %
% This function converts data from one base to another.
% "Base" refers to number of bits the symbol/word uses to represent data.
function data_out = ofdm_base_convert(data_in, base, new_base)
% if new base is in a higer order than the current base,
% make the size of data in current base a multiple of its new base if new_base>base data_in = data_in(1:...
floor(length(data_in)/(new_base/base))*(new_base/base));
end
% base to binary for k=1:base binary_matrix(k,:) = floor(data_in/2^(base-k));
data_in = rem(data_in,2^(base-k));
end
% format the binary matrix to fit dimensions of the new base newbase_matrix = reshape(binary_matrix, new_base, ...
size(binary_matrix,1)*size(binary_matrix,2)/new_base);
% binary to new_base data_out = zeros(1, size(newbase_matrix,2));
for k=1:new_base data_out = data_out + newbase_matrix(k,:)*(2^(new_base-k));
end
% ************* FUNCTION: ofdm_modulation() ************* %
% This function performance the OFDM modulation before data transmission.
function signal_tx = ofdm_modulate(data_tx, ifft_size, carriers, ...
conj_carriers, carrier_count, symb_size, guard_time, fig)
% symbols per carrier for this frame carrier_symb_count = ceil(length(data_tx)/carrier_count);
% append zeros to data with a length not multiple of number of carriers if length(data_tx)/carrier_count = carrier_symb_count,
padding = zeros(1, carrier_symb_count*carrier_count);
padding(1:length(data_tx)) = data_tx;
data_tx = padding;
end
% serial to parellel: each column represents a carrier data_tx_matrix = reshape(data_tx, carrier_count, carrier_symb_count)';
% --------------------------------- %
% ##### Differential Encoding ##### %
% --------------------------------- %
% an additional row and include reference point carrier_symb_count = size(data_tx_matrix,1) + 1;
1 2 3 4 5 6 7
1
П
од
п.
и
д
ат
а
И
нв
.
д
уб
л
.
В
за
м
.и
нв
.
П
од
п.
и
д
ат
а
42
5
В
ер
но
(
)
Н
.к
он
т
р
.
И
нв
.
по
дл
.
ф.2.106-5
Копировал
Формат А4
П
ер
в.
п
ри
м
ен
.
С
пр
ав
.
(
)
Листов
Примечание
Кол.
Наименование
Поз. обо-
значение
З
о
н
а
Приемопередатчик OFDM
Перечень элементов
ПГУ 1.11.05.01.10EР114
2
1 150 пФ-50В-NPO-1206+/-5%
1 1
2 2
2
С1, C2
С5
С6, С7
С8, С9
С10
С11
С12, С13
С14, С15 2
2
Кравченко
X1
Розетка 34000000-04 1
X2
Розетка СНЦ23-4/18В-1В ГЕ0.364.241ТУ
1
B1
Резонатор кварцевый MC-306 128МГц
В3 1
1
TR2
С21, С22 150 пкФ-50В-NPO-1206+/-5%
2 4
С23... С26 0,1 мкФ-50В-NPO-1206+/-5%
С16...С20 0,1 мкФ-50В-NPO-1206+/-5%
5
Конденсаторы
B2
Резонатор кварцевый HC-49U 4664МГц
Резонатор кварцевый MC-306 128МГц
1 1
1
TR1
Трансформатор четвертьволновый
Трансформатор питания ТП124-5
РК-50-9
C3, С4 0,1 мкФ-50В-NPO-1206+/-5%
2 12 пкФ-50В-NPO-1206+/-5%
0,1 мкФ-50В-NPO-1206+/-5%
10 мкФ-16В-В +/-10% (танталовый)
0,1 мкФ-50В-NPO-1206+/-5%
100 мкФ-16В-Е+/-10% (танталовый)
0,1 мкФ-50В-NPO-1206+/-5%
10 мкФ-16В-В +/-10% (танталовый)
С27... С30 12 пкФ-50В-NPO-1206+/-5%
4
С31, С32 0,1 мкФ-50В-NPO-1206+/-5%
2
117
118
119
ПРИЛОЖЕНИЕ Е
ЛИСТИНГ ПРОГРАММЫ MATLAB
ДЛЯ ПЕРЕДАЧИ И ПРИЕМА ИНФОРМАЦИИ
120
% *************** MAIN PROGRAM FILE *************** %
% This is the OFDM simulation program's main file.
% It requires a 256-grayscale bitmap file (*.bmp image file) as data source
% and the following 5 script and function m-files to work:
% ofdm_parameters.m, ofdm_base_convert.m, ofdm_modulate.m,
% ofdm_frame_detect.m, ofdm_demod.m
% ####################################################### %
% ************* OFDM SYSTEM INITIALIZATION: ************* %
% **** setting up parameters & obtaining source data **** %
% ####################################################### %
% Turn off exact-match warning to allow case-insensitive input files warning('off','MATLAB:dispatcher:InexactMatch');
clear all; % clear all previous data in MATLAB workspace close all; % close all previously opened figures and graphs fprintf('\n\n##########################################\n')
fprintf('#*********** OFDM Simulation ************#\n')
fprintf('##########################################\n\n')
% invoking ofdm_parameters.m script to set OFDM system parameters ofdm_parameters;
% save parameters for receiver save('ofdm_parameters');
% read data from input file x = imread(file_in);
% arrange data read from image for OFDM processing h = size(x,1);
w = size(x,2);
x = reshape(x,1,w*h);
baseband_tx = double(x);
% convert original data word size (bits/word) to symbol size (bits/symbol)
% symbol size (bits/symbol) is determined by choice of modulation method baseband_tx = ofdm_base_convert(baseband_tx, word_size, symb_size);
% save original baseband data for error calculation later save('err_calc.mat', 'baseband_tx');
121
% ####################################################### %
% ******************* OFDM TRANSMITTER ****************** %
% ####################################################### %
tic; % start stopwatch
% generate header and trailer (an exact copy of the header)
f = 0.25;
header = sin(0:f*2*pi:f*2*pi*(head_len-1));
f=f/(pi*2/3);
header = header+sin(0:f*2*pi:f*2*pi*(head_len-1));
% arrange data into frames and transmit frame_guard = zeros(1, symb_period);
time_wave_tx = [];
symb_per_carrier = ceil(length(baseband_tx)/carrier_count);
fig = 1;
if (symb_per_carrier > symb_per_frame) % === multiple frames === %
power = 0;
while isempty(baseband_tx)
% number of symbols per frame frame_len = min(symb_per_frame*carrier_count,length(baseband_tx));
frame_data = baseband_tx(1:frame_len);
% update the yet-to-modulate data baseband_tx = baseband_tx((frame_len+1):(length(baseband_tx)));
% OFDM modulation time_signal_tx = ofdm_modulate(frame_data,ifft_size,carriers,...
conj_carriers, carrier_count, symb_size, guard_time, fig);
fig = 0; %indicate that ofdm_modulate() has already generated plots
% add a frame guard to each frame of modulated signal time_wave_tx = [time_wave_tx frame_guard time_signal_tx];
frame_power = var(time_signal_tx);
end
% scale the header to match signal level power = power + frame_power;
% The OFDM modulated signal for transmission time_wave_tx = [power*header time_wave_tx frame_guard power*header];
else % === single frame === %
% OFDM modulation time_signal_tx = ofdm_modulate(baseband_tx,ifft_size,carriers,...
conj_carriers, carrier_count, symb_size, guard_time, fig);
% calculate the signal power to scale the header power = var(time_signal_tx);
% The OFDM modulated signal for transmission time_wave_tx = ...
[power*header frame_guard time_signal_tx frame_guard power*header];
end
% show summary of the OFDM transmission modeling peak = max(abs(time_wave_tx(head_len+1:length(time_wave_tx)-head_len)));
sig_rms = std(time_wave_tx(head_len+1:length(time_wave_tx)-head_len));
peak_rms_ratio = (20*log10(peak/sig_rms));
fprintf('\nSummary of the OFDM transmission and channel modeling:\n')
fprintf('Peak to RMS power ratio at entrance of channel is: %f dB\n', ...
peak_rms_ratio)
122
% ####################################################### %
% **************** COMMUNICATION CHANNEL **************** %
% ####################################################### %
% ===== signal clipping ===== %
clipped_peak = (10^(0-(clipping/20)))*max(abs(time_wave_tx));
time_wave_tx(find(abs(time_wave_tx)>=clipped_peak))...
= clipped_peak.*time_wave_tx(find(abs(time_wave_tx)>=clipped_peak))...
./abs(time_wave_tx(find(abs(time_wave_tx)>=clipped_peak)));
% ===== channel noise ===== %
power = var(time_wave_tx); % Gaussian (AWGN)
SNR_linear = 10^(SNR_dB/10);
noise_factor = sqrt(power/SNR_linear);
noise = randn(1,length(time_wave_tx)) * noise_factor;
time_wave_rx = time_wave_tx + noise;
% show summary of the OFDM channel modeling peak = max(abs(time_wave_rx(head_len+1:length(time_wave_rx)-head_len)));
sig_rms = std(time_wave_rx(head_len+1:length(time_wave_rx)-head_len));
peak_rms_ratio = (20*log10(peak/sig_rms));
fprintf('Peak to RMS power ratio at exit of channel is: %f dB\n', ...
peak_rms_ratio)
% Save the signal to be received save('received.mat', 'time_wave_rx', 'h', 'w');
fprintf('#******** OFDM data transmitted in %f seconds ********#\n\n', toc)
% ####################################################### %
% ********************* OFDM RECEIVER ******************* %
% ####################################################### %
disp('Press any key to let OFDM RECEIVER proceed...')
pause;
clear all; % flush all data stored in memory previously tic; % start stopwatch
% invoking ofdm_parameters.m script to set OFDM system parameters load('ofdm_parameters');
% receive data load('received.mat');
time_wave_rx = time_wave_rx.';
end_x = length(time_wave_rx);
start_x = 1;
data = [];
phase = [];
last_frame = 0;
unpad = 0;
if rem(w*h, carrier_count)=0
unpad = carrier_count - rem(w*h, carrier_count);
end num_frame=ceil((h*w)*(word_size/symb_size)/(symb_per_frame*carrier_count));
fig = 0;
123 for k = 1:num_frame if k==1 || k==num_frame || rem(k,max(floor(num_frame/10),1))==0
fprintf('Demodulating Frame #%d\n',k)
end
% pick appropriate trunks of time signal to detect data frame if k==1
time_wave = time_wave_rx(start_x:min(end_x, ...
(head_len+symb_period*((symb_per_frame+1)/2+1))));
else time_wave = time_wave_rx(start_x:min(end_x, ...
((start_x-1) + (symb_period*((symb_per_frame+1)/2+1)))));
end
% detect the data frame that only contains the useful information frame_start = ...
ofdm_frame_detect(time_wave, symb_period, envelope, start_x);
if k==num_frame last_frame = 1;
frame_end = min(end_x, (frame_start-1) + symb_period*...
(1+ceil(rem(w*h,carrier_count*symb_per_frame)/carrier_count)));
else frame_end=min(frame_start-1+(symb_per_frame+1)*symb_period, end_x);
end
% take the time signal abstracted from this frame to demodulate time_wave = time_wave_rx(frame_start:frame_end);
% update the label for leftover signal start_x = frame_end - symb_period;
if k==ceil(num_frame/2)
fig = 1;
end
% demodulate the received time signal
[data_rx, phase_rx] = ofdm_demod...
(time_wave, ifft_size, carriers, conj_carriers, ...
guard_time, symb_size, word_size, last_frame, unpad, fig);
if fig==1
fig = 0; % indicate that ofdm_demod() has already generated plots end phase = [phase phase_rx];
data = [data data_rx];
end phase_rx = phase; % decoded phase data_rx = data; % received data
% convert symbol size (bits/symbol) to file word size (bits/byte) as needed data_out = ofdm_base_convert(data_rx, symb_size, word_size);
fprintf('#********** OFDM data received in %f seconds *********#\n\n', toc)
% ####################################################### %
% ********************** DATA OUTPUT ******************** %
% ####################################################### %
% patch or trim the data to fit a w-by-h image if length(data_out)>(w*h) % trim extra data data_out = data_out(1:(w*h));
elseif length(data_out)<(w*h) % patch a partially missing row buff_h = h;
h = ceil(length(data_out)/w);
% if one or more rows of pixels are missing, show a message to indicate if h=buff_h disp('WARNING: Output image smaller than original')
disp(' due to data loss in transmission.')
124 end
% to make the patch nearly seamless,
% make each patched pixel the same color as the one right above it if length(data_out)=(w*h)
for k=1:(w*h-length(data_out))
mend(k)=data_out(length(data_out)-w+k);
end data_out = [data_out mend];
end end
% format the demodulated data to reconstruct a bitmap image data_out = reshape(data_out, w, h)';
data_out = uint8(data_out);
% save the output image to a bitmap (*.bmp) file imwrite(data_out, file_out, 'bmp');
% ####################################################### %
% ****************** ERROR CALCULATIONS ***************** %
% ####################################################### %
% collect original data before modulation for error calculations load('err_calc.mat');
fprintf('\n#**************** Summary of Errors ****************#\n')
% Let received and original data match size and calculate data loss rate if length(data_rx)>length(baseband_tx)
data_rx = data_rx(1:length(baseband_tx));
phase_rx = phase_rx(1:length(baseband_tx));
elseif length(data_rx) fprintf('Data loss in this communication = %f%% (%d out of %d)\n', ...
(length(baseband_tx)-length(data_rx))/length(baseband_tx)*100, ...
length(baseband_tx)-length(data_rx), length(baseband_tx))
end
% find errors errors = find(baseband_tx(1:length(data_rx))=data_rx);
fprintf('Total number of errors = %d (out of %d)\n', ...
length(errors), length(data_rx))
% Bit Error Rate fprintf('Bit Error Rate (BER) = %f%%\n',length(errors)/length(data_rx)*100)
% find phase error in degrees and translate to -180 to +180 interval phase_tx = baseband_tx*360/(2^symb_size);
phase_err = (phase_rx - phase_tx(1:length(phase_rx)));
phase_err(find(phase_err>=180)) = phase_err(find(phase_err>=180))-360;
phase_err(find(phase_err<=-180)) = phase_err(find(phase_err<=-180))+360;
fprintf('Average Phase Error = %f (degree)\n', mean(abs(phase_err)))
% Error pixels x = ofdm_base_convert(baseband_tx, symb_size, word_size);
x = uint8(x);
x = x(1:(size(data_out,1)*size(data_out,2)));
y = reshape(data_out', 1, length(x));
err_pix = find(y=x);
fprintf('Percent error of pixels of the received image = %f%%\n\n', ...
length(err_pix)/length(x)*100)
fprintf('##########################################\n')
fprintf('#******** END of OFDM Simulation ********#\n')
125 fprintf('##########################################\n\n')
% ************* PARAMETERS INITIALIZATION ************* %
% This file configures parameters for the OFDM system.
% input/output file names file_in = [];
while isempty(file_in)
file_in = input('source data filename: ', 's');
if exist([pwd '/' file_in],'file')=2
fprintf ...
('"%s" does not exist in current directory.\n', file_in);
file_in = [];
end end file_out = [file_in(1:length(file_in)-4) '_OFDM.bmp'];
disp(['Output file will be: ' file_out])
% size of Inverse Fast Fourier Transform (must be power of 2)
ifft_size = 0.1; % force into the while loop below while (isempty(ifft_size) || ...
(rem(log2(ifft_size),1) = 0 || ifft_size < 8))
ifft_size = input('IFFT size: ');
if (isempty(ifft_size) || ...
(rem(log2(ifft_size),1) = 0 || ifft_size < 8))
disp('IFFT size must be at least 8 and power of 2.')
end end
% number of carriers carrier_count = ifft_size; % force into the while loop below while (isempty(carrier_count) || ...
(carrier_count>(ifft_size/2-2)) || carrier_count<2)
carrier_count = input('Number of carriers: ');
if (isempty(carrier_count) || (carrier_count > (ifft_size/2-2)))
disp('Must NOT be greater than ("IFFT size"/2-2)')
end end
% bits per symbol (1 = BPSK, 2=QPSK, 4=16PSK, 8=256PSK)
symb_size = 0; % force into the while loop below while (isempty(symb_size) || ...
(symb_size=1 && symb_size=2 && symb_size=4 && symb_size=8))
symb_size = input...
('Modulation(1=BPSK, 2=QPSK, 4=16PSK, 8=256PSK): ');
if (isempty(symb_size) || ...
(symb_size=1&&symb_size=2&&symb_size=4&&symb_size=8))
disp('Only 1, 2, 4, or 8 can be choosen')
end end
126
% channel clipping in dB
clipping = [];
while isempty(clipping)
clipping = input('Amplitude clipping introduced by communication channel
(in dB):');
end
% signal to noise ratio in dB
SNR_dB = [];
while isempty(SNR_dB)
SNR_dB = input('Signal-to-Noise Ratio (SNR) in dB: ');
end word_size = 8; % bits per word of source data (byte)
guard_time = ifft_size/4; % length of guard interval for each symbol period
% 25% of ifft_size
% number of symbols per carrier in each frame for transmission symb_per_frame = ceil(2^13/carrier_count);
% === Derived Parameters === %
% frame_len: length of one symbol period including guard time symb_period = ifft_size + guard_time;
% head_len: length of the header and trailer of the transmitted data head_len = symb_period*8;
% envelope: symb_period/envelope is the size of envelope detector envelope = ceil(symb_period/256)+1;
% === carriers assigned to IFFT bins === %
% spacing for carriers distributed in IFFT bins spacing = 0;
while (carrier_count*spacing) <= (ifft_size/2 - 2)
spacing = spacing + 1;
end spacing = spacing - 1;
% spead out carriers into IFFT bins accordingly midFreq = ifft_size/4;
first_carrier = midFreq - round((carrier_count-1)*spacing/2);
last_carrier = midFreq + floor((carrier_count-1)*spacing/2);
carriers = [first_carrier:spacing:last_carrier] + 1;
conj_carriers = ifft_size - carriers + 2;
127
% ************* FUNCTION: ofdm_base_convert() ************* %
% This function converts data from one base to another.
% "Base" refers to number of bits the symbol/word uses to represent data.
function data_out = ofdm_base_convert(data_in, base, new_base)
% if new base is in a higer order than the current base,
% make the size of data in current base a multiple of its new base if new_base>base data_in = data_in(1:...
floor(length(data_in)/(new_base/base))*(new_base/base));
end
% base to binary for k=1:base binary_matrix(k,:) = floor(data_in/2^(base-k));
data_in = rem(data_in,2^(base-k));
end
% format the binary matrix to fit dimensions of the new base newbase_matrix = reshape(binary_matrix, new_base, ...
size(binary_matrix,1)*size(binary_matrix,2)/new_base);
% binary to new_base data_out = zeros(1, size(newbase_matrix,2));
for k=1:new_base data_out = data_out + newbase_matrix(k,:)*(2^(new_base-k));
end
% ************* FUNCTION: ofdm_modulation() ************* %
% This function performance the OFDM modulation before data transmission.
function signal_tx = ofdm_modulate(data_tx, ifft_size, carriers, ...
conj_carriers, carrier_count, symb_size, guard_time, fig)
% symbols per carrier for this frame carrier_symb_count = ceil(length(data_tx)/carrier_count);
% append zeros to data with a length not multiple of number of carriers if length(data_tx)/carrier_count = carrier_symb_count,
padding = zeros(1, carrier_symb_count*carrier_count);
padding(1:length(data_tx)) = data_tx;
data_tx = padding;
end
% serial to parellel: each column represents a carrier data_tx_matrix = reshape(data_tx, carrier_count, carrier_symb_count)';
% --------------------------------- %
% ##### Differential Encoding ##### %
% --------------------------------- %
% an additional row and include reference point carrier_symb_count = size(data_tx_matrix,1) + 1;
1 2 3 4 5 6 7
П
од
п.
и
д
ат
а
И
нв
.
д
уб
л
.
В
за
м
.и
нв
.
П
од
п.
и
д
ат
а
42
5
В
ер
но
(
)
Н
.к
он
т
р
.
И
нв
.
по
дл
.
ф.2.106-5
Копировал
Формат А4
П
ер
в.
п
ри
м
ен
.
С
пр
ав
.
(
)
Листов
Примечание
Кол.
Наименование
Поз. обо-
значение
З
о
н
а
Приемопередатчик OFDM
Перечень элементов
ПГУ 1.11.05.01.10EР114
2
1 150 пФ-50В-NPO-1206+/-5%
1 1
2 2
2
С1, C2
С5
С6, С7
С8, С9
С10
С11
С12, С13
С14, С15 2
2
Кравченко
X1
Розетка 34000000-04 1
X2
Розетка СНЦ23-4/18В-1В ГЕ0.364.241ТУ
1
B1
Резонатор кварцевый MC-306 128МГц
В3 1
1
TR2
С21, С22 150 пкФ-50В-NPO-1206+/-5%
2 4
С23... С26 0,1 мкФ-50В-NPO-1206+/-5%
С16...С20 0,1 мкФ-50В-NPO-1206+/-5%
5
Конденсаторы
B2
Резонатор кварцевый HC-49U 4664МГц
Резонатор кварцевый MC-306 128МГц
1 1
1
TR1
Трансформатор четвертьволновый
Трансформатор питания ТП124-5
РК-50-9
C3, С4 0,1 мкФ-50В-NPO-1206+/-5%
2 12 пкФ-50В-NPO-1206+/-5%
0,1 мкФ-50В-NPO-1206+/-5%
10 мкФ-16В-В +/-10% (танталовый)
0,1 мкФ-50В-NPO-1206+/-5%
100 мкФ-16В-Е+/-10% (танталовый)
0,1 мкФ-50В-NPO-1206+/-5%
10 мкФ-16В-В +/-10% (танталовый)
С27... С30 12 пкФ-50В-NPO-1206+/-5%
4
С31, С32 0,1 мкФ-50В-NPO-1206+/-5%
2
117
118
119
ПРИЛОЖЕНИЕ Е
ЛИСТИНГ ПРОГРАММЫ MATLAB
ДЛЯ ПЕРЕДАЧИ И ПРИЕМА ИНФОРМАЦИИ
120
% *************** MAIN PROGRAM FILE *************** %
% This is the OFDM simulation program's main file.
% It requires a 256-grayscale bitmap file (*.bmp image file) as data source
% and the following 5 script and function m-files to work:
% ofdm_parameters.m, ofdm_base_convert.m, ofdm_modulate.m,
% ofdm_frame_detect.m, ofdm_demod.m
% ####################################################### %
% ************* OFDM SYSTEM INITIALIZATION: ************* %
% **** setting up parameters & obtaining source data **** %
% ####################################################### %
% Turn off exact-match warning to allow case-insensitive input files warning('off','MATLAB:dispatcher:InexactMatch');
clear all; % clear all previous data in MATLAB workspace close all; % close all previously opened figures and graphs fprintf('\n\n##########################################\n')
fprintf('#*********** OFDM Simulation ************#\n')
fprintf('##########################################\n\n')
% invoking ofdm_parameters.m script to set OFDM system parameters ofdm_parameters;
% save parameters for receiver save('ofdm_parameters');
% read data from input file x = imread(file_in);
% arrange data read from image for OFDM processing h = size(x,1);
w = size(x,2);
x = reshape(x,1,w*h);
baseband_tx = double(x);
% convert original data word size (bits/word) to symbol size (bits/symbol)
% symbol size (bits/symbol) is determined by choice of modulation method baseband_tx = ofdm_base_convert(baseband_tx, word_size, symb_size);
% save original baseband data for error calculation later save('err_calc.mat', 'baseband_tx');
121
% ####################################################### %
% ******************* OFDM TRANSMITTER ****************** %
% ####################################################### %
tic; % start stopwatch
% generate header and trailer (an exact copy of the header)
f = 0.25;
header = sin(0:f*2*pi:f*2*pi*(head_len-1));
f=f/(pi*2/3);
header = header+sin(0:f*2*pi:f*2*pi*(head_len-1));
% arrange data into frames and transmit frame_guard = zeros(1, symb_period);
time_wave_tx = [];
symb_per_carrier = ceil(length(baseband_tx)/carrier_count);
fig = 1;
if (symb_per_carrier > symb_per_frame) % === multiple frames === %
power = 0;
while isempty(baseband_tx)
% number of symbols per frame frame_len = min(symb_per_frame*carrier_count,length(baseband_tx));
frame_data = baseband_tx(1:frame_len);
% update the yet-to-modulate data baseband_tx = baseband_tx((frame_len+1):(length(baseband_tx)));
% OFDM modulation time_signal_tx = ofdm_modulate(frame_data,ifft_size,carriers,...
conj_carriers, carrier_count, symb_size, guard_time, fig);
fig = 0; %indicate that ofdm_modulate() has already generated plots
% add a frame guard to each frame of modulated signal time_wave_tx = [time_wave_tx frame_guard time_signal_tx];
frame_power = var(time_signal_tx);
end
% scale the header to match signal level power = power + frame_power;
% The OFDM modulated signal for transmission time_wave_tx = [power*header time_wave_tx frame_guard power*header];
else % === single frame === %
% OFDM modulation time_signal_tx = ofdm_modulate(baseband_tx,ifft_size,carriers,...
conj_carriers, carrier_count, symb_size, guard_time, fig);
% calculate the signal power to scale the header power = var(time_signal_tx);
% The OFDM modulated signal for transmission time_wave_tx = ...
[power*header frame_guard time_signal_tx frame_guard power*header];
end
% show summary of the OFDM transmission modeling peak = max(abs(time_wave_tx(head_len+1:length(time_wave_tx)-head_len)));
sig_rms = std(time_wave_tx(head_len+1:length(time_wave_tx)-head_len));
peak_rms_ratio = (20*log10(peak/sig_rms));
fprintf('\nSummary of the OFDM transmission and channel modeling:\n')
fprintf('Peak to RMS power ratio at entrance of channel is: %f dB\n', ...
peak_rms_ratio)
122
% ####################################################### %
% **************** COMMUNICATION CHANNEL **************** %
% ####################################################### %
% ===== signal clipping ===== %
clipped_peak = (10^(0-(clipping/20)))*max(abs(time_wave_tx));
time_wave_tx(find(abs(time_wave_tx)>=clipped_peak))...
= clipped_peak.*time_wave_tx(find(abs(time_wave_tx)>=clipped_peak))...
./abs(time_wave_tx(find(abs(time_wave_tx)>=clipped_peak)));
% ===== channel noise ===== %
power = var(time_wave_tx); % Gaussian (AWGN)
SNR_linear = 10^(SNR_dB/10);
noise_factor = sqrt(power/SNR_linear);
noise = randn(1,length(time_wave_tx)) * noise_factor;
time_wave_rx = time_wave_tx + noise;
% show summary of the OFDM channel modeling peak = max(abs(time_wave_rx(head_len+1:length(time_wave_rx)-head_len)));
sig_rms = std(time_wave_rx(head_len+1:length(time_wave_rx)-head_len));
peak_rms_ratio = (20*log10(peak/sig_rms));
fprintf('Peak to RMS power ratio at exit of channel is: %f dB\n', ...
peak_rms_ratio)
% Save the signal to be received save('received.mat', 'time_wave_rx', 'h', 'w');
fprintf('#******** OFDM data transmitted in %f seconds ********#\n\n', toc)
% ####################################################### %
% ********************* OFDM RECEIVER ******************* %
% ####################################################### %
disp('Press any key to let OFDM RECEIVER proceed...')
pause;
clear all; % flush all data stored in memory previously tic; % start stopwatch
% invoking ofdm_parameters.m script to set OFDM system parameters load('ofdm_parameters');
% receive data load('received.mat');
time_wave_rx = time_wave_rx.';
end_x = length(time_wave_rx);
start_x = 1;
data = [];
phase = [];
last_frame = 0;
unpad = 0;
if rem(w*h, carrier_count)=0
unpad = carrier_count - rem(w*h, carrier_count);
end num_frame=ceil((h*w)*(word_size/symb_size)/(symb_per_frame*carrier_count));
fig = 0;
123 for k = 1:num_frame if k==1 || k==num_frame || rem(k,max(floor(num_frame/10),1))==0
fprintf('Demodulating Frame #%d\n',k)
end
% pick appropriate trunks of time signal to detect data frame if k==1
time_wave = time_wave_rx(start_x:min(end_x, ...
(head_len+symb_period*((symb_per_frame+1)/2+1))));
else time_wave = time_wave_rx(start_x:min(end_x, ...
((start_x-1) + (symb_period*((symb_per_frame+1)/2+1)))));
end
% detect the data frame that only contains the useful information frame_start = ...
ofdm_frame_detect(time_wave, symb_period, envelope, start_x);
if k==num_frame last_frame = 1;
frame_end = min(end_x, (frame_start-1) + symb_period*...
(1+ceil(rem(w*h,carrier_count*symb_per_frame)/carrier_count)));
else frame_end=min(frame_start-1+(symb_per_frame+1)*symb_period, end_x);
end
% take the time signal abstracted from this frame to demodulate time_wave = time_wave_rx(frame_start:frame_end);
% update the label for leftover signal start_x = frame_end - symb_period;
if k==ceil(num_frame/2)
fig = 1;
end
% demodulate the received time signal
[data_rx, phase_rx] = ofdm_demod...
(time_wave, ifft_size, carriers, conj_carriers, ...
guard_time, symb_size, word_size, last_frame, unpad, fig);
if fig==1
fig = 0; % indicate that ofdm_demod() has already generated plots end phase = [phase phase_rx];
data = [data data_rx];
end phase_rx = phase; % decoded phase data_rx = data; % received data
% convert symbol size (bits/symbol) to file word size (bits/byte) as needed data_out = ofdm_base_convert(data_rx, symb_size, word_size);
fprintf('#********** OFDM data received in %f seconds *********#\n\n', toc)
% ####################################################### %
% ********************** DATA OUTPUT ******************** %
% ####################################################### %
% patch or trim the data to fit a w-by-h image if length(data_out)>(w*h) % trim extra data data_out = data_out(1:(w*h));
elseif length(data_out)<(w*h) % patch a partially missing row buff_h = h;
h = ceil(length(data_out)/w);
% if one or more rows of pixels are missing, show a message to indicate if h=buff_h disp('WARNING: Output image smaller than original')
disp(' due to data loss in transmission.')
124 end
% to make the patch nearly seamless,
% make each patched pixel the same color as the one right above it if length(data_out)=(w*h)
for k=1:(w*h-length(data_out))
mend(k)=data_out(length(data_out)-w+k);
end data_out = [data_out mend];
end end
% format the demodulated data to reconstruct a bitmap image data_out = reshape(data_out, w, h)';
data_out = uint8(data_out);
% save the output image to a bitmap (*.bmp) file imwrite(data_out, file_out, 'bmp');
% ####################################################### %
% ****************** ERROR CALCULATIONS ***************** %
% ####################################################### %
% collect original data before modulation for error calculations load('err_calc.mat');
fprintf('\n#**************** Summary of Errors ****************#\n')
% Let received and original data match size and calculate data loss rate if length(data_rx)>length(baseband_tx)
data_rx = data_rx(1:length(baseband_tx));
phase_rx = phase_rx(1:length(baseband_tx));
elseif length(data_rx)
(length(baseband_tx)-length(data_rx))/length(baseband_tx)*100, ...
length(baseband_tx)-length(data_rx), length(baseband_tx))
end
% find errors errors = find(baseband_tx(1:length(data_rx))=data_rx);
fprintf('Total number of errors = %d (out of %d)\n', ...
length(errors), length(data_rx))
% Bit Error Rate fprintf('Bit Error Rate (BER) = %f%%\n',length(errors)/length(data_rx)*100)
% find phase error in degrees and translate to -180 to +180 interval phase_tx = baseband_tx*360/(2^symb_size);
phase_err = (phase_rx - phase_tx(1:length(phase_rx)));
phase_err(find(phase_err>=180)) = phase_err(find(phase_err>=180))-360;
phase_err(find(phase_err<=-180)) = phase_err(find(phase_err<=-180))+360;
fprintf('Average Phase Error = %f (degree)\n', mean(abs(phase_err)))
% Error pixels x = ofdm_base_convert(baseband_tx, symb_size, word_size);
x = uint8(x);
x = x(1:(size(data_out,1)*size(data_out,2)));
y = reshape(data_out', 1, length(x));
err_pix = find(y=x);
fprintf('Percent error of pixels of the received image = %f%%\n\n', ...
length(err_pix)/length(x)*100)
fprintf('##########################################\n')
fprintf('#******** END of OFDM Simulation ********#\n')
125 fprintf('##########################################\n\n')
% ************* PARAMETERS INITIALIZATION ************* %
% This file configures parameters for the OFDM system.
% input/output file names file_in = [];
while isempty(file_in)
file_in = input('source data filename: ', 's');
if exist([pwd '/' file_in],'file')=2
fprintf ...
('"%s" does not exist in current directory.\n', file_in);
file_in = [];
end end file_out = [file_in(1:length(file_in)-4) '_OFDM.bmp'];
disp(['Output file will be: ' file_out])
% size of Inverse Fast Fourier Transform (must be power of 2)
ifft_size = 0.1; % force into the while loop below while (isempty(ifft_size) || ...
(rem(log2(ifft_size),1) = 0 || ifft_size < 8))
ifft_size = input('IFFT size: ');
if (isempty(ifft_size) || ...
(rem(log2(ifft_size),1) = 0 || ifft_size < 8))
disp('IFFT size must be at least 8 and power of 2.')
end end
% number of carriers carrier_count = ifft_size; % force into the while loop below while (isempty(carrier_count) || ...
(carrier_count>(ifft_size/2-2)) || carrier_count<2)
carrier_count = input('Number of carriers: ');
if (isempty(carrier_count) || (carrier_count > (ifft_size/2-2)))
disp('Must NOT be greater than ("IFFT size"/2-2)')
end end
% bits per symbol (1 = BPSK, 2=QPSK, 4=16PSK, 8=256PSK)
symb_size = 0; % force into the while loop below while (isempty(symb_size) || ...
(symb_size=1 && symb_size=2 && symb_size=4 && symb_size=8))
symb_size = input...
('Modulation(1=BPSK, 2=QPSK, 4=16PSK, 8=256PSK): ');
if (isempty(symb_size) || ...
(symb_size=1&&symb_size=2&&symb_size=4&&symb_size=8))
disp('Only 1, 2, 4, or 8 can be choosen')
end end
126
% channel clipping in dB
clipping = [];
while isempty(clipping)
clipping = input('Amplitude clipping introduced by communication channel
(in dB):');
end
% signal to noise ratio in dB
SNR_dB = [];
while isempty(SNR_dB)
SNR_dB = input('Signal-to-Noise Ratio (SNR) in dB: ');
end word_size = 8; % bits per word of source data (byte)
guard_time = ifft_size/4; % length of guard interval for each symbol period
% 25% of ifft_size
% number of symbols per carrier in each frame for transmission symb_per_frame = ceil(2^13/carrier_count);
% === Derived Parameters === %
% frame_len: length of one symbol period including guard time symb_period = ifft_size + guard_time;
% head_len: length of the header and trailer of the transmitted data head_len = symb_period*8;
% envelope: symb_period/envelope is the size of envelope detector envelope = ceil(symb_period/256)+1;
% === carriers assigned to IFFT bins === %
% spacing for carriers distributed in IFFT bins spacing = 0;
while (carrier_count*spacing) <= (ifft_size/2 - 2)
spacing = spacing + 1;
end spacing = spacing - 1;
% spead out carriers into IFFT bins accordingly midFreq = ifft_size/4;
first_carrier = midFreq - round((carrier_count-1)*spacing/2);
last_carrier = midFreq + floor((carrier_count-1)*spacing/2);
carriers = [first_carrier:spacing:last_carrier] + 1;
conj_carriers = ifft_size - carriers + 2;
127
% ************* FUNCTION: ofdm_base_convert() ************* %
% This function converts data from one base to another.
% "Base" refers to number of bits the symbol/word uses to represent data.
function data_out = ofdm_base_convert(data_in, base, new_base)
% if new base is in a higer order than the current base,
% make the size of data in current base a multiple of its new base if new_base>base data_in = data_in(1:...
floor(length(data_in)/(new_base/base))*(new_base/base));
end
% base to binary for k=1:base binary_matrix(k,:) = floor(data_in/2^(base-k));
data_in = rem(data_in,2^(base-k));
end
% format the binary matrix to fit dimensions of the new base newbase_matrix = reshape(binary_matrix, new_base, ...
size(binary_matrix,1)*size(binary_matrix,2)/new_base);
% binary to new_base data_out = zeros(1, size(newbase_matrix,2));
for k=1:new_base data_out = data_out + newbase_matrix(k,:)*(2^(new_base-k));
end
% ************* FUNCTION: ofdm_modulation() ************* %
% This function performance the OFDM modulation before data transmission.
function signal_tx = ofdm_modulate(data_tx, ifft_size, carriers, ...
conj_carriers, carrier_count, symb_size, guard_time, fig)
% symbols per carrier for this frame carrier_symb_count = ceil(length(data_tx)/carrier_count);
% append zeros to data with a length not multiple of number of carriers if length(data_tx)/carrier_count = carrier_symb_count,
padding = zeros(1, carrier_symb_count*carrier_count);
padding(1:length(data_tx)) = data_tx;
data_tx = padding;
end
% serial to parellel: each column represents a carrier data_tx_matrix = reshape(data_tx, carrier_count, carrier_symb_count)';
% --------------------------------- %
% ##### Differential Encoding ##### %
% --------------------------------- %
% an additional row and include reference point carrier_symb_count = size(data_tx_matrix,1) + 1;
1 2 3 4 5 6 7
diff_ref = round(rand(1, carrier_count)*(2^symb_size)+0.5);
128 data_tx_matrix = [diff_ref; data_tx_matrix];
for k=2:size(data_tx_matrix,1)
data_tx_matrix(k,:) = ...
rem(data_tx_matrix(k,:)+data_tx_matrix(k-1,:), 2^symb_size);
end
% ------------------------------------------ %
% ## PSK (Phase Shift Keying) modulation ### %
% ------------------------------------------ %
% convert data to complex numbers:
% Amplitudes: 1; Phaes: converted from data using constellation mapping
[X,Y] = pol2cart(data_tx_matrix*(2*pi/(2^symb_size)), ...
ones(size(data_tx_matrix)));
complex_matrix = X + i*Y;
% ------------------------------------------------------------ %
% ##### assign IFFT bins to carriers and imaged carriers ##### %
% ------------------------------------------------------------ %
spectrum_tx = zeros(carrier_symb_count, ifft_size);
spectrum_tx(:,carriers) = complex_matrix;
spectrum_tx(:,conj_carriers) = conj(complex_matrix);
% Figure(1) and Figure(2) can both shhow OFDM Carriers on IFFT bins if fig==1
figure(1)
stem(1:ifft_size, abs(spectrum_tx(2,:)),'b*-')
grid on axis ([0 ifft_size -0.5 1.5])
ylabel('Magnitude of PSK Data')
xlabel('IFFT Bin')
title('OFDM Carriers on designated IFFT bins')
figure(2)
plot(1:ifft_size, (180/pi)*angle(spectrum_tx(2,1:ifft_size)), 'go')
hold on grid on stem(carriers, (180/pi)*angle(spectrum_tx(2,carriers)),'b*-')
stem(conj_carriers, ...
(180/pi)*angle(spectrum_tx(2,conj_carriers)),'b*-')
axis ([0 ifft_size -200 +200])
ylabel('Phase (degree)')
xlabel('IFFT Bin')
title('Phases of the OFDM modulated Data')
end
% --------------------------------------------------------------- %
% ##### obtain time wave from spectrums waveform using IFFT ##### %
% --------------------------------------------------------------- %
signal_tx = real(ifft(spectrum_tx'))';
% plot one symbol period of the time signal to be transmitted if fig==1
% OFDM Time Signal (1 symbol period in one carrier)
limt = 1.1*max(abs(reshape(signal_tx',1,size(signal_tx,1)...
*size(signal_tx,2))));
figure (3)
plot(1:ifft_size, signal_tx(2,:))
grid on axis ([0 ifft_size -limt limt])
ylabel('Amplitude')
xlabel('Time')
title('OFDM Time Signal (one symbol period in one carrier)')
129
% OFDM Time Signal (1 symbol period in a few samples of carriers)
figure(4)
colors = ['b','g','r','c','m','y'];
for k=1:min(length(colors),(carrier_symb_count-1))
plot(1:ifft_size, signal_tx(k+1,:))
plot(1:ifft_size, signal_tx(k+1,:), colors(k))
hold on end grid on axis ([0 ifft_size -limt limt])
ylabel('Amplitude')
xlabel('Time')
title('Samples of OFDM Time Signals over one symbol period')
end
% ------------------------------------- %
% ##### add a periodic guard time ##### %
% ------------------------------------- %
end_symb = size(signal_tx, 2); % end of a symbol period without guard signal_tx = [signal_tx(:,(end_symb-guard_time+1):end_symb) signal_tx];
% parellel to serial signal_tx = signal_tx'; % MATLAB's reshape goes along with columns signal_tx = reshape(signal_tx, 1, size(signal_tx,1)*size(signal_tx,2));
% ************* FUNCTION: ofdm_frame_detect() ************* %
% This function is to synchronize the received signal before demodulation
% by detecting the starting point of a frame of received signal.
function start_symb = ofdm_frame_detect(signal, symb_period, env, label)
% Find the approximate starting location signal = abs(signal);
% ===== narrow down to an approximate start of the frame ===== %
idx = 1:env:length(signal);
samp_signal = signal(idx); % sampled version of signal mov_sum = filter(ones(1,round(symb_period/env)),1,samp_signal);
mov_sum = mov_sum(round(symb_period/env):length(mov_sum));
apprx = min(find(mov_sum==min(mov_sum))*env+symb_period);
% move back by approximately 110% of the symbol period to start searching idx_start = round(apprx-1.1*symb_period);
% ===== look into the narrow-downed window ===== %
mov_sum = filter(ones(1,symb_period),1,...
signal(idx_start:round(apprx+symb_period/3)));
130 mov_sum = mov_sum(symb_period:length(mov_sum));
null_sig = find(mov_sum==min(mov_sum));
start_symb = min(idx_start + null_sig + symb_period) - 1;
% convert to global index start_symb = start_symb + (label - 1);
% ************* FUNCTION: ofdm_demod() ************* %
% This function performs OFDM demodulation after data reception.
function [decoded_symb, decoded_phase] = ofdm_demod...
(symb_rx, ifft_size, carriers, conj_carriers, ...
guard_time, symb_size, word_size, last, unpad, fig)
symb_period = ifft_size + guard_time;
% reshape the linear time waveform into fft segments symb_rx_matrix = reshape(symb_rx(1:...
(symb_period*floor(length(symb_rx)/symb_period))), ...
symb_period, floor(length(symb_rx)/symb_period));
% ------------------------------------------ %
% ##### remove the periodic time guard ##### %
% ------------------------------------------ %
symb_rx_matrix = symb_rx_matrix(guard_time+1:symb_period,:);
% ------------------------------------------------------------------ %
% ### take FFT of the received time wave to obtain data spectrum ### %
% ------------------------------------------------------------------ %
rx_spectrum_matrix = fft(symb_rx_matrix)';
% plot magnitude and phase of the received frequency spectrum if fig==1
limt = 1.1*max(abs(reshape(rx_spectrum_matrix',1,...
size(rx_spectrum_matrix,1)*size(rx_spectrum_matrix,2))));
figure(5)
stem(0:ifft_size-1, abs(rx_spectrum_matrix(ceil...
(size(rx_spectrum_matrix,1)/2),1:ifft_size)),'b*-')
grid on axis ([0 ifft_size -limt limt])
ylabel('Magnitude')
xlabel('FFT Bin')
title('Magnitude of Received OFDM Spectrum')
figure(6)
plot(0:ifft_size-1, (180/pi)*angle(rx_spectrum_matrix(ceil...
(size(rx_spectrum_matrix,1)/2),1:ifft_size)'), 'go')
hold on stem(carriers-1, (180/pi)*angle(rx_spectrum_matrix(2,carriers)'),'b*-')
stem(conj_carriers-1, (180/pi)*angle(rx_spectrum_matrix(ceil...
(size(rx_spectrum_matrix,1)/2),conj_carriers)),'b*-')
axis ([0 ifft_size -200 +200])
grid on ylabel('Phase (degrees)')
xlabel('FFT Bin')
title('Phase of Receive OFDM Spectrum')
end
% ----------------------------------------------------------------- %
131
% ### extract columns of data on IFFT bins of all carriers only ### %
% ----------------------------------------------------------------- %
rx_spectrum_matrix = rx_spectrum_matrix(:,carriers);
% --------------------------------------------- %
% ### PSK (Phase Shift Keying) demodulation ### %
% --------------------------------------------- %
% calculate the corresponding phases from the complex spectrum rx_phase = angle(rx_spectrum_matrix)*(180/pi);
% make negative phases positive rx_phase = rem((rx_phase+360), 360);
% polar plot for the received symbols if fig==1
figure(7)
rx_mag = abs(rx_spectrum_matrix(ceil(size(rx_spectrum_matrix,1)/2),:));
polar(rx_phase(ceil(size(rx_spectrum_matrix,1)/2),:)*(pi/180), ...
rx_mag, 'bd')
title('Received Phases')
end
% --------------------------------- %
% ##### Differential Decoding ##### %
% --------------------------------- %
% reverse the differential coding decoded_phase = diff(rx_phase);
% make negative phases positive decoded_phase = rem((decoded_phase+360), 360);
% parellel to serial conversion of phases decoded_phase = reshape(decoded_phase', ...
1, size(decoded_phase,1)*size(decoded_phase,2));
% phase-to-data classification base_phase = 360/(2^symb_size);
% phase-to-data translation decoded_symb = ...
floor(rem((decoded_phase/base_phase+0.5),(2^symb_size)));
% obtain decoded phases for error calculations decoded_phase = rem(decoded_phase/base_phase+0.5, ...
(2^symb_size))*base_phase - 0.5*base_phase;
% remove padded zeros during modulation if last==1
decoded_symb = decoded_symb(1:(length(decoded_symb)-unpad));
decoded_phase = decoded_phase(1:(length(decoded_phase)-unpad));
end
132
ПРИЛОЖЕНИЕ F
РЕЗУЛЬТАТ ЭКСПЕРИМЕНТАЛЬНОЙ ЧАСТИ
133
134
ПРИЛОЖЕНИЕ G
РЕЗУЛЬТАТЫ ИССЛЕДОВАНИЯ
135
136
ПРИЛОЖЕНИЕ H
ПЕЧАТНАЯ ПЛАТА УСТРОЙСТВА ПИТАНИЯ
137
138
139