Перейти к содержанию
    

Методы определения модуляции сигнала.

Здравствуйте. Вопрос наверно будет звучать глупо, но найти на него ответ я не могу.

Так вот, имеется запись сырого (RAW IQ) сигнала длиной 10 с. Запись производилась с использованием обычного китайского dvb-t-dab+fm приемника и программы SDRSharp (Airspy, SDR#). Частота дискретизации составляет 3.2 МГц, запись 16 бит. 

Произведя запись данного сигнала я задался вопросом о попытки его демодуляции. Для начала хотелось бы узнать о том как можно определить например какая модуляция применяется в данном сигнале по I и Q компонентам. К вопросу прикладывают спектр I и Q компонент полученных из эфира. И возможно ли определить метод модуляции сигнала по его спектру?

Используя матлаб смог демодулировать FM сигнал с радиостанции.

Сразу хочу попросить прощения, но запись сигнала отправить не смогу!!

Заранее хочу поблагодарить за ответы, комментарии и критику!!!

спектр.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

промежуточную частоту и полосу сигнала вы увидеть уже можете, попробуйте снести сигнал на нулевую частоту (убрать модуляцию) через комплексное умножение на exp(2*pi*[1:1:length]*f/fs + ph), где f - промежуточная частота

далее, как уберете промежуточную частоту (визуально во временной области) можно уже будет разглядеть символы

можно покрутить начальную фазу ph, чтобы крутить фазовое смещение I/Q

PS для отображения спектра пользуйтесь функцией pwelch из матлаба и стройте спектр комплексного сигнала, а не отдельно I и Q.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

14 часов назад, quato_a сказал:

промежуточную частоту и полосу сигнала вы увидеть уже можете, попробуйте снести сигнал на нулевую частоту (убрать модуляцию) через комплексное умножение на exp(2*pi*[1:1:length]*f/fs + ph), где f - промежуточная частота

Тогда такой вопрос. В приложении SDR# при записи RAW говорится о том, что запись производится в IQ. Так как тогда мы получаем две компоненты не смещенные на нулевую частоту? Для меня просто это как разрыв шаблона. В теории изучал одно, а получается другое. Т.е. необходимо и эту полосу сместить на 0?

14 часов назад, quato_a сказал:

через комплексное умножение на exp(2*pi*[1:1:length]*f/fs + ph)

Я так понимаю f/fs вы нормируете сигнал и полоса получается от 0 до pi/2?

Только тут же сигнал не нормирован и необходимо f/fs сделать центральной частотой?

14 часов назад, quato_a сказал:

PS для отображения спектра пользуйтесь функцией pwelch из матлаба

Для того чтобы избавиться от шумов?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

14 часов назад, quato_a сказал:

далее, как уберете промежуточную частоту (визуально во временной области) можно уже будет разглядеть символы

По предположениям данная вещь вещает с использованием амплитудной модуляции, но это не точно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, Nik_Su said:

Тогда такой вопрос. В приложении SDR# при записи RAW говорится о том, что запись производится в IQ. Так как тогда мы получаем две компоненты не смещенные на нулевую частоту? Для меня просто это как разрыв шаблона. В теории изучал одно, а получается другое. Т.е. необходимо и эту полосу сместить на 0?

да, если приемник выдает с АЦП I/Q компоненты, то это приемник прямого переноса на baseband (нулевую частоту), но в вашем случаем может быть несущие передатчика и приемника значительно не совпали

 

2 hours ago, Nik_Su said:

Я так понимаю f/fs вы нормируете сигнал и полоса получается от 0 до pi/2?

Только тут же сигнал не нормирован и необходимо f/fs сделать центральной частотой?

f/fs - это инкремент фазы, такой записью exp(1i * 2*pi * [1:1:length] * f/fs + ph) я синтезирую массив длиной length сигнала cos+1i*sin частотой f при частоте дискретизации fs

да, в предыдущем посте забыл добавить мнимую единицу 1i

 

2 hours ago, Nik_Su said:

Для того чтобы избавиться от шумов?

нет, для отображения спектральной плотности мощности PSD, где по х будет частота в Гц, а по y уровень сигнала в дБ

у вас график спектра изображен с непонятными величинами по x и y, и еще с зеркальной составляющей

пример функции:

window = 300;
noverlap = 100;
nfft = 2^10;
[pxx,f] = pwelch(IQ,window,noverlap,nfft,fs,'centered','power');

figure;
plot(f,10*log10(pxx)); grid on;
xlabel('Frequency, MHz');
ylabel('Magnitude, dB');
title('PSD');

 
2 hours ago, Nik_Su said:

По предположениям данная вещь вещает с использованием амплитудной модуляции, но это не точно.

можно еще продецимировать сигнал через downsample(x,R) в несколько раз и визуально посмотреть на результат. если амплитудная модуляция, то ее можно заметить визуально

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, quato_a сказал:

f/fs - это инкремент фазы, такой записью exp(1i * 2*pi * [1:1:length] * f/fs + ph) я синтезирую массив длиной length сигнала cos+1i*sin частотой f при частоте дискретизации fs

да, в предыдущем посте забыл добавить мнимую единицу 1i

Я бегло посмотрел запись и не разобрался в ней. Сейчас понял суть. Я не много не так делаю.

t = 0:1/Fs:x; y = sin(2*pi*f.*t);

1 час назад, quato_a сказал:

нет, для отображения спектральной плотности мощности PSD, где по х будет частота в Гц, а по y уровень сигнала в дБ

у вас график спектра изображен с непонятными величинами по x и y, и еще с зеркальной составляющей

пример функции:

Я просто не подписал оси ох и оу. По оси ох у меня частота ненормированная а по оу модуль |H(jw)|.

В спектре нет зеркальной составляющей если я правильно понял вас которая образуется в после Fs/2 частоты Найквиста. Этот реальная часть преобразования abs(fft). Даже при выделении сигнала в программе SDR# были видны два пика и несущая. Чуть чуть позже скину спектр построенный с использованием  pwelch. Возможно там используется АМ с подавлением несущей. Но это пока догадки на основе прочитанной литературы. Большое спасибо за ответы и помощь!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

23 часа назад, quato_a сказал:

PS для отображения спектра пользуйтесь функцией pwelch из матлаба и стройте спектр комплексного сигнала, а не отдельно I и Q.

Я не стал центровать сигнал вокруг нулевой частоты.

Использовал данный метод

[pxx,f] = pwelch(tee,512,256,2048,Fs,'power');

plot(f,10*log10(pxx));

figure2.jpg

figure.jpg

5 часов назад, quato_a сказал:

можно еще продецимировать сигнал через downsample(x,R) в несколько раз и визуально посмотреть на результат. если амплитудная модуляция, то ее можно заметить визуально

Для децимации сигнала я применяю функцию decimate. В ней уже имеется fir фильтр который нужен для удаления эффекта алиасинга.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

04.08.2021 в 22:53, quato_a сказал:

похоже на FSK2 модуляцию

Я почитал литературу по поводу FSK, а именно Low-SNR Operation of FSK Demodulators и на сайте dsplib. Как раз в книге которую я написал первую там представлен спектр сигнала один в один как мой и там как раз сказано об обработке данного сигнала, выделения его. Использовал схему по выделения FM. И получилось у меня выделить поток бит. Вы можете подсказать как преобразовать данный поток именно в вид чисел.

untitled.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, Nik_Su said:

Вы можете подсказать как преобразовать данный поток именно в вид чисел.

Ну из этого максимум можно получить битовый поток. Например, если большая частота - это передавался 0, а меньшая частота - 1, то есть если demod(t) > 0, то bit(t) = 0, иначе bit(t) = 1. А может и наоборот: если demod(t) > 0, то bit(t) = 1, иначе bit(t) = 0.

Но вы же не знаете в каком формате кодировались биты. А тем более не знаете формат пакетов, состоящий из этих битов: преамбулы, размер пакетов, квитирование, crc и т.п.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, quato_a сказал:

Ну из этого максимум можно получить битовый поток

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 minutes ago, Nik_Su said:

После чего переводился в формат 1 либо ноль

Определите сколько примерно сэмплов в символе (можно по самому короткому положительному или отрицательному импульсу), далее определите центральный значищий сэмпл в символе и его захватывайте в массив значащих отсчетов demod.

Далее demod(t) > 0, то bit(t) = 0, иначе bit(t) = 1.

И получите массив битового потока.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 hours ago, Nik_Su said:

И получилось у меня выделить поток бит. Вы можете подсказать как преобразовать данный поток именно в вид чисел.

 

самое простое

y = downsample(x,n,phase);

ну и

z=sign(y)/2+0.5;

 

более сложно - что-то подобное навернуть:

% N           - Len of bytes read 
% Fs          - Sample rate 
% Fd          - Data rate 
% v2          - input bytes
% v3          - output doubles 
%% ------------------------------------------------------------------------
T=Fs/Fd
N_sync=fix(N/T);
v3=zeros(N_sync,1);

T100=fix(T+1);
T050=fix(T/2);
T125=fix(T+T/4);

D=double(xor(v2(1),1)); L=0; K=0; 
for a1 = 2:N_byte
    if (D~=v2(a1))
        K=0;
        D=v2(a1);
    else
        K=K+1;
        if (K==T050)
            L=L+1;
            v3(L)=D;
        end
        if (K>T125)
            K=K-T100;
        end
    end

end 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

06.08.2021 в 17:57, quato_a сказал:

Определите сколько примерно сэмплов в символе (можно по самому короткому положительному или отрицательному импульсу), далее определите центральный значищий сэмпл в символе и его захватывайте в массив значащих отсчетов demod.

Далее demod(t) > 0, то bit(t) = 0, иначе bit(t) = 1.

И получите массив битового потока.

 

06.08.2021 в 13:51, Nik_Su сказал:

untitled.jpg

Если вам интересно, я реализовал такой алгоритм для выделения из представленного потока нулей и единиц.

 

 

static void Main(string[] args)
        {

            //Читаем из файла данные
            List<string> vs = new List<string>();
            string readPath = @"путь к файлу с данными.txt";
            string line_;
            try
            {
                using (StreamReader streamReader = new StreamReader(readPath))
                {
                    while ((line_ = streamReader.ReadLine()) != null) { vs.Add(line_); }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine($"ИСключение: {e.Message}");
            }



            //Основная программа

            // Количество единиц в потоке
            int one_ = 0;

            // Кол - о нулей в потоке
            int zero_ = 0;

            // Средняя длина символа
            int average_lengh_simb = 35;

            // Счетчик символов
            //int count = 1;

            // Выходной массив данных
            List<int> out_arr = new List<int>();

            // Предыдущее значение пишедшее из потока
            // может иметь значение либо 0 либо 0.06
            double previus_num_from_stream = 0;


            //Обычный склад мусора для постоянного удаления
            double Y = 0;

            //
            double tresh = 0;

            int count = 0;


            foreach (string i in vs)
            {
                if (previus_num_from_stream != Convert.ToDouble(Double.Parse((i.Substring(0, i.Length - 4)).Replace('.', ','))))
                {

                    if (previus_num_from_stream == 0.06)
                    {
                        Y = one_ / average_lengh_simb;
                        if (Y > 0.7 || Y > 1.7 || Y > 2.7 || Y > 3.7 || Y > 4.7 || Y > 5.7 || Y > 6.7 || Y > 7.7 || Y > 8.7 || Y > 9.7 || Y > 10.7 || Y > 11.7 || Y > 12.7 || Y > 13.7 || Y > 14.7 || Y > 15.7)
                        {
                            for (int j = 0; j < Math.Ceiling(Y); j++)
                            {
                                out_arr.Add(1);
                            }
                        }
                        Y = 0;
                        one_ = 0;
                    }

                    if (previus_num_from_stream == 0)
                    {
                        Y = zero_ / average_lengh_simb;
                        if (Y > 0.7 || Y > 1.7 || Y > 2.7 || Y > 3.7 || Y > 4.7 || Y > 5.7 || Y > 6.7 || Y > 7.7 || Y > 8.7 || Y > 9.7 || Y > 10.7 || Y > 11.7 || Y > 12.7 || Y > 13.7 || Y > 14.7 || Y > 15.7)
                        {
                            for (int j = 0; j < Math.Ceiling(Y); j++)
                            {
                                out_arr.Add(0);
                            }
                        }
                        Y = 0;
                        zero_ = 0;
                    }

                }
                if (Double.Parse((i.Substring(0, i.Length - 4)).Replace('.', ',')) == 0.06)
                {
                    one_++;
                }

                if (Double.Parse((i.Substring(0, i.Length - 4)).Replace('.', ',')) == 0)
                {
                    zero_++;
                }
                previus_num_from_stream = Double.Parse((i.Substring(0, i.Length - 4)).Replace('.', ','));
            }


            string writerPath = @"Путь к файлу для сохранения.txt";

            using (StreamWriter streamWriter = new StreamWriter(writerPath,false, System.Text.Encoding.Default))
            {
                foreach(double i in out_arr) { streamWriter.WriteLine(i); }
            }

            Console.WriteLine("Все отработало нормально!!");
        }
    }

 

Только что, Nik_Su сказал:

Если вам интересно, я реализовал такой алгоритм для выделения из представленного потока нулей и единиц.

К слову отрабатывает в 95% у меня. Средняя длина символа была вычислена путем поиска самых коротких импульсов и нахождения среднего из суммы их длины. Конкретно была взята длина 10 символов.

3 минуты назад, Nik_Su сказал:

Если вам интересно, я реализовал такой алгоритм для выделения из представленного потока нулей и единиц.

Также импульсы были сглажены путем применения функции smooth в matlab, а именно сигнал был пропущен через фильтр экспоненциального скользящего среднего. Также был получен однополярный сигнал, обрезана отрицательная часть и получены ровные импульсы. С зашумленным сигналом мой алгоритм не работает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, Nik_Su said:

К слову отрабатывает в 95% у меня. Средняя длина символа была вычислена путем поиска самых коротких импульсов и нахождения среднего из суммы их длины. Конкретно была взята длина 10 символов.

совсем не понятен мат алгоритм, по которому происходило выделение нулей и единиц)))

почему же только 95%? остальные случаи зашумлены?

 

может иметь значение либо 0 либо 0.06
            

какие-то магические константы

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...