Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Обнаружение частоты
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Alex_1811
Возникла такая проблема:
Имеется Мега8 на вход АЦП которой через усилитель подключен микрофон.
Нужно детектировать наличее сигнала определенной частоты (в моем случаи 1000Гц).
Я понимаю что нужно что-то типа преобразования Фурье, но я далек от этого. smile.gif
Буду рад любой помощи.
МП41
А что если LM567 подвесить? Микросхема детектирует любую частоту с некоторой регулируемой полосой и выдаёт логический сигнал.

Или посмотрите тут FFT7, но AVR будет сильно загружен. Можно еще попробовать на КИХ-фильтре детектор собрать.
Alex_1811
Цитата(МП41 @ Nov 25 2008, 13:57) *
Или посмотрите тут FFT7, но AVR будет сильно загружен. Можно еще попробовать на КИХ-фильтре детектор собрать.

С примером FFT проблемы не будет, мне не понятно как мне его применить под мою задачу.
SasaVitebsk
Цитата(Alex_1811 @ Nov 25 2008, 14:28) *
С примером FFT проблемы не будет, мне не понятно как мне его применить под мою задачу.

Если вам нужно только 1-2 частоты, то зачем вам фурье? Обычный фильтр режекторный на эту частоту. Выборки достаточно 8000Гц. Проц практически не загружен будет. Время реакции фильтра будет зависеть от добротности, но буквально несколько периодов частоты.
МП41
Нужно в результатах этой функции найти регистр/область памяти (в общем место, куда она результаты сохраняет), значение в котором(ой) соответствует амплитуде сигнала на частоте 1000Гц (а реально - в некоторой полосе частот). Правда чтобы обеспечить узкую полосу обнаружения, нужен многоточечный БПФ, что для AVR проблема.

Цитата(SasaVitebsk @ Nov 25 2008, 12:34) *
Если вам нужно только 1-2 частоты, то зачем вам фурье? Обычный фильтр режекторный на эту частоту. Выборки достаточно 8000Гц. Проц практически не загружен будет. Время реакции фильтра будет зависеть от добротности, но буквально несколько периодов частоты.

Т.е. какой-нибудь цифровой фильтр, где нужно только умножать и суммировать, а также сделать буфер для задержки выборок?
Alex_1811
Цитата(SasaVitebsk @ Nov 25 2008, 14:34) *
Если вам нужно только 1-2 частоты, то зачем вам фурье?

Параметр частота может изменяться, так что детектированиє нужно реализовать программно.
Узкая полоса по частоте не нужна.
Stanislav_S
Цитата(Alex_1811 @ Nov 25 2008, 15:42) *
Параметр частота может изменяться, так что детектированиє нужно реализовать программно.
Узкая полоса по частоте не нужна.

Если заранее известно какая частота, то коэфициенты фильтра проще хранить во флэши для каждой частоты отдельно, если частота меняется "сама по себе", то стоит задуматься о более мощном вычислителе.
МП41
Адаптивный фильтр тоже будет проблемой, если частот много. Иначе - коэффициенты фильтра можно рассчитать заранее и хранить для каждой конкретной частоты.
Designer56
Самое простое, если программно,- это вычислит ДПФ для одной гармоники, в данном случае- 1 кГц, т. е по периоду 1 мс.
mse
Искать Goertzel algorithm
МП41
У меня где-то были программы для расчёта коэффициентов фильтра с визуальным контролем АЧХ и ФЧХ. Сейчас в сети их найти не могу.
Alex_1811
Цитата(Designer56 @ Nov 25 2008, 15:10) *
Самое простое, если программно,- это вычислит ДПФ для одной гармоники, в данном случае- 1 кГц, т. е по периоду 1 мс.


Может есть у кого пример (желательно на Си) или скажите где искить.
Ваши умные реплики мне мало о чем говорят. smile.gif
Designer56
Цитата(ukpyr @ Nov 25 2008, 16:26) *
может, проще коррелятором ?
или синхр. детектором ?

