Próbuję znaleźć przejścia przez zero fali sinusoidalnej, aby przekształcić falę sinusoidalną w falę kwadratową. Jedyny problem polega na tym, że fala sinusoidalna jest hałaśliwa, więc mam dużo drgań i fałszywych przejść przez zero.
Czy ktoś może polecić prosty kod psued lub odpowiednie materiały? Do tej pory mam coś takiego:
if (sample[i]>0 && sample[i+1]<0) || (sample[i]<0 && sample[i+1]>0)
Czy ktoś może polecić bardziej niezawodną metodę?
Odpowiedzi:
Możesz spróbować filtrować dolnoprzepustowy sygnał wejściowy, aby uzyskać płynniejsze przejścia przez zero (lub nawet filtrowanie pasmowo-przepustowe, jeśli masz dobre pojęcie o lokalizacji częstotliwości fali sinusoidalnej). Ryzyko polega na tym, że jeśli dokładne informacje o fazie są niezbędne dla twojej aplikacji, dodatkowe opóźnienie z filtra może stanowić problem.
Inne podejście: zamiast próbować przekształcić falę sinusoidalną w falę kwadratową, co powiesz na uzyskanie niezależnego oscylatora fali prostokątnej, który wyrówna się fazowo / częstotliwościowo z falą sinusoidalną? Można to zrobić za pomocą pętli synchronizacji fazy .
źródło
Z pewnością pokazałeś wykrywacz przejścia przez zero. Przychodzi mi na myśl kilka rzeczy, które mogą poprawić twoją sytuację:
Jeśli masz szum, który znajduje się poza pasmem sygnału (co jest prawie na pewno tak, ponieważ twój sygnał wejściowy jest czystym tonem), możesz poprawić stosunek sygnału do szumu, stosując filtr pasmowy wokół interesującego sygnału . Szerokość pasma przepustowego filtra należy wybrać na podstawie tego, jak dokładnie znasz częstotliwość sinusoidalną z góry . Poprzez zmniejszenie ilości szumu obecnego na sinusoidzie, liczba fałszywych przejść przez zero i ich fluktuacje dotyczące prawidłowych czasów przekroczenia zostaną zmniejszone.
W odniesieniu do samego detektora przejścia przez zero możesz dodać do procesu pewną histerezę . Zapobiegnie to generowaniu dodatkowych fałszywych zmierzonych skrzyżowań wokół właściwej chwili przejścia. Dodanie histerezy do detektora może wyglądać mniej więcej tak:
Skutecznie dodajesz pewien stan do detektora przejścia przez zero. Jeśli uważasz, że sygnał wejściowy ma wartość dodatnią, musisz obniżyć sygnał poniżej wybranej wartości progowej
-T
, aby zadeklarować rzeczywiste przekroczenie zera. Podobnie, wymaga się, aby sygnał wzrósł ponownie powyżej proguT
, aby zadeklarować, że sygnał ponownie oscyluje z powrotem na dodatni.Możesz wybrać progi, które chcesz, ale dla zrównoważonego sygnału, takiego jak sinusoida, sensowne jest, aby były symetryczne względem zera. Takie podejście może pomóc w uzyskaniu bardziej przejrzystego wyniku, ale doda pewne opóźnienie czasowe ze względu na fakt, że faktycznie mierzysz niezerowe przejścia progowe zamiast przejść przez zero.
Jak sugerują piknetyle w swojej odpowiedzi, pętla z zablokowaną fazą byłaby najprawdopodobniej najlepszym sposobem, ponieważ PLL robi dokładnie to, co próbujesz zrobić. Krótko mówiąc, uruchamiasz generator fali prostokątnej, który działa równolegle z sinusoidą wejściową. PLL dokonuje okresowych pomiarów fazy na sinusoidzie, a następnie filtruje ten strumień pomiarów, aby sterować chwilową częstotliwością generatora fali kwadratowej. W pewnym momencie pętla zostanie (miejmy nadzieję) zablokowana, w którym to momencie fala prostokątna powinna zostać zablokowana częstotliwościowo i fazowo za pomocą sinusoidy wejściowej (oczywiście z pewnym błędem; nic w inżynierii nie jest idealne).
źródło
T
. Znaczenie zamiast&& (sample[i - 1] > -T) && (sample[i] < -T))
, użyj&& (sample[i - 1] >= -T) && (sample[i] < -T))
. Należy to zastosować zarówno do oświadczeń, jakif
i do nichelse if
.Mam dobre doświadczenie z bardzo prostą metodą znajdowania zmian w znakach w czasie:
średnia / mediana każdego klastra, jest to zmiana znaku
wykonać korelację z funkcją kroku w punkcie przewidywanym przez 4
W moim przypadku 5 i 6 nie zwiększają precyzji metody. Możesz roztrzaskać swój sygnał hałasem i sprawdzić, czy to pomaga.
źródło
Wiem, że to pytanie jest dość stare, ale ostatnio musiałem wdrożyć przejście przez zero. Wdrożyłem zgodnie z sugestią Dana i jestem raczej zadowolony z wyniku. Oto mój kod python, jeśli ktoś jest zainteresowany. Nie jestem naprawdę eleganckim programistą, proszę o wyrozumiałość.
Uwaga: mój kod nie wykrywa znaków i wykorzystuje niewielką a priori wiedzę na temat częstotliwości docelowej w celu ustalenia progu czasowego. Ten próg służy do grupowania wielokrotnego przekraczania (różne kolorowe kropki na zdjęciu), z którego wybierana jest ta najbliższa medianie grup (niebieskie krzyże na zdjęciu).
źródło