Страница 2 из 2

Re: Модифицированный алгоритм Герцеля

Добавлено: 03 мар 2016, 11:55
Heavy
Такой вопрос:
Если необходимо детектировать 8 частот, которые приходят в случайном порядке ( DTMF передача данных), то при успешном детектировании одной из частот (когда модуль искомой частоты перевалит за порог), следует обнулять I и Q ? Верно ли я понимаю?

И еще: если на входе алгоритма присутствует шум, или просто звук, который не содержит искомой компоненты, то модуль растет со временем. Допустим, я ставлю порог равным 5000. Из-за шума модуль постепенно доползет до 5000 за несколько секунд, и произойдет ложное детектирование, хотя искомый сигнал так и не пришел. Что в этом случае необходимо делать? Есть мысль обнулять I и Q с определенной периодичностью, но тогда теряется смысл SDFT. Есть мысль резать шум, то есть принимать все семплы, которые ниже определенного уровня, равными нулю. Но это как-то слишком топорно.

Re: Модифицированный алгоритм Герцеля

Добавлено: 03 мар 2016, 16:30
Бахурин Сергей
Вероятно, что у вас просто ошибка. Модуль не должен расти со временем.

Re: Модифицированный алгоритм Герцеля

Добавлено: 03 мар 2016, 18:11
Santik
Heavy писал(а): ...И еще: если на входе алгоритма присутствует шум, или просто звук, который не содержит искомой компоненты, то модуль растет со временем.
Может на этот эффект Вам намекали здесь?
http://electronix.ru/forum/index.php?sh ... 33098&st=0

Re: Модифицированный алгоритм Герцеля

Добавлено: 03 мар 2016, 18:32
Heavy
Бахурин Сергей писал(а): Вероятно, что у вас просто ошибка. Модуль не должен расти со временем.
Хм. Взял реализацию, предложенную вами несколько сообщений назад. В ней ошибки вроде нет.
Единственное что заменил, так это инициализацию массива ADC[]:

Код: Выделить всё

#define N 147		//размер окна
#define K 294		//кол-во семплов всего
for (int i =0; i<K; i++)
{
//вторая половина 294 семплов (от 147 до 293) равна постоянному уровню 100
    if ((i/147)%2)	
    {
        ADC[i]=100;
    }
    else
    {
 //первая половина (от 0 до 146) равна искомой частоте со сдвигом фазы.
       ADC[i] = (unsigned char) 100*sin((c*i + M_PI/5))+100; 
    }
}
От 0 семпла до 147 семпла идет рост модуля, и на 147 семпле я ловлю искомую частоту. Пусть на 17000гц есть растекание спектра (17000 на 300 не делится). Как мне кажется, это не важно.
После 147 семпла (номер 146) идут нули. Ровно 147 семплов, до 294 семпла (293 номер). Модуль растет все равно. Даже если обнулить I и Q, все равно растет из-за наличия искомой частоты на 147 семплов назад.
То есть рост модуля происходит за счет:

Код: Выделить всё

u = I[0] + ADC[n] - ((n>=N) ? ADC[n-N] : 0.0);
А именно за счет ADC[n-N] .
Получается, что надо еще 147 семплов не посылать в буфер искомую частоту. То есть , как я понял , получается примерно так:
[0..146] = sin(2pi*17000t) => рост модуля, на номере 146 модуль максимален
[147..293] = 100 => рост модуля продолжается за счет предыдущих 147 семплов. Можно словить ложное детектирование
[294..440] = роста нет, все предыдущие 147 семплов равны нулю.

Re: Модифицированный алгоритм Герцеля

Добавлено: 03 мар 2016, 18:35
Heavy
Santik писал(а):
Heavy писал(а): ...И еще: если на входе алгоритма присутствует шум, или просто звук, который не содержит искомой компоненты, то модуль растет со временем.
Может на этот эффект Вам намекали здесь?
http://electronix.ru/forum/index.php?sh ... 33098&st=0
Нет, там на счет округления намекали. С этим можно бороться. У Лайонса написано как. Но это добавляет еще кучу вычислительных операций. Тестирую алгоритм на QT и на STM32F103VET. На QT буфер генерю программно, на STM буфер шлю через звуковую карту, звук генерю тоже через QT. С генерацией буфера и звука проблем нет. Пока что хотя бы на QT отладить.

Re: Модифицированный алгоритм Герцеля

Добавлено: 03 мар 2016, 18:38
Heavy
Прихожу к выводу, что после детектирования частоты необходимо не только обнулить I и Q, но еще и предыдущие N семплов принять равными 0.

Re: Модифицированный алгоритм Герцеля

Добавлено: 04 мар 2016, 16:49
Heavy
Записал видео с своей реализацией https://youtu.be/FhoelOKbjfk?t=964 . Сильно не пинайте за путаницу в терминологии, и за неуверенность в некоторой матчасти. Видео около часа длительностью. Примерно с 16 минуты запускаю алгоритм, и начинаю тестить и показывать что получается. В итоге прихожу в ступор.

Re: Модифицированный алгоритм Герцеля

Добавлено: 24 июн 2016, 16:42
serjik
Не знаю, нашел ли автор топика ответы на свои вопросы. Видео я смотреть не стал.
Поскольку мне была интересна эта тема, я решил попробовать реализовать приведенный алгоритм.
В исходном варианте у меня модуль не уменьшался. То есть, если фильтр сработал на какую-то частоту, то его значение не уменьшалось, даже если этой частоты уже нет в сигнале.
Однако вот такая модификация: умножение на коэффиент 0.9995 значений a и b
a = 0.9995 * Math.Cos(2.0 * Math.PI * k0 / filterConfig.FrameSamplesCount);
b = 0.9995 * Math.Sin(2.0 * Math.PI * k0 / filterConfig.FrameSamplesCount);
при каждом вычислении модуля, будет уменьшать его.
И еще, чтобы величина модуля оставалась постоянной от частоты, его можно вычислять так:
value = Math.Sqrt(i1 * i1 + q1 * q1) / k0;
k0 это "номер гармоники"

Вот что у меня получилось: https://github.com/jauseg/GoertzelOnTheFly

Как это прикрутить к ардуинке со светодиодной лентой я пока еще не придумал.