Так это по сути то- же самое, что и Фурье
GetSmart
Цитата(Designer56 @ Nov 25 2008, 17:32) *
Так это по сути то- же самое, что и Фурье

Не, не то же. Коррелятор будет хуже фурье когда вместе в синусом 1000 Гц будут посторонние сигналы, например 1500 Гц сразу обломает результат. А Фурье это будет "до лампочки". Правда у корреляции есть свои плюсы в разных ситуациях.
Designer56
Цитата(GetSmart @ Nov 25 2008, 17:22) *
Не, не то же.....

В смысле- КФ считается через спектры соотв. сигналов. Только уже ДПФ не обойдешься, или интегрировать по времени нужно по большому интервалу, чтобы поймать максимум.
GetSmart
Цитата(Alex_1811)
Нужно детектировать наличее сигнала определенной частоты (в моем случаи 1000Гц).
Я понимаю что нужно что-то типа преобразования Фурье, но я далек от этого.
Берёте свёртку сигнала и 10..100 периодов исследуемой частоты в комплексном виде. Другими словами один нужный базис ДПФ. Длину вектора будет равна амплитуде искомой частоты. Далее что хотите, то и делайте smile.gif

ЗЫ. Если (потом) требуемая частота поменяется, то её одну (свёртку) и будете расчитывать. На AVR наверное нужно все операции делать в целых числах. И синус с косинусом вычислять как-нибудь таблично.
klen
1. корелятор и БПФ/ДПФ - cуть одно и тоже, ДПФ - векторный коррелятор с опорой в виде синусойды, все определяется тоько временем накопления (кличество отсчетов)!

2. если очень очень бысторо написать и попробывать то рекомендую сделать буфер на 3x512 отсчетов
в первых двух расчитать и хранить синусойду и косинусойду 1000Гц - это будет опора в комплексном виде
в последний записать выборку.

оценка квадрата амплитуды сигнала 1000Гц вычисляется по формуле

(1/512)*E( (cos[i]*y(i))^2 +(sin(i)y(i))^2 )
где Е - сумма 0...511



пример кода
Код
int main (void)
{
  // допустим частота АЦП 10000Гц
  float adc_freq  = 10000.0;
  float view_freq = 1000.0 ;
  


  for (uint16_t i = 0; i < 512; i++)
   {
     buf_sin[i] = sin( (adc_freq / view_freq) * i * 2 * M_PI / 512);
     buf_sin[i] = cos( (adc_freq / view_freq) * i * 2 * M_PI / 512);
   }

  // GetSamples();

  volatile float AmpSqrt = 0.0;
  for (uint16_t i = 0; i < 512; i++)
   {
      AmpSqrt = pow(buf_sin[i]*buf_in[i],2)  + pow(buf_cos[i]*buf_in[i],2);
   }
  
  return 1 ;
}


прогнал в авр студии - 7мгц частота проца, 88мега на вычисление одного значения потреюуется 44мс, тоесть Вы сможете 25 раз в секунду измерять. полоса примерно 100Гц. это если тупо использовать float, если использовать целочисленную арифметику то скорость можно увеличить в разы(соответственно и полосу сузить)
Alex_1811
Вот тут http://helper10.narod.ru/alg2.htm
Нашел такое:

Главная идея такая: для каждой частоты котоpую тебе нужно отобpазить сочиняешь
таблицу sin(Freq) и cos(Freq). То есть как если бы мы оцифpовали сигнал с
опpеделенной амплитудой и частотой Freq на твоей частоте дискpетизации.
Длина таблицы должна быть больше чем одна полуволна сигнала Freq. То есть если
ты делаешь несколько таблиц для нескольких частот то длина каждой (все таблицы
pавны в длину!) беpешь длину полуволны для низшей частоты.
Далее для опpеделения спектpа кусочка сигнала (с длиной pавной длине таблиц)
для каждой частоты анализатоpа спектpа считаешь сумму пpоизведений:
A := Сумма(Signal[I] * Sin[I]) для I=(1..BlockLen)
B := Сумма(Signal[I] * Cos[I]) для I=(1..BlockLen)
После этого амплитуда данной частоты есть
Sqrt(A^2 + B^2).
Чтобы не вычислять коpень можешь делать пpосто A^2 + B^2.
Hу и как-то их масштабиpуешь. Потом pисуешь палку соотв. длины и усе.


Это для меня покатит?
klen
пробуй
Alex_1811
А какой длины таблицу Sin и Cos нужно брать (волну, полуволну) и какое время между отсчетами
(частоту выборки сигнала)?
ukpyr
лучше делать выборки на частоте, кратной искомой (напр. 8/16/32кГц). таблица - целочисленная, на 1 полупериод синуса (т.е. 4/8/16 выборок), умножение/сложение/наколение на лету.
SasaVitebsk
Цитата(ukpyr @ Nov 25 2008, 15:26) *
может, проще коррелятором ?

Вот у корелятора наблюдается большое время детектирования. В разы больше чем у фильтра.
Microwatt
Да, тяжело в электронике программерам... Ну, куда ни сунься - везде гигабайта- другого не хватает...
Сказано было сразу:LM567. Вот от нее и пляшите после тщательного изучения матчасти.... И перестраиваемый по частоте программно фильтр достаточно просто на ней организовать.
А то- Фурье, корреляторы, матрицы- накопители, синус-косинусные преобразования....
Rst7
Цитата(Microwatt @ Nov 25 2008, 19:37) *
Да, тяжело в электронике программерам... Ну, куда ни сунься - везде гигабайта- другого не хватает...

Вашу ненависть к цифровым методам мы знаем. Предложите решение, если завтра человеку понадобится определить 10 разных частот одновременно? Десять LM'ок? wink.gif
klen
Вот один из самых оригинальных в моем понятиии пример для AVR - я долго искал, как же всетаки применить в жизни дробные операции AVR не притягивая за уши - вот оно
http://elm-chan.org/works/akilcd/report_e.html
Serg76
Присоединяюсь к mse. Самое простое это применить алгоритм Герцеля. Так, например, делают в декодере DTMF.
demiurg_spb
Цитата(ukpyr @ Nov 25 2008, 18:41) *
лучше делать выборки на частоте, кратной искомой
Чем лучше?
Главное чтобы частота выборки была как минимум в 2 раза выше искомой (теорема Котельникова).
Microwatt
Цитата(Rst7 @ Nov 25 2008, 22:56) *
Вашу ненависть к цифровым методам мы знаем. Предложите решение, если завтра человеку понадобится определить 10 разных частот одновременно? Десять LM'ок? wink.gif

Не стоит тут трактовать мои чувства.
завтра? так то будет завтра.
А человек сегодня не может уверенно одну частоту обнаружить. Ему решение оптимальное и подсказали.
Можно одной LM и десять частот обнаружить и весь спектр прочесать умеючи. Только не сразу, а поочередно. Кстати, вычисления так точно придется делать поочередно. или срочно затребовать десятиядерный контроллер....
SasaVitebsk
Цитата(Microwatt @ Nov 25 2008, 21:37) *
Да, тяжело в электронике программерам... Ну, куда ни сунься - везде гигабайта- другого не хватает...
Сказано было сразу:LM567. Вот от нее и пляшите после тщательного изучения матчасти.... И перестраиваемый по частоте программно фильтр достаточно просто на ней организовать.
А то- Фурье, корреляторы, матрицы- накопители, синус-косинусные преобразования....

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

Тот же DTMF делал на м8 - 10 режекторных фильтров. Пару килобайтов.

Тут ещё одной информации не хватает - а именно превышение сигнала над фоном. Насколько сигнал чёткий будет?

Корелятором тоже делал, но ... выделяет хуже, соотношение сигнал/шум держит хуже, времени тратит больше, проц загружает намного больше.

Конечно фильтр перестраевыемый сделать значительно сложнее. Плавучку не потянешь, а фиксированная времени больше захавает, но какого-нибудь второго порядка вполне реально потянуть с 16-ти битной арифметикой с фиксированной точкой. Одну частоту. Если сигнал отчётливый.
Aleksandr Baranov
А что, вычисление величины гармоники 1000 Гц - это не вычисление коэффициента корреляции сигнала с синусоидой частоты 1000 Гц?
GetSmart
Цитата(Aleksandr Baranov)
А что, вычисление величины гармоники 1000 Гц - это не вычисление коэффициента корреляции сигнала с синусоидой частоты 1000 Гц?

Не пойму, почему все так считают. Корреляция - скалярная сумма, ДПФ - комплексная. Корреляция равна мощности сигнала, ДПФ равна вектору, содержащему амплитуду и фазу. Для определения уровня сигнала (синуса) методом корреляции нужно сделать множество свёрток с разными относительными сдвигами. Для ДПФ достаточно посчитать один раз и сразу выяснить относительный сдвиг между синусами и одновременно амплитуду. Кроме того, ДПФ обнаруживает только синусоиды, корреляция - вообще любые сигналы. И главная фича - корреляцию можно сделать сигнала самим с собой.
Microwatt
Цитата(SasaVitebsk @ Nov 26 2008, 02:49) *
Да всё это звучит грозно, а на деле ... Гигобайты это на ПиСишках, а здесь их нет и сотнями байтов укладываемся.
Тут ещё одной информации не хватает - а именно превышение сигнала над фоном. Насколько сигнал чёткий будет?
Конечно фильтр перестраевыемый сделать значительно сложнее.

Так надо матчасть учить. Что умеет 16-разрядный процессор приблизительно понятно. И сколько времени программер будет уродоваться над всякими БПФ, пока 1000Гц от 2000Гц в идеальном спектре так-сяк программа отличать начнет.
А почему все-таки стандартный тональный декодер не годится? При уровне сигнала -6 дБ уверенно обнаруживает. Когда на экране самого сигнала за помехами не видно. За несколько периодов всего.
И перестраивается практически одним резистором. Это можно и программно делать.
Просто программеры не ищут легких путей в жизни?
SasaVitebsk
Цитата(Microwatt @ Nov 26 2008, 03:59) *
Так надо матчасть учить. Что умеет 16-разрядный процессор приблизительно понятно. И сколько времени программер будет уродоваться над всякими БПФ, пока 1000Гц от 2000Гц в идеальном спектре так-сяк программа отличать начнет.
А почему все-таки стандартный тональный декодер не годится? При уровне сигнала -6 дБ уверенно обнаруживает. Когда на экране самого сигнала за помехами не видно. За несколько периодов всего.
И перестраивается практически одним резистором. Это можно и программно делать.
Просто программеры не ищут легких путей в жизни?

Да нет, наоборот. Я просто говорю, что этот параметр надо учитывать при выборе алгоритма. А то наши советы бессмысленны.
Цифровой фильтр у меня также устойчиво обнаруживал сигнал DTMF на фоне разговора. При этом никогда не подрабатывал во время разговора. И, действительно, обнаруживал сигнал буквально по нескольким периодам. Мы добились качества работы неотличимого от ВЖ18. Точных параметров я вам не скажу, так как там всё несколько сложнее было (сигнал восстанавливался из цифры сначала).

У корелятора эти параметры раз в 10 хуже были.
Alex_1811
Вот до чего я докотился sad.gif .
Пока на Delphi для простоты реализации.

Кто скажет, похоже на правду?
GetSmart
Цитата(Alex_1811)
Кто скажет, похоже на правду?

Очень похоже. Даже не отличишь smile.gif
Только свёртку делают с нормированным (еденичным) синусом и косинусом, чтобы C (C:=sqrt(A*A+B*cool.gif) содержало сразу же реальную амплитуду.
Stanislav
Цитата(Alex_1811 @ Nov 25 2008, 12:43) *
Возникла такая проблема:
Имеется Мега8 на вход АЦП которой через усилитель подключен микрофон.
Нужно детектировать наличее сигнала определенной частоты (в моем случаи 1000Гц).
Опишите сигнал подробнее. Нужна форма его огибающей, уровень относительно помех, длительность,необходимое время обнаружения и т.д. Также нужна статистика помехи и вероятность ложного срабатывания или пропуска.
Если это покажется сложным - поймите, что простыми средствами накакую задачу удовлетворительно решить нельзя.
Оптимум нужно искать только тогда, когда условия определены по максимуму. Если чего-то не хватает - ищется компромиссное решение.

ЗЫ. Для начала, можно попробовать полосовой фильтр конечной длины. Возьмите частоту выборки равной, скажем, 4 кГц, и реализуйте разностное отношение: Y(k)=Y(k-1)+X((k)-X(k-2)-X(k-40)+X(k-42). Это рекурсивный КИХ-фильтр, не содержащий операций умножения, и оптимальный для куска (ко)синусоиды частотой в 1 кГц и длиной в 10 периодов в белом шуме. Y(k) - текущий выходной отсчёт, Y(k-1) - предыдущий выходной отсчёт, X(k) - текущий входной отсчёт и т.д.
В реальности всё, конечно, сложнее.
В полосе фильтра может оказаться, например, форманта.
Alex_1811
Цитата(GetSmart @ Nov 27 2008, 02:52) *
Только свёртку делают с нормированным (еденичным) синусом и косинусом, чтобы C (C:=sqrt(A*A+B*cool.gif) содержало сразу же реальную амплитуду.


Розжуйте пожалуйста белее популярно (доступно для меня).

Цитата(Stanislav @ Nov 27 2008, 02:52) *
Опишите сигнал подробнее. Нужна форма его огибающей, уровень относительно помех, длительность,необходимое время обнаружения и т.д. Также нужна статистика помехи и вероятность ложного срабатывания или пропуска.


Форму сигнала я вам не скажу так как сам не представляю.
Но получаем его приблизительно так:
1. Радиопередатчик передает синусоиду 1КГц в эфир.
2. Со стороны радиоприемника стоит мое устройство с подключ. микрофоном к АЦП Мега8.
3. Мне нужно определить есть ли на АЦП сигнал частотою 1КГц.
МП41
Это для синхронизации по 6-и точкам что-ли?
GetSmart
Цитата(Alex_1811)
Розжуйте пожалуйста белее популярно (доступно для меня).

В конце обоих строк кода лишние умножения на 30.
Цитата
A:=A+(Signal*sin(cnt*2*Pi*FREQ/512)*30);
B:=B+(Signal*cos(cnt*2*Pi*FREQ/512)*30);
Alex_1811
А от корня квадратного никак избавиться нельзя, для Меги8 напряг.
GetSmart
Цитата(Alex_1811)
А от корня квадратного никак избавиться нельзя, для Меги8 напряг.

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

ЗЫ. Корень можно вычислить 3..5 итерациями методом Ньютона.
Alex_1811
Цитата(GetSmart @ Nov 27 2008, 11:51) *
Или нужно знать реальную амплитуду?

Для данного проэкта не нужно.
Stanislav
Цитата(Alex_1811 @ Nov 27 2008, 10:38) *
Форму сигнала я вам не скажу так как сам не представляю.
Но получаем его приблизительно так:
1. Радиопередатчик передает синусоиду 1КГц в эфир.
2. Со стороны радиоприемника стоит мое устройство с подключ. микрофоном к АЦП Мега8.
Непонятно что-то.
Сталыть, передатчик передаёт синусоиду в эфир.
А ловите его Вы микрофоном.
Если учесть, что плотность эфира =0, Ваша система работать не должна.

Цитата(Alex_1811 @ Nov 27 2008, 10:38) *
...3. Мне нужно определить есть ли на АЦП сигнал частотою 1КГц.
Я предлагаю Вам начать с простейших фильтров, на которых можно изучить элементарные свойства цифровой фильтрации, а затем уже двигаться дальше.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.