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

Вытащить биты из фазового демодулятора

repstosw

Могли бы и на этом форуме найти не заумные рассуждения, а какой-никакой практический толк формализованный, который можно конструктивно обсудить, хотя бы по той же синхронизации, замираниям.

Вы определитесь, вам просто пытаться или сделать то что нужно для решения, в GSM канал оценивают и эквалайзер Витерби применяют для того чтобы гнуть пальцы и демонстрировать свою крутость, раздувают из мухи слона, или подобные решения есть во всех цифровых средствах связи в подобных условиях?

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


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

7 hours ago, petrov said:

Могли бы и на этом форуме найти не заумные рассуждения, а какой-никакой практический толк формализованный, который можно конструктивно обсудить, хотя бы по той же синхронизации, замираниям.

Прочитайте название темы.  Причём тут замирания?

Нужно получить битовый поток из сигнала модулятора.  Про замирания - в других темах.

 

7 hours ago, petrov said:

Вы определитесь, вам просто пытаться или сделать то что нужно для решения

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

Мои цели - отказаться от встроенного модема Si4463 и научиться находить битовый поток с отсчётов фазы демодулятора. Задача как я понял, не тривиальная.

При этом мне нужны не просто биты в виде 0 и 1,  а результат в виде мягких решений: [0.0...1.0], для того, чтобы загнать это на LDPC или Турбо-код.

Хочу поиграться с мягким выходом демодулятора и оценить насколько FEC на мягких решениях более эффективна, чем FEC на жёстких решениях, которая уже работает.

Тоесть, если разбить на под-этапы:

1) Получение сигнала мгновенной частоты с отсчётов фаз

2) Обработка сигнала (фильтрация, клиппинг, интерполяция,...)

3) Обнаружение преамбулы, нахождение тактовой частоты потока бит (сколько отсчётов на бит - среднее,  и плюс-минус)

4) Нахождение синхрослова

5) Получение мягких решений для каждого бита, коррекция тактовой частоты битового потока (на базе алгоритмов корелляции, предсказания, ...)

 

7 hours ago, petrov said:

в GSM канал оценивают и эквалайзер Витерби применяют для того чтобы гнуть пальцы и демонстрировать свою крутость,

Нужна конкретика, а не общие слова...

Тот же эквалайзер Витерби.  Я ничего по нему не нашёл, кроме как хвалебные оды о том, какой он хорош.  А где микросхема этого эквалайзера?  А программная реализация?  Или может мне сразу выломать кусок с сотовой БС  и использовать готовую плату?

К тому же, ЕМНИП эквалайзер Витерби борется с частотно-селективными замираниями.  А у меня плоские замирания.  Так что нужен он мне или нет - ещё большой вопрос.

И MIMO - это тоже мимо для моих целей.   Ставить 4 антенны на передачу (привет, матрица Аламоути!) или на приём - как-то не хочется.   У трубки телефона - 1 сотовая антенна.

 

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

 

Формализую задачу.

 

raw-файл отсчётов фазы (не обработан - прямой забор с демодулятора):   https://dropmefiles.com/aNLMd

 

Дано:  raw-файл с отсчётами фазы, снятыми с демодулятора Si4463.  Каждый отсчёт хранится в байте.  Каждый отсчёт 7-битный знаковый: -64...+63.   Причём знаковый бит - 6-й, а не 7-й (7-й бит пустой и всегда равен 0)

В файле есть участки с принятым пакетом, который содержит:  преамбулу 64 байта, синхрослово 32 байта (значение 0x5A0FBE66 )  и 6080 байт PayLoad (байты от 0 до 255, по возрастанию, повторяются).

 

Параметры модема: модуляция 2FSK, скорость 50 кбит/c, девиация частоты +/-25 кГц, полоса пропускания приемника: 150 кГц.

 

Надо: получить буфер бит данных (6080*8) мягких решений в диапазоне от 0.0 до 1.0.   Допускается использовать мгновенные отсчёты и окна фиксированного размера (для оконных функций, фреймов).

 

Тоесть - обработка данных в оффлайне.

 

на 50 кбит/c обработанные отсчёты фазы (мгновенная частота) смотрятся веселее:

