реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Модифицированный алгоритм Герцеля
Lost_Viking
сообщение Jan 21 2016, 05:58
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091



Взялся за реализацию. Прочитал про алгоритм тут: dsplib
Написал такую реализацию:
Код
#define Fd 9000 //частота дискретизации
#define f1 600  //частота тона
#define f_search 600 //искомая алгоритмом частота
#define N 70 //размер массива
int main()
{
unsigned char ADC[350]; //Массив, эмулирующий поток из АЦП
unsigned char buff[N]; //Буфер, в который пишутся данные из АЦП
float I[2];
float Q[2];
float a;
float b;
float c = 2* M_PI *f1/Fd; //Заранее рассчитаем то, что не будет меняться
float module; //здесь будет лежать модуль комплексного числа
I[0]=0; I[1]=0; //инициализируем массивы
Q[0]=0; Q[1]=0;
for (int i =0; i<350; i++)
{
    ADC[i] = (unsigned char) 100*sin(c*i)+100; //заполняем "поток" АЦП синусом с амплитудой от 0 до 100

}

a=cos(2*M_PI*f_search/N); //рассчитываем к-ты
b=sin(2*M_PI*f_search/N);

for (int n=0; n<70; n++) //начальное заполнение буфера
{
    I[0]=I[1]; //Готовим предыдущее I
    Q[0]=Q[1];
    buff[n]=ADC[n]; // Просто заполняем буфер данными из АЦП
    I[1]=a*(I[0]+buff[n])-b*Q[0]; //Все по формуле 16 из статьи
    Q[1]=a*Q[0]+b*(I[0]+buff[n]);

}
for (int n=70; n<350; n++) //Когда буфер заполнился, то запускаем цикл с выталкиванием
{
    I[0]=I[1];
    Q[0]=Q[1];
    I[1]=a*(I[0]+ADC[n]-buff[0])-b*Q[0]; //В качестве i(n) выступает ADC(n), где n=70. Следовательно buff(n-N)=buff(0)
    Q[1]=a*Q[0]+b*(I[0]+ADC[n]-buff[0]);
    for (int nn=0; nn<69; nn++) //перемещаем элементы массива на 1 влево
    {
        buff[nn]=buff[nn+1];
    }
    buff[69]=ADC[n]; //Заносим полученное значение АЦП на данном цикле работы алгоритма в последний эллемент буфера
    module = sqrt(I[1]*I[1]+Q[1]*Q[1]); //вычисляем модуль комплексного числа
}
//конец работы алгоритма
}

Для удобства чтения скрин из саблайма: screenshot

В итоге имею изменяющийся модуль, хотя, как я понимаю, его значение должно быть постоянным и максимальным про наличии искомой частоты:

Скрин вывода программы переменной module:screenshot

Что я делаю не так?

Сообщение отредактировал Lost_Viking - Jan 21 2016, 08:19
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jan 21 2016, 06:17
Сообщение #2


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



На елку такие скриншоты можно вешать, и гирлянды не надо. Все люди как люди, выкладывают код между соответствующими тэгами.
Go to the top of the page
 
+Quote Post
Lost_Viking
сообщение Jan 21 2016, 07:54
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091



Цитата(ViKo @ Jan 21 2016, 09:17) *
На елку такие скриншоты можно вешать, и гирлянды не надо. Все люди как люди, выкладывают код между соответствующими тэгами.

Ок,понял. Через 30 минут исправлю
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jan 21 2016, 08:13
Сообщение #4


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



В книге Р. Лайонса "Цифровая обработка сигналов" алгоритм Герцеля описан. Кажется, если сделать по формулам, то и работать должно безупречно.
Go to the top of the page
 
+Quote Post
Lost_Viking
сообщение Jan 21 2016, 08:20
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091



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

А на dsplib предложен алгоритм, который позволяет на лету обрабатывать семплы. Так вот разобраться с ним не могу.

