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

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

7 часов назад, repstosw сказал:

Я не знаю внутренней структуры демодулятора Si4463. Но предполагаю, что он квадратурный.   И я уже писал что модуляция 4GFSK.  И мне нужен выходной поток бит, вытащенных из отсчётов квадратурного демодулятора.  Что не ясно?

Задача внезапно заиграла новыми красками. Так у Вас же частотный детектор уже есть в микросхеме. Вы с ее помощью хотите что-то другое принимать? При чем здесь тогда 4GFSK. Или нужен битовый поток с детектора без пакетной синхронизации? И можно пояснить, почему 7 бит? И та запись, которая на картинке, это все-таки вход частотного детектора или выход?

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


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

7 часов назад, repstosw сказал:

Дальнейшие изыскания сводятся к выбору жесткого интервала между опросами SFR-регистра фазы:  по таймеру или привязка к растактовкам ядра  8051..

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

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


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

8 часов назад, repstosw сказал:

Каким образом без ЦОС вы получите битовый поток с отсчётов ЧФД, который ещё и подвергается коррекции ошибок LDPC?

Посмотрел другие темы, пазл сложился. Нужно получить мягкие решения с выхода демодулятора для декодера LDPC. И есть доступ к внутреннему регистру, хранящему значение фазы текущего отсчета.

1. При считывании фазу рвать нельзя. Можно пропускать отсчеты, но равномерно. И нужно понимать, сколько отсчетов на символ будет в итоге. 

2. Unwrap - это не так просто, как кажется. Предположим, один отсчет имеет значение 32, следующий -32. Чему равна дельта? 

3. Декодеру LDPC мягкие решения не обязательны. В Вашей теме я про bit-flipping отвечал. Либо их можно просто сделать из жестких ). Кстати, если есть значение RSSI, можно грубо ОСШ оценить. Это все для декодера полезно. Короче, если трансивер уже умеет ЧМ демодулировать, этого вполне достаточно.

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


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

23 minutes ago, komah said:

Посмотрел другие темы, пазл сложился. Нужно получить мягкие решения с выхода демодулятора для декодера LDPC. И есть доступ к внутреннему регистру, хранящему значение фазы текущего отсчета.

Да. Всё верно.  Есть регистр PHASE_OUT, который хранит отсчёты фазы в знаковом 7-битном формате.   Причём регистр доступен только асинхронно - я не нашёл никаких дополнительных сведений о синхронизации для забора данных с него.   Возможно, это даже не демодулятор, а АЦП после смесителя.

Серия инструкций MOV для чтения этого регистра ядром 8051 даёт до 4-х одинаковых подряд значений.  На практике всё грустно: удалось передавать непрерывным потоком эти данные управляющему процессору со скоростью до 128 отсчётов за 0.11 мс.

 

27 minutes ago, komah said:

2. Unwrap - это не так просто, как кажется. Предположим, один отсчет имеет значение 32, следующий -32. Чему равна дельта? 

Я уже мозг взорвал этими разрывами фазы, но так ничего толкового не увидел.

Проще говоря, как из асинхронно взятых отсчётов мгновенных значений фазы вытащить биты?  Для упрощения перешёл пока на 2FSK.

Пока делал так: отсчёты от 0 до +63 - это мягкие решения от 0 до 1.  Тоже и отрицательный диапазон:  от 0 до -64 - это мягкие 0..1.

Но на графике лажа получается:  я не вижу преамбулы и синхрослова.   Причём отбеливания всякие пока выключил.

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


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

В 08.03.2024 в 11:55, repstosw сказал:

Одно непонятно - как взять производную..  По идее - это разница между соседними отсчётами.  Но не сшивается в точках переполнения.  Интересно, как они выполнили условие непрерывности?

Мгновенную частоту можно считать не как разность фаз, а как фазу между двумя квадратурами в терминах Matlab:

 

freq = atan2(x1*conj(x2))*fclk/2/pi

или, что тоже самое

freq = angle(x1*conj(x2))*fclk/2/pi

 

где x1, x2 - соседние комплексные квадратуры,

conj - функция комплексного сопряжения,

fclk - частота следования квадратур.

 

Способ несколько приближенный, с учетом того, что искомая частота freq много меньше fclk. В противном случае необходима дополнительная компенсация на sinc (sin(x)/x)

 

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

https://dsp.stackexchange.com/questions/24487/calculate-and-interpret-the-instantaneous-frequency

 

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


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

2 minutes ago, rloc said:

Мгновенную частоту можно считать не как разность фаз, а как фазу между двумя квадратурами в терминах Matlab:

Нет доступа к квадратурам.  Есть только фаза со знаком в виде дискретных значений [-64.. + 63].

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


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

repstosw

Как это не нужны?

Каким образом без ЦОС вы получите битовый поток с отсчётов ЧФД, который ещё и подвергается коррекции ошибок LDPC?

Таким же образом как и в Si4463, процессоры и программизм не имеют никакого отношения к ЦОС и цифровой схемотехнике.

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


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

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

Нет доступа к квадратурам

Вычислите )

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


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

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

Проще говоря, как из асинхронно взятых отсчётов мгновенных значений фазы вытащить биты? 

Из взятых асинхронно - только если есть гарантия, что количество полученных отсчетов на символ всегда одинаковое. Я бы с мягкими решениями просто не заморачивался. Не нужны они они для dmr. Если полностью приемник реализовать предстоит, то демодулятор там - 3% работы. 

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


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

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

Проще говоря, как из асинхронно взятых отсчётов мгновенных значений фазы вытащить биты? 

1. Считываем значения фазы из регистра с фиксированной частотой. Чем чаще - тем лучше. Если набег фазы между считанными значениями близок к PI/2 (32), отказываемся от этой затеи. При известной символьной скорости считаем, сколько отсчетов приходится на символ.

2. Для считанных значений делаем unwrap, хотя бы как в примере, который Вы приводили. Находим разность между соседними отсчетами. При наличии шумов в сигнале, на выходе в любом случае будут выбросы из-за перескока фазы на 2PI.

3. Фильтруем полученный сигнал. Лучше согласованным фильтром. Смотрим на результат. На графике должны быть видны явно различимые импульсы. Из-за межсимвольной интерференции их амплитуда будет непостоянной, но четыре интервала значений должны быть различимы. Если нет - отказываемся...

4. Теперь самое интересное. Тактовая синхронизация. Для принятия решения о значении символа нужно выбрать отсчет, находящийся на пике импульса. Если отсчетов на символ много и это целое число - существуют более-менее простые алгоритмы. В противном случае нужна интерполяция. Можно совместить с фильтрацией из предыдущего пункта. Схема называется pfb - polyphase filter bank. В принципе, есть готовые решения под разное железо, но за ними еще куча всего обычно тянется.

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

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

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


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

Задача решена.

Нашёл синхро-слово после преамбулы, которое передаю (преамбула 010101...0101, синхрослово: 0x5A0FBE66 - в эфире: 01011010 00001111 10111110 01100110).

Скорость 0.5 МБит/c, модуляция 2FSK:

image.png.cc94e10b4b7dd9a14ebaea2be76dd53c.png

 

Очень помогла вот эта статья:

https://ru.dsplib.org/content/signal_fm_demod/signal_fm_demod.html

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

 

По мгновенным отсчётам фазы, вначеле построил I- и Q- сигналы.  Их магнитуда условно принята M=1, так как амплитудная составляющая предполагается постоянной при угловой модуляции (ЧМ, ФМ) а также включено АРУ в приёмнике.

Затем нашёл мгновенные значения модулирующей частоты по формуле из статьи:

fmdemod_html_5b2b95b0.gif

 

Весь конвеер:

Packet - исходные отсчёты фазы (полученные из Si4463 с помощью программы-эксплоита, и переданные на хост-контроллер для записи данных).

OutI - синфазная составляющая, найденная по отсчётам фазы: I(o)=M*cos(o)

OutQ - квадратурная составляющая, найденная по отсчётам фазы: Q(o)=M*sin(o)

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

Pipeline.thumb.jpg.8e7a146554201641a1d69ea4f9e3c080.jpg

 

Программа на Сях (накидал на скорую руку):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#include "Type.h"

#define SIZE 32538

s8 BufferIn[SIZE];
float BufferOutI[SIZE];
float BufferOutQ[SIZE];
float BufferOutF[SIZE];

int main(void)
{
 FILE *f=fopen("Packet.raw","rb");
 fread(BufferIn,SIZE,1,f);
 fclose(f);

 for(int i=0;i<SIZE;i++)
 {
  s8 o=BufferIn[i];

  float fi=((float)o)*M_PI/64;

  if(fi<-M_PI)fi=-M_PI;
  else
  if(fi>+M_PI)fi=+M_PI;

  float I=cosf(fi);
  float Q=sinf(fi);

  BufferOutI[i]=I;
  BufferOutQ[i]=Q;
 }

 BufferOutF[0]=0.0F;
 for(int i=1;i<SIZE;i++)
 {
  float dI=BufferOutI[i]-BufferOutI[i-1];
  float dQ=BufferOutQ[i]-BufferOutQ[i-1];
  BufferOutF[i]=((dQ*BufferOutI[i])-(dI*BufferOutQ[i]))/((BufferOutI[i]*BufferOutI[i])+(BufferOutQ[i]*BufferOutQ[i]));
 }

 f=fopen("outI.raw","wb");
 fwrite(BufferOutI,SIZE,sizeof(float),f);
 fclose(f);

 f=fopen("outQ.raw","wb");
 fwrite(BufferOutQ,SIZE,sizeof(float),f);
 fclose(f);

 f=fopen("outF.raw","wb");
 fwrite(BufferOutF,SIZE,sizeof(float),f);
 fclose(f);
}

 

1 hour ago, komah said:

4. Теперь самое интересное. Тактовая синхронизация. Для принятия решения о значении символа нужно выбрать отсчет, находящийся на пике импульса. Если отсчетов на символ много и это целое число - существуют более-менее простые алгоритмы. В противном случае нужна интерполяция. Можно совместить с фильтрацией из предыдущего пункта. Схема называется pfb - polyphase filter bank. В принципе, есть готовые решения под разное железо, но за ними еще куча всего обычно тянется.

Пока есть небольшой джиттер.  Я могу позволить себе до 8 отсчётов на символ максимум при символьной скорости до 625 кбит/с.

 

2 hours ago, petrov said:

Таким же образом как и в Si4463, процессоры и программизм не имеют никакого отношения к ЦОС и цифровой схемотехнике.

fmdemod_html_46eb685f.gif

Так что-ли?

Мне пока интересно софтово это сделать.

 

2 hours ago, rloc said:

Вычислите )

Уже вычислил.  Нормированные, правда.  Но в моём случае амплитуда не нужна.

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

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


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

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

По мгновенным отсчётам фазы, вначеле построил I- и Q- сигналы.

Это лишнее, unwrap достаточно. Сейчас вы двойную работу делаете, а формула без арктангенса все равно хуже, чем 

 

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

angle(x1*conj(x2))

 Выход частотного детектора нужно поделить на (h * M_PI), где h - индекс модуляции.

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


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

1 hour ago, komah said:

Это лишнее, unwrap достаточно. Сейчас вы двойную работу делаете, а формула без арктангенса все равно хуже, чем 

Unwrap не получается сделать так, чтобы он правильно работал:  он ползёт куда-то вверх, и не всегда срабатывает - оставляются переполнения.

Может в MATLAB оно и работает превосходно, но Си-шный алгоритм даёт фигню мягко говоря...

К тому же, если размотанная фаза будет постоянно ползти, то и 32 бит скоро может не хватить.

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


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

repstosw

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

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


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

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

Уже вычислил.

Формула f3(t) в приведенной выше ссылке, всего 5 вариантов, включая atan2, который считается ничуть не медленнее пары операций перемножения при соответствующей оптимизации (легко проверить в Matlab).

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

Выход частотного детектора нужно поделить на (h * M_PI), где h - индекс модуляции.

Поправил в исходном сообщении нормировку.

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


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

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

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

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

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

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

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

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

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

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