Do wejścia ADC został doprowadzony sygnał analogowy o paśmie około
100-5000Hz. Co pewien czas w sygnale pojawia się wyraźnie dominująca składowa o częstotliwości od 200 do 4000Hz. Poza nią jest trochę szumu i zakłóceń harmonicznych. Ten dominujący sygnał trwa min. 0.2 sek. Zwykle około 1 sek. W tym czasie jego amplituda może się zmienić nawet 10 razy. Częstotliwość trochę się zmienia ale w zakresie 0.2 sek. w praktyce można uznać ją za stałą.
W jaki sposób programowo wykryć pojawienie się tego dominującego sygnału i określić jego częstotliwość z dokładnością około 1% ?
Paweł
Didn't find your answer? Ask the community — no account required.
I
identyfikator: 20040501
ponoć najlepszym w tym wypadku byłby filtr adaptacyjny...
M
MH
FFT
I
identyfikator: 20040501
aj sory, częstotliwość jest nieznana, to nie.
K
Konop
Zależy na ile ta składowa jest "dominująca".. zakładam, że wybija się znacznie ponad tło... wówczas robisz to tak... podajesz sygnał, przez dobry filtr AA. Próbkujesz go 20kHz i z każdej paczki po 0,1s liczysz FFT. Mierzysz średni poziom sygnału w zakresie 200-4000Hz. Jeśli jakaś próbka przekracza ZNACZNIE poziom średni (żeby ustalić ten próg trzeba znać widmo przebiegu bez sygnału i z sygnałem) to przyjmujesz, że to jest Twój sygnał... przy danych jak wcześniej FFT liczone jest z 2000 próbek, czyli masz rozdzielczość na poziomie 10Hz... czyli dla 4kHz masz mały bład, ale dla 200Hz jest to aż 5% błędu... jeśli to zły wynik - musisz zwiększyć częstotliwość próbkowania lub zwiększyć okno czasowe... ale jego zwiększenie może spowodować, że nie zauważysz sygnału (pamiętaj, że jest on wysyłany asynchronicznie, więc może przyjść w połowie Twojego okna)....
Pozdrawiam Konop
P
Paweł
Tak chciałem to zrobić. Wykonałem nawet kilka doświadczeń. Jednak jak FFT jest liczone dla malej ilości próbek np. dla 200 to trudno wykryć ten właściwy sygnał. Zwiększenie ilości punktów np. do 2000 daje bardzo dobre rezultaty ale wymaga znacznego zwiększenia ilości częstotliwości dla których jest liczone FFT. W praktyce na tanim ARMie mogę to zrobić w czasie rzeczywistym tylko dla 40-50 częstotliwości. Aby wykonać to z rozdzielczością 10Hz potrzebny jest min. 10x szybszy procesor. Tego jednak chcę uniknąć. Szukam więc jakiegoś prostszego algorytmu.
Paweł
K
Konop
Dla 2000 czy dla 2048?? :)... Bo to mała różnica, algorytm FFT jest optymalny dla ilości próbek równych 2^k ;)... Swoją drogą - nie implementowałem takiego FFT nigdy.. ale wydaje mi się, że ARM powinien sobie z tym poradzić ;)... na ile go puszczasz?? 60MHz, 70?? i z jakiej biblioteki FFT korzystasz?? czy proc robi coś w tle, czy może 100% swoich możliwości przekazać na te obliczenia??
Pozdrawiam Konop
P
Paweł
Dla mojego algorytmu jest to bez znaczenia. Szuka się największego prążka a nie dokładnej amplitudy. Dla obliczenia amplitudy trzeba wykonać jeszcze dzielenie przez ilość próbek. Dla 2048 można zastąpić je przesunięciem co jest szybsze.
... Swoją drogą - nie
FFT sam sobie napisałem w ASM. W praktyce dla 50MHz ARMa w czasie
1/16000 sek. (co tyle są pobierane próbki z ADC) można wykonać obliczenia tylko dla 40-50 częstotliwości.
Paweł
P
pgw
Ciekawy jestem co to za algorytm zastosowales, ktoremu bez roznicy jest czy to 2000 czy to 2048 probek, pytam bez sarkazmu z ciekawosci :)
A po co liczysz FFT dla kazdej nowej probki? to Ci nic nie daje.
P
pgw
Rozdzielczosc 10Hz ale blad 5Hz - 2,5%
Zwiekszenie czestotliwosci probkowania nie poprawi rozdzielczosci częstotliwosciowej tylko zwiekszy pasmo, tu trzeba zwiekszyc okno do 0,25s
P
Paweł
Oczywiście w FFT trzeba wykonać tym więcej operacji im więcej jest próbek danych. Ja jednak wykonuję FFT w czasie rzeczywistym (może lepiej powiedzieć sukcesywnie). Czyli co odczyt z ADC muszę zrobić obliczenia dla wszystkich częstotliwości ale tylko dla dwóch próbek. Dla aktualnej i dla opóźnionej. Czy ta opóźniona próbka jest o 100 czy o 4096 odczytów z ADC nie ma wpływu na czas obliczeń.
Precyzyjniej należy powiedzieć, że mam wynik FFT co próbkę z ADC. Nie wpływa to na obciążenie uP a gwarantuje, że nie przegapię poszukiwanego sygnału.
Paweł
P
pgw
Przyznaje, ze nie rozumiem tego. Co to znaczy ze liczysz dla 2 probek i co to jest próbka opózniona?
Jezeli co 62,5ns jestes wstanie policzyc FFT dla 50 próbek to w 11ms bedziesz wstanie policzyc FFT dla 4096 próbek. Czyli wynik FFT dostawalbys co okolo 180 próbka a nie co jedna. Rzeczywiste FFT nie koniecznie oznacza wynik co jedna próbka. Skoro sygnał który chcesz wyłapac trwa najkrócej 200ms to dostając wynik FFT co 11ms spewnościa go nie przegapisz.
Przy czasie okna 256ms masz rodzielczość czestotliwościową FFT ok 4Hz czyli błąd 2Hz.
K
Konop
Fakt, zgadam się, mój błąd!
Tu też się przyznaje do błędu i dziękuje za poprawienie mnie :)...
Pozdrawiam Konop
K
Konop
I tu jest błąd!! Algorytm FFT jest SZYBKI tylko i wyłącznie, jeśli masz ilość próbek równą 2^N!!!! Chyba, że Twój algorytm automatycznie uzupełnia analizowany ciąg zerami...
To ja chyba nie wiem, jak się liczy FFT :P...
Jeśli chcesz mi powiedzieć, że analizowanie tego FFT co próbkę nie zużywa więcej czasu procesora niż analizowanie co 0,1s, to OK :)...
Pozdrawiam Konop
P
Paweł
Próbka opóźniona oznacza wartość odczytaną z ADC np. 2000 odczytów wcześniej.
Wykonuję obliczenia sukcesywnie. Zauważ, że znając wyniki FFT dla danego okienka próbek już łatwo obliczyć FFT dla okienka przesuniętego o jedną próbkę. Wymaga to tylko kilku prostych działań. Właśnie te obliczenia wykonuję po każdym odczycie z ADC. Do ich przeprowadzenia konieczna jest właśnie wartość danej próbki i próbki z drugiego końca okienka czyli opóźnionej.
W ciągu 62,5uS mogę policzyć FFT dla 2 próbek i 50 częstotliwości. Dla
2048 próbek i 400 częstotliwości (co 10Hz) zajmie to już 0.5 sek.
Paweł
P
Paweł
Niestety już dano temu uczyłem się o transformacie Fouriera. Nie jest wykluczone, że to co robię nie jest to FFT tylko liczenie transformaty metodą "tradycyjną". Bardzo prosty algorytm ale wymaga wielu mnożeń. Chyba muszę się trochę doszkolić.
Paweł
P
pgw
Nie slyszalem o czyms takim, mozesz podać jakieś zródla?
J
J.F.
Niekoniecznie - sa algorytmy na inne ilosci, ale nie dowolne.
J.
P
Paweł
Opierałem się jedynie na tym co bardzo bardzo dawno temu się nauczyłem. Tak więc oczywiście mogłem popełnić jakieś podstawowe błędy i zrobić coś kompletnie bez sensu.
Dla poszczególnych częstotliwości liczę coś takiego A=P1*Cos(k1)+P2*Cos(k2)+P3*Cos(k3)...+Pn*Con(n) B=P1*Sin(k1)+P2*Sin(k2)+P3*Sin(k3)...+Pn*Sin(n)
gdzie: P0,P1,P2,P3... kolejne próbki z ADC n ilośc próbek dla jakiej przeprowadza się operacje Cos(k1),Sin(k1),Cos(k2),Sin(k2),Cos(k3)... stablicowane wartości funkcji Cos i Sin (różne dla różnych częstotliwości). Amplituda danej składowej jest proporcjonalna do SQR(A*A+B*B)
Aby obliczyć A i B dla okienka przesuniętego jedną próbkę wystarczy policzyć:
Tak więc liczę tylko coś takiego dla różnych częstotliwości po odczytaniu próbki z ADC.
Dodatkowo liczę A*A+B*B aby porównać prążki i przeprowadzam operacje na wskaźnikach do tablicy Sin i Cos. Długości tych tablic są rożne dla różnych częstotliwości.
Dla ARMa jest to łącznie tylko około 20-25 instrukcji w asm na jedną częstotliwość. Ma on instrukcję MLA mnożenia i jednoczesnego dodawania. Przy odpowiednio dobranych argumentach dla AT91SAM7S wykonuje się ona teoretycznie 2 cykle.
Paweł
K
Konop
Tak, wiem :). Nie zmienia to faktu, że najszybsze są FFT dla 2^N.. dla innych liczb (np. 3*2^N) można zrobić to też szybko (tzn. szybciej niż klasyczną transformatą ;), jednak ciut wolniej, prawda?? :)...
Pozdrawiam Konop
Join the Discussion
Have something to add? Share your thoughts — no account required.
Didn't find your answer?
Ask the community — no account required
Report Content
You are reporting this content to the moderators. They will look at it
ASAP.