Немножко напишу про свое понимание алгоритма, который на dsplib. Если перейти по ссылке сюда: dsplib, то можно увидеть вот что:
формула 12: . О ней говорится, что это входной сигнал. На форуме dsplib мне ответили, что q(n) нужно принимать равными нулю. Вполне логично. Соответственно сама рекурсивная формула имеет вид:

Из нее убираем все q. Но тогда какой смысл вываливать такую формулу, если ее можно сократить? Это смущает

Сообщение отредактировал Lost_Viking - Jan 21 2016, 08:39
Go to the top of the page
 
+Quote Post
petrov
сообщение Jan 21 2016, 09:10
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 220
Регистрация: 21-10-04
Из: Balakhna
Пользователь №: 937



Практически алгоритм не работоспособен в конечной разрядной сетке, ошибки округления будут бесконечно в интеграторе циркулировать.
Go to the top of the page
 
+Quote Post
Lost_Viking
сообщение Jan 21 2016, 09:23
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091



То есть округление до целого даст нарастание ошибки?
Хотите сказать, что модуль так скачет именно из-за этого?
Go to the top of the page
 
+Quote Post
petrov
сообщение Jan 21 2016, 09:31
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 220
Регистрация: 21-10-04
Из: Balakhna
Пользователь №: 937



Прикрепленный файл  SlidingDFT_BW.pdf ( 150.16 килобайт ) Кол-во скачиваний: 225
Go to the top of the page
 
+Quote Post
Lost_Viking
сообщение Jan 21 2016, 09:42
Сообщение #9


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091



Наверное тогда лучше так: Скользящее ДПФ
Go to the top of the page
 
+Quote Post
petrov
сообщение Jan 21 2016, 10:29
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 220
Регистрация: 21-10-04
Из: Balakhna
Пользователь №: 937



Цитата(Lost_Viking @ Jan 21 2016, 12:42) *
Наверное тогда лучше так: Скользящее ДПФ


Что-то я не понял каким образом здесь решается проблема конечной разрядной сетки, всё тот же компелексный множитель в интеграторе остаётся?
Go to the top of the page
 
+Quote Post
Lost_Viking
сообщение Jan 21 2016, 11:02
Сообщение #11


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091



Цитата(petrov @ Jan 21 2016, 12:31) *
Прикрепленный файл  SlidingDFT_BW.pdf ( 150.16 килобайт ) Кол-во скачиваний: 225

А здесь как решена эта проблема? Здесь тоже комплексный множитель. Статья похожа на Лайонса, кстати =)
Go to the top of the page
 
+Quote Post
petrov
сообщение Jan 21 2016, 11:09
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 220
Регистрация: 21-10-04
Из: Balakhna
Пользователь №: 937



Цитата(Lost_Viking @ Jan 21 2016, 14:02) *
А здесь как решена эта проблема?


Демпинг фактор вводится.
Go to the top of the page
 
+Quote Post
Lost_Viking
сообщение Jan 21 2016, 11:39
Сообщение #13


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091



Цитата(petrov @ Jan 21 2016, 14:09) *
Демпинг фактор вводится.

Окно Хэннинга?

Сообщение отредактировал Lost_Viking - Jan 21 2016, 11:40
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jan 21 2016, 11:46
Сообщение #14


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Lost_Viking @ Jan 21 2016, 14:02) *
Статья похожа на Лайонса, кстати =)

Там в начале документа автор указан: Lyons. rolleyes.gif
Go to the top of the page
 
+Quote Post
Lost_Viking
сообщение Jan 21 2016, 16:28
Сообщение #15


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091



Все равно мне не ясно как может конечная разрядность так сильно влиять на алгоритм. Выполняю алгоритм на JavaScript, все вычисления примерно с такой точностью: 60.469052485485626 . Но модуль всегда плавает.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd June 2025 - 10:55
Рейтинг@Mail.ru


Страница сгенерированна за 0.0155 секунд с 7
ELECTRONIX ©2004-2016