image.thumb.png.a9b34732bcea7d60c1d0597122c6b168.png

image.thumb.png.b037db77cb3699cb43ac915baf3f2abe.png

 

снизу - отсчёты фазы:

image.thumb.png.a089737cc0f73e1fcb7982476c4d4432.png

Изменено пользователем repstosw

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


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

Действительно весело. Это на длительности символа (бита) мгновенная частота к нулю 6 раз возвращается? 

Там, похоже, частота записи в регистр жестко связана с тактовой. То есть, число отсчетов на символ примерно одинаковое для любой скорости передачи. 

Хотя если отсчеты фазы на нижнем графике в той же временной шкале, то просто мгновенная частота неправильно считается.

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


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

1 hour ago, komah said:

Это на длительности символа (бита) мгновенная частота к нулю 6 раз возвращается? 

Да.  Возвраты к нулю происходят от того что иногда соседние отсчёты фазы одинаковы (на скорости 50 кбит/с):

image.thumb.png.1b142ceb4bd8eb02e23e318323a17c42.png

 

Пофиксил отсчёты:   +0+, -0-, +00+, -00-. Значения в нулях - нашёл интерполяцией.

Вот так вышло (рисунок внизу):

image.thumb.png.f4bc01dd04168ca4b545e391f7f9d9e7.png

 

Для +0+ и -0-:

//Step 1: Kill -0-

for(u32 t=0;t<SIZE;t++)if((s[t]<0)&&(s[t-1]==0)&&(s[t-2]<0))
                        {
                         y[t-1]=(s[t]+s[t-2])/2; //-2147483648.0/2;
                        }

for(u32 t=0;t<SIZE;t++)if((s[t]>0)&&(s[t-1]==0)&&(s[t-2]>0))
                        {
                         y[t-1]=(s[t]+s[t-2])/2; //2147483647.0/2;
                        }

 

Для +00+ и -00-:

//Step 2: Kill -00-
 
 for(u32 t=0;t<SIZE;t++)if((s[t]<0)&&(s[t-1]==0)&&(s[t-2]==0)&&(s[t-3]<0))
                        {
                         float k=(s[t]-s[t-3])/3;
                         y[t-2]=s[t-3]+k*1;
                         y[t-1]=s[t-3]+k*2;
                        }

 for(u32 t=0;t<SIZE;t++)if((s[t]>0)&&(s[t-1]==0)&&(s[t-2]==0)&&(s[t-3]>0))
                        {
                         float k=(s[t]-s[t-3])/3;
                         y[t-2]=s[t-3]+k*1;
                         y[t-1]=s[t-3]+k*2;
                        }

 

Каким фильтром это можно сделать?  ФНЧ боюсь срежет скаты, будет плохо.

 

А если ноль между минусами превратить в минимум,  а ноль между плюсами - в максимум,  то получается прямо закраски битов данных дискретно.

 

 

 

В логарифмической шкале ещё лучше:

image.thumb.png.4bdff1045531c5ee3f48ff43775e905a.png

 

Мусор слева:

image.thumb.png.16f0a7c8c57e7507717724ba27539c1f.png

 

Уже можно детектор преамбулы писать! :)))

 

Кстати, что есть мягкое решение для одного бита?   Нормированная площадь отсчётов на 1 бит?

image.png.be4dccfd3c07a7a5f260719163219248.png

Изменено пользователем repstosw

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


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

1 hour ago, komah said:

Там, похоже, частота записи в регистр жестко связана с тактовой. То есть, число отсчетов на символ примерно одинаковое для любой скорости передачи. 

Скорость взятия отсчётов  зависит программы, насколько быстро она может читать регистр. С учётом кольцевой буферизации, DMA и одинакового интервала взятия  отсчётов - 20 машинных циклов 8051,  больше, чем 1 300 000 отсчётов  за 1 секунду - не получить.

Изменено пользователем repstosw

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


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

Удалил повторяющиеся отсчёты из raw-файла.

Теперь соседние отсчёты фазы различны, и мгновенная частота не возвращается к нулю несколько раз.

Очевидно, для скорости 50 кбит/с было пересемплирование.

image.thumb.png.a74567a1d843dd740a86b156b711bc53.png

image.thumb.png.2f2ae84514643c85464f812dfa7a79cf.png

И теперь на 1 бит приходится 12-13 отсчётов всегда:

image.thumb.png.054c19e0bd41638fdb4ba1cac0c8db4a.png

 

Насколько высок потенциал для нахождения мягких решений?

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


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

21 час назад, repstosw сказал:

Какие следующие шаги должны быть?

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

1. Согласованный фильтр. Импульсная характеристика должна соответствовать ИХ фильтра на передаче. Есть вероятность, что он уже присутствует до вычисления фазы. Можно проверить - на передачу выбрать режим FSK, а на приеме сначала FSK, потом GFSK. Если результаты разные, фильтр уже есть.

2. Ресемплер (интерполятор) - на каждый символ должно приходиться целое число отсчетов, например 2.

3. Выбрать метод оценивания ошибки синхронизации. Выбор зависит от числа отсчетов на символ и формы символа (ИХ фильтра). Если предполагается передача настроечной последовательности в каждом пакете, то выбор богаче, но я с такими вариантами дела не имел. Из NDA самые популярные алгоритмы -  Early-Late и Гарднер. Если использовать решения о принятых символах (обратную связь)  - Zero-Crossing.

4. В синхронизаторе присутствует интерполятор (например, на основе pfb), который должен выдавать значение в зависимости от полученной оценки ошибки синхронизации (в пределах интервала времени между отсчетами).

5. Если ИХ фильтра и число отсчетов на символ на входе синхронизатора всегда одни и те же (для любой скорости), п. 1, 2 и 4 можно объединить.

6. Оценка ошибки фильтруется простейшим БИХ - фильтром. Коэффициенты определяют скорость подстройки синхронизатора. 

7. Если накопленная ошибка превышает интервал времени между отсчетами, следующий отсчет пропускается.

8. В схеме с pfb можно реализовать оценку ошибки синхронизации на основе максимального правдоподобия. Для этого делается два банка фильтров - с ИХ==ИХ согласованного фильтра (mf) и с ИХ== производной ИХ согласованного фильтра (dmf).  Оценка ошибки рассчитывается как произведение выходов mf и  dmf. 

9. В итоге, при исходных 8,3 отсчета на символ, синхронизатор будет выдавать 10 выходных отсчетов на 83 входных. То есть, на каждый входной отсчет, будет получаться от 0 до N выходных. N зависит от реализации. 

 

16 минут назад, repstosw сказал:

Насколько высок потенциал для нахождения мягких решений?

Выше некоторых звезд ) Наверное, стоит говорить о потенциале реализации демодулятора, который обеспечит вероятность ошибки на бит не хуже, чем встроенный. 

2 часа назад, repstosw сказал:

Кстати, что есть мягкое решение для одного бита?   Нормированная площадь отсчётов на 1 бит?

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

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


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

36 минут назад, komah сказал:

Нормированная площадь отсчётов на 1 бит?

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

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


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

repstosw

прямой забор с демодулятора

Чтение не синхронизировано с АЦП? Неразличимы одинковые отсчёты и повторы чтения одного и того же отсчёта, выбрасывание истинного отсчёта - сбой синхронизации, на этом можно заканчивать.

_

Мои цели - отказаться от встроенного модема Si4463 и научиться находить битовый поток с отсчётов фазы демодулятора. Задача как я понял, не тривиальная.

Тогда железки в сторону, они только мешают.

_

При этом мне нужны не просто биты в виде 0 и 1,  а результат в виде мягких решений: [0.0...1.0], для того, чтобы загнать это на LDPC или Турбо-код.

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

_

К тому же, ЕМНИП эквалайзер Витерби борется с частотно-селективными замираниями.  А у меня плоские замирания.  Так что нужен он мне или нет - ещё большой вопрос.

Только каким образом так получается, у них и полоса уже и один из модемов на вышке? И дело не в эквалайзере Витерби, любым способом это необходимо решать, каким сможете .

_

И MIMO - это тоже мимо для моих целей.   Ставить 4 антенны на передачу (привет, матрица Аламоути!) или на приём - как-то не хочется.   У трубки телефона - 1 сотовая антенна.

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

_

Нужна конкретика, а не общие слова...

Вот вам конкретика как такие вещи формализуют и изучают, которую вы могли бы найти на этом форуме.

https://electronix.ru/forum/topic/23652-model-8psk-modema/page/10/#comment-818746

https://electronix.ru/forum/topic/23652-model-8psk-modema/page/13/#comment-1755048

https://electronix.ru/forum/topic/23652-model-8psk-modema/page/9/#comment-803139

_

И отсылка к книгам Скляра - это тоже ни о чём.

Готовых решений хорошо описанных никогда нигде не было.

 

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


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

3 hours ago, komah said:

3. Выбрать метод оценивания ошибки синхронизации. Выбор зависит от числа отсчетов на символ и формы символа (ИХ фильтра). Если предполагается передача настроечной последовательности в каждом пакете, то выбор богаче, но я с такими вариантами дела не имел. Из NDA самые популярные алгоритмы -  Early-Late и Гарднер. Если использовать решения о принятых символах (обратную связь)  - Zero-Crossing.

Пока не смотрел ИХ фильтра на GFSK и FSK.

Сделал свой битовый синхронизатор, по крайней мере преамбулу и синхрослово ищет без ошибок :sun_bespectacled: :

//BitStream Engine

u32 b=0;
u32 counter0=0;
u32 counter1=0;

#define THR 12
#define DEL  2

for(u32 i=0;i<SIZE;i++)
{
 if(BufferOut[i]>0) //'1'
 {
  if(counter0)
  {
   if(counter0>=THR-DEL)bitstream[b++]='0';
   counter0=0;
  }

  counter1++;

  if(counter1==THR)
  {
   bitstream[b++]='1';
   counter1=0;
  }

 }
 else
 if(BufferOut[i]<0) //'0'
 {

  if(counter1)
  {
   if(counter1>=THR-DEL)bitstream[b++]='1';
   counter1=0;
  }

  counter0++;

  if(counter0==THR)
  {
   bitstream[b++]='0';
   counter0=0;
  }

 }
}

 

...

Preamble (64 bytes "0101..."):

0101010101010101010101010101010101010101010101010101010101010101
0101010101010101010101010101010101010101010101010101010101010101
0101010101010101010101010101010101010101010101010101010101010101
0101010101010101010101010101010101010101010101010101010101010101
0101010101010101010101010101010101010101010101010101010101010101
0101010101010101010101010101010101010101010101010101010101010101
0101010101010101010101010101010101010101010101010101010101010101
0101010101010101010101010101010101010101010101010101010101010101

Sync:

0101 => 5
1010 => A
0000 => 0
1111 => F
1011 => B
1110 => E
0110 => 6
0110 => 6

Data (0,1,2,3,...,255):

00000000
00000001
00000010
00000011
00000100
00000101
00000110
00000111
00001000
00001001
00001010
00001011
00001100
00001101
00001110
00001111

...

 

Изменено пользователем repstosw

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


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

30 минут назад, repstosw сказал:

Сделал свой битовый синхронизатор, по крайней мере преамбулу и синхрослово ищет без ошибок

Здесь вместо согласованного фильтра интегратор со сбросом (счетчик). Можно обойтись одним сумматором и вычитать отсчет, задержанный на длительность символа, если знак совпадает. Тогда переполнения не будет. Решение принимается по переходу через 0, для 4FSK работать не будет. И даже сам переход по моему не очень правильно ищется. Лучше не по одному отсчету смотреть, а по выходу интегратора. Ну и подстройки тактовой здесь нет. 

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


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

repstosw

Сделал свой битовый синхронизатор

Ничего вы не сделали, это типичный программизм, просто сочинение на тему как я провёл это лето на языке Ц, никакого отношения к ЦОС и тому, что реально нужно сделать, это объективно, а не раздувание из мухи слона, как вам кажется.

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


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

36 minutes ago, komah said:

Можно обойтись одним сумматором и вычитать отсчет, задержанный на длительность символа, если знак совпадает. Тогда переполнения не будет. Решение принимается по переходу через 0, для 4FSK работать не будет. И даже сам переход по моему не очень правильно ищется. Лучше не по одному отсчету смотреть, а по выходу интегратора. Ну и подстройки тактовой здесь нет. 

Всё ещё впереди! ))) 

 

Сделал детектор паттерна преамбулы и нахождение синхрослова.   И выпарсил данные наконец-то и проверил их.

Все три пакета правильные.

Spoiler
//b - размер массива потока бит (определён ранее)

///////////////////////////////////////

//Preamble Search

#define PRE_THR 32

static const u8 PRE[PRE_THR*8]="0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101";

u32 pre=0;

#define NUMP 3

u32 Nump=0;

u32 found;

SearchNewPacket:

found=0;

for(u32 i=pre;i<b-sizeof(PRE);i++)
{

 if(memcmp(&bitstream[i],PRE,sizeof(PRE))==0)
 {
  pre=i;
  printf("Preamble pattern %d found at offset %d\n",Nump,pre);
  found=1;
  break;
 }
}

Nump++;

if(Nump<NUMP)
{
 pre+=(PRE_THR*2)*8;

 goto SearchNewPacket;
}

if(!found)
{
 printf("No more data...\n");
 getch();

 return -1;
}

///////////////////////////////////////

//Sync Search

u32 syn=pre+sizeof(PRE);

static const u8 SYN[4*8]="01011010000011111011111001100110";

for(u32 i=syn;i<b-sizeof(SYN);i++)
{

 if(memcmp(&bitstream[i],SYN,sizeof(SYN))==0)
 {
  syn=i;
  printf("Syncword pattern found at offset %d\n",syn);
  break;
 }
}

///////////////////////////////////////

//Data Pack

#define DATA_LEN 6080

u32 dat=syn+sizeof(SYN);

static u8 Data[DATA_LEN];

for(u32 i=0;i<DATA_LEN;i++)
{
 if((dat-8+(i*8))>=b)
 {
  printf("No more data...\n");
  getch();

  return -1;
 }

 Data[i]=0;
 for(j=0;j<8;j++)Data[i]|=(bitstream[dat+j+(i*8)]-'0')<<(7-j);
}

///////////////////////////////////////

//Data Check

u32 error=0;

for(u32 i=0;i<DATA_LEN;i++)
{
 if(Data[i]!=(u8)i)
 {
  printf("Error: position: %d, 0x%02X != 0x%02X\n",i,(u8)i,Data[i]);
  error++;
 }
}

if(!error)printf("\nData checked - all OK!\n");

///////////////////////////////////////

 

 

18 minutes ago, petrov said:

Ничего вы не сделали, это типичный программизм, просто сочинение на тему как я провёл это лето на языке Ц, никакого отношения к ЦОС и тому, что реально нужно сделать, это объективно, а не раздувание из мухи слона, как вам кажется.

Корона не жмёт? :)))

Изменено пользователем repstosw

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


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

repstosw

Корона не жмёт? :)))

))

Так можно объективно установить, кто воображает  :sun_bespectacled: ... корону.

Можно сделать модельку генератор CPFSK 4 с известными параметрами близкую к реальности с выводом IQ в .wav файл.

Делаем простейшие демодуляторы, никаких Витерби не требуется. Смотрим при каком Eb/N0 достигается BER=10^-1.

Объективно проверите насколько хороша ЦОС в сочинении, сравните с другой реализацией.

Я ж на вашей стороне, хочу чтоб как можно лучше сделали. ))

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


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

3 часа назад, repstosw сказал:

Всё ещё впереди! ))) 

Вот хорошее начало:

https://wirelesspi.com/phase-locked-loop-pll-for-symbol-timing-recovery/

Без восстановления тактовой все остальное не имеет смысла. А в учебниках про это пишут мало и неправильно.

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

Можно сделать модельку генератор CPFSK 4 с известными параметрами близкую к реальности с выводом IQ в .wav файл.

А можно записать сигнал передатчика свистком (RTL-SDR) и демодулировать полностью. И сравнивать не только программные реализации, но и условно железную (в трансивере).

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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