Я пытаюсь найти нулевые пересечения синусоидальной волны, чтобы преобразовать синусоидальную волну в квадратную. Единственная проблема в том, что синусоида шумит, поэтому я получаю много джиттера и ложных пересечений нуля.
Кто-нибудь может порекомендовать какой-нибудь простой psuedocode или соответствующие материалы? Пока что у меня есть что-то вроде этого:
if (sample[i]>0 && sample[i+1]<0) || (sample[i]<0 && sample[i+1]>0)
Кто-нибудь может порекомендовать более надежный метод?
Ответы:
Вы можете попробовать низкочастотную фильтрацию входного сигнала, чтобы получить более плавные пересечения нуля (или даже полосовую фильтрацию, если у вас есть хорошее представление о частотном расположении синусоидальной волны). Существует риск того, что если для вашего приложения важна точная информация о фазе, может возникнуть проблема с дополнительным запаздыванием фильтра.
Другой подход: вместо того, чтобы пытаться преобразовать синусоидальную волну в прямоугольную, как насчет того, чтобы заставить независимый осциллятор прямоугольной формы совмещаться по фазе / частоте с синусоидальной волной? Это можно сделать с помощью фазовой автоподстройки частоты .
источник
То, что вы показали, это детектор пересечения нуля. На ум приходит пара вещей, которые могут улучшить вашу ситуацию:
Если у вас есть шум, который находится за пределами полосы вашего сигнала (что почти наверняка имеет место, поскольку ваш вход является чистым тоном), то вы можете улучшить отношение сигнал / шум, применив полосовой фильтр вокруг интересующего сигнала. , Ширина полосы пропускания фильтра должна выбираться исходя из того, насколько точно вы знаете синусоидальную частоту априори . За счет уменьшения количества шума, присутствующего на синусоиде, количество ложных пересечений нуля и их дрожание относительно правильного времени пересечения будут уменьшены.
Что касается самого детектора пересечения нуля, вы можете добавить некоторый гистерезис к процессу. Это предотвратит создание дополнительных ложных измеренных пересечений вокруг правильного момента пересечения. Добавление гистерезиса к детектору может выглядеть примерно так:
По сути, вы добавляете какое-то состояние к вашему детектору пересечения нуля. Если вы считаете, что входной сигнал имеет положительное значение, вам необходимо, чтобы сигнал опустился ниже выбранного порогового значения
-T
, чтобы объявить реальное пересечение нуля. Точно так же вы требуете, чтобы сигнал поднялся выше порогаT
, чтобы объявить, что сигнал снова вернулся в положительное положение.Вы можете выбрать пороговые значения так, как хотите, но для сбалансированного сигнала, такого как синусоида, имеет смысл, чтобы они были симметричны относительно нуля. Этот подход может помочь вам получить более чистый внешний вид, но он добавит некоторую задержку по времени из-за того, что вы фактически измеряете пересечения с ненулевым порогом вместо пересечений с нулем.
Как предположили в своем ответе пикенетки, петля с фазовой синхронизацией, скорее всего, была бы наилучшим способом, поскольку ФАПЧ делает в значительной степени именно то, что вы пытаетесь сделать. Короче говоря, вы запускаете генератор прямоугольных импульсов, который работает параллельно входной синусоиде. ФАПЧ выполняет периодические измерения фазы на синусоиде, затем фильтрует этот поток измерений, чтобы управлять мгновенной частотой генератора прямоугольных импульсов. В какой-то момент петля будет (надеюсь) заблокирована, и в этом случае прямоугольная волна должна быть синхронизирована по частоте и фазе с синусоидой входа (конечно, с некоторой ошибкой; в разработке ничего не бывает идеально).
источник
T
. Значение вместо&& (sample[i - 1] > -T) && (sample[i] < -T))
, используйте&& (sample[i - 1] >= -T) && (sample[i] < -T))
. Это должно быть применено к обоимif
иelse if
заявлениям.У меня есть хороший опыт с очень простым методом, чтобы найти изменения знака сигнала в разы:
среднее / медиана каждого кластера, это ваш знак изменения
сделать корреляцию с функцией шага в точке, предсказанной 4
В моем случае 5 и 6 не увеличивают точность метода. Вы можете смешать ваш сигнал с шумом и посмотреть, поможет ли это.
источник
Я знаю, что этот вопрос довольно старый, но недавно мне пришлось внедрить пересечение нуля. Я реализовал способ, предложенный Даном, и довольно доволен результатом. Вот мой код на Python, если кому-то интересно. Я не очень элегантный программист, пожалуйста, терпите меня.
Примечание Pls: мой код не обнаруживает признаков и использует немного априорное знание целевой частоты для определения порога времени. Этот порог используется для группировки нескольких пересечений (разные цветные точки на рисунке), из которых выбирается ближайший к медиане групп (синие крестики на рисунке).
источник