В заключительной части КП перед нами стоит задача разработки программы имитирующей передачу и прием одного из сообщений нашей системы. Рассмотрим сообщение, передаваемое от светильника на ТУС, содержащее данные о мощности потребления, температуре излучающей поверхности и температуре источника питания. На рисунке 1 представлен вид сообщения на канальном уровне.


Рисунок 1. Структура сообщения на канальном уровне.

После кодирования блочным кодом БЧХ сообщение имеет размер 127 бит. Однако нам нужно прибавить еще один бит для того чтобы размер сообщения стал равным степени двойки.

Параметры.

В файле initSettings.m задаются параметры, используемые в программе, а также информационные данные, которые необходимо передать.

% Информационные параметры, передаваемые в сообщении

set.power = 0900; % мощность, потребляемая светильником

set.tempr1 = 0030; % температура излучающей панели

set.tempr2 = 0040; % температура источника питания

 

% Другие параметры полей пакета канального уровня

set.number_of_lighter = 200; % уникальный номер светильника (УН)

set.type_of_mes = 63; % индикатор информационного пакета

set.begin_of_mes = 0; % индикатор начала пакета

 

% Позиционность модуляции - QPSK

set.mPos = 4;

 

% Параметры БЧХ кода

set.n = 127; % размер после кодирования

set.k = 64; % размер до кодирования

 

% Параметры CRC

set.poly=[1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0];

[set.x set.y]=size(set.poly); %размерность полинома

 

% переменная, равная длине передаваемого сообщения канального уровня

% без поля контрольной суммы

set.length_msg_Lev2 = 48;

 

Передатчик.

В файле transmitter.m реализована программа передатчика.

% установка параметров модели

st=initSettings();

 

% Открытие файлов на запись и получение их идентификаторов

[fidw, message] = fopen(st.SignalFileName, 'wb');

[fidw2, message] = fopen(st.SignalFileName2, 'wb');

 

%% ================== Канальный  уровень ================================

 

% Подготовка к передаче сообщения

 

% Перевод параметров, передаваемых в сообщении в двоичную систему счисления

power = my_de2bi(st.power,'left_msb',10); % мощность потребления светильника

tempr1 = my_de2bi(st.tempr1,'left_msb',10); % температура излучающей панели

tempr2 = my_de2bi(st.tempr2,'left_msb',10); % температура источника питания

number_of_lighter = my_de2bi(st.number_of_lighter,'left_msb',8); % уникальный номер светильника (УН)

type_of_mes = my_de2bi(st.type_of_mes,'left_msb',6); % индикатор информационного пакета

begin_of_mes = my_de2bi(st.begin_of_mes,'left_msb',4); % индикатор начала пакета


Рисунок 2. Просмотр значения параметра, переведенного в двоичную систему счисления.

 

            Далее мы собираем пакет физического уровня воедино и рассчитываем значение поля контрольной суммы.

 

% сборка сообщения канального уровня

msg_Lev2 = [begin_of_mes number_of_lighter type_of_mes power tempr1 tempr2];

 

% получение CRC кода

m=[msg_Lev2 zeros(1,st.y-1)]; % вставка нулей в поле CRC

% Поиск частного и остатка от деления информационной части

% на порождающий полином CRC кода

[q r] = deconv(m,st.poly);

r = mod(abs(r),2);

CRC = r(st.length_msg_Lev2 + 1:end);%расчет CRC

  

     Присоединяем поле CRC к нашему пакету, полученному ранее.

 

% сборка сообщения

msg_Lev1 = [msg_Lev2 CRC];

trx = msg_Lev1;


Рисунок 3. Размер и содержание пакета канального уровня.

 

%% ================== Физический уровень ================================

 

            Полученное на канальном уровне сообщения необходимо закодировать с помощью блочного кода БЧХ с параметрами (127, 64), которые прописываются в файле initSettings.m.

 

% Помехоустойчивое кодирование БЧХ

 

code_word = encode(trx,st.n,st.k,'bch/binary');

 

% Добавление к сообщению нулевого бита с целью

% приведения длины сообщения к величине, кратной степени 2

code_word = [code_word 0]';

 

     В результате этих операций размер пакета увеличится до 128 битов.

 

Рисунок 4. Размер пакета после помехоустойчивого кодирования.

           

Далее сообщение модулируется, после чего передается в канал, где на подвергается воздействию шумов.

 

% Модуляция

h = modem.pskmod(st.mPos); % h - модем PSK с позиционностью mPos

 

% Параметры модуляции

h.inputtype = 'bit';

h.SymbolOrder = 'gray';

h.PhaseOffset = pi/3;

 

% собственно модуляция

IQ_signal = modulate(h, code_word);

    

% Наложение шума на сигнал

noise_sgn = awgn(IQ_signal,10);

 

% Запись действительной и мнимой частей сигнала

% в соответствующие двоичные файлы

fwrite(fidw,real(noise_sgn),'double');

fwrite(fidw2,imag(noise_sgn),'double');

 

% отображение сигнально-кодового созвездия

figure(10);

plot(noise_sgn,'.');


Рисунок 5. Сигнально-кодовое созвездие.

 

Приемник.

 

function  [R_message error] = Receiver()

%% ================== Физический уровень ================================

 

% установка параметров модели

st = initSettings();

 

% инициализация переменной, в которой будут сохраняться

% принимаемаемая информация

R_message = '';

 

% Параметры демодуляции

h = modem.pskdemod(st.mPos);

h.SymbolOrder = 'gray';

h.PhaseOffset = pi/3;

h.OutputType = 'bit';

 

% Открытие файлов на чтение и получение их идентификаторов

[fid, message] = fopen(st.SignalFileName, 'rb');

[fid2, message] = fopen(st.SignalFileName2, 'rb');

 

% Чтение действительной и мнимой частей сигнала

signal_real = fread(fid,'double')';

signal_image = fread(fid2,'double')';

         

% Представление сигнала в комплексной форме  

noise_sgn = complex(signal_real, signal_image);

  

Принятое сообщение демодулируется и декодируется.

 

% демодуляция

code_word = demodulate(h,noise_sgn);

 

%Устранение лишнего нулевого бита

code_word = code_word(1:127);

   

%Декодирование

received_mes_L1 = decode(code_word,st.n,st.k,'bch/binary',st.errocorr);

 

     После этих операций мы получаем наше сообщение канального уровня на приемной стороне. Его размер и содержание совпадают с аналогичными параметрами сообщения, которое было передано. Это видно из рисунков 3 и 6.


Рисунок 6. Сообщение канального уровня, полученное на приемной стороне после демодуляции и декодирования.

 

%% ================== Канальный  уровень ================================

 

     Далее необходимо проверить, нет ли ошибок в принятом сообщении. Для этого вычисляется значение поля контрольной суммы.

 

% Подготовка к проверке CRC

[q r]=deconv(received_mes_L1,st.poly);

 

% Проверка остатка

r = mod(abs(r),2);

if r == zeros(1,length(received_mes_L1))

     detect=0;% ошибок нет

else

     error = error + 1;

     detect=1;% обнаружены ошибки

end;

 

     После этого поле контрольной суммы отбрасывается.

                                                                

% Принятое сообщение

received_mes_L2 = received_mes_L1(1:st.length_msg_Lev2);

 

     Затем мы извлекаем информационные параметры из принятого сообщения и переводим их в привычную для восприятия человека десятичную систему счисления.

 

% Преобразование принятых параметров в десятичную систему счисления

number_of_lighter = my_bi2de(received_mes_L2(5:12),'left_msb');

power = my_bi2de(received_mes_L2(19:28),'left_msb');

tempr1 = my_bi2de(received_mes_L2(29:38),'left_msb');

tempr2 = my_bi2de(received_mes_L2(39:48),'left_msb');


Рисунок 7. Просмотр значения параметра, переведенного в десятичную систему счисления.

  

% Вывод информации на экран

R_message = [number_of_lighter power tempr1 tempr2];

 

     После этого на экране отразятся параметры светильника, где первым числом будет его уникальный номер, вторым – потребляемая мощность, третьим – температура излучающей поверхности, четвертым – температура источника питания.

 

ans =

 

   200   900    30    40


Литература.

1.      Текст программы в полном объеме http://radiolay.ru/download/file.php?id=351

2.      Третья часть КП  http://omoled.ru/publications/view/345

3.      Вторая часть КП http://omoled.ru/publications/view/325

4.      Первая часть КП http://omoled.ru/publications/view/319

5.      А.В. Бакке. «Лекции по курсу ССПО», Рязань, РГРТУ 2012.