Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[ARM] LPC11xx i cyfrowa filtracja

15 Wrz 2011 11:12 3445 24
  • Poziom 35  
    Witam,

    Sampluję sobie za pomocą ADC jakiś przebieg, z którego chcę odfiltrować tylko i wyłącznie częstotliwość 40kHz (w celu dalszej obróbki sygnału). Częstotliwość próbkowania ≈90ksps. Sygnał po odfiltrowaniu będzie badany na okoliczności przesunięcia w fazie (pomiar czasu od szczytu do szczytu).
    Wiem oczywiście że do użycia są gotowe filtry cyfrowe, kalkulatorki do współczynników itp itd, ale, że jako się słabo znam na DSP, stąd pytanie: jaki filtr? FIR, IIR? Chciałoby się precyzyjnie wyciąć wszystko inne, co nie jest 40kHz (czyli np. 42kHz powinien już być wycięty, tj. stłumiony conajmniej kilka razy).

    Nie jest problemem implementacja filtra, tyle, że po prostu nie mam pojęcia jaki filtr, i od której strony do tego podejść...
  • Poziom 38  
    Właśnie... W DSP tak naprawdę nie ma nic uniwersalnego. "Jakiś przebieg" to trochę mało żeby określić czego potrzebujesz, nie da się określić jaki filtr Ci będzie za bardzo potrzebny :) Potrzebujesz tylko 40kHz i nic innego więcej czy 0-40 ? Sama informacja jak rozumiem jest zawarta w dziedzinie częstotliwości ? Jakie częstotliwości może zawierać sygnał który próbkujesz ?
  • Poziom 35  
    Próbkowany sygnał może, i będzie, zawierał różnorakie śmieci o bliżej nieokreślonej amplitudzie. Potrzebuję tylko 40kHz, precyzyjnie wyciąć z tych sampli które generuje ADC, i następnie obrabiać. Wszystko wolniejsze od 40kHz i szybsze od 40kHz trzeba ubić.
    Oczywiście jeszcze w torze analogowym obecny będzie dolnoprzepustowy filtr antialiasingowy z "kolankiem" przy 45kHz.
    Po filtracji oczekuję dostać bufor/kolejkę sampli w których zostało już tylko 40kHz o "jakiejś" amplitudzie, a dalsza obróbka będzie polegać na algorytmie szukającym przesunięcia w fazie tego 40KHz-owego sygnału. Ten algorytm nie jest trudny, więc nie o niego mi chodzi ;]

    Możemy założyć, że te 40kHz to będzie wmiksowany przebieg sinsoidalny w szumy, zakłócenia od komórek, cewek elektromagnetycznych, generatorów prądu, transformatorów itp, przy czym ten 40kHz sinus według założeń powinien być dominujący.
  • Pomocny post
    Poziom 38  
    Skoro implementacja i tym podobne rzeczy to nie problem, to może filtr IIR rekursywny wąskopasmowy ? Taki odwrócony notch - wydaje się być akuratny.
  • Poziom 35  
    Też właśnie o tym myślałem, aby użyć IIR, ale mam pewne niewielkie obawy, ponieważ nie jestem w stanie sobie w mózgu wyobraźić, na czym polega "infinite impulse response" (w przeciwieństwie do FIR, który dobrze rozumiem). Zgaduję, że polega to na tym, że jak przez filtr przejdzie impuls 40kHz, to nawet gdy impuls wejściowy sie skonczy, to filtr po wsze czasy będzie z siebie wypluwał ciągły przebieg 40kHz tyle, że z malejącą amplitudą?...dobrze myślę?
  • Poziom 27  
    Ten "nieskończony" przebieg zginie w szumie zaokrągleń i rozdzielczości zmiennych na jakich będziesz operował (o ile filtr będzie stabilny).
    Czas trwania tego "echa" możesz określić wyznaczając odpowiedź impulsową filtra.

    Inna kwestia:
    chcesz sygnał 40kHz samplować z częstotliwością 90kHz i później mierzyć czas od szczytu do szczytu.

    - co jest częstotliwością wzorcową, względem której wyznaczasz przesunięcie fazy?
    - zrób sobie małą symulację w dowolnym programie do obróbki dźwięku. Stwórz nowy plik, z f samplowania 96kHz i wygeneruj przebieg powiedzmy 41kHz. Zrób zoom na poszczególne próbki i ... wyciągnij wnioski...
  • Pomocny post
    Specjalista - Mikrokontrolery
    http://en.wikipedia.org/wiki/Infinite_impulse_response

    Nieskończona jest odpowiedź na impuls, a nie na jakiś "nieimpulsowy" sygnał. Na wiki fajnie porównali do prostego filtra RC, który też ma nieskończoną odpowiedź, tyle że malejącą exponencjalnie.

    Tak jak napisano na wiki, projektowanie filtra IIR jest bardziej skomplikowane, może on być niestabilny, jednak jest bardziej wydajny (wymaga mniejszej mocy obliczeniowej). Filtr FIR jest prostszy w zaprojektowaniu, zawsze stabilny, ale mniej wydajny. Wszystko więc zależy od tego który rząd filtra pragniesz uzyskać (;

    Jeśli uda Ci się sprawę rozwiązać przy użyciu fixed-point, to mnie by się chyba nie chciało kombinować z IIR, zysk wydajności nie będzie duży. Z drugiej strony LPC11xx jakiejś specjalnej mocy nie mają, od Twojej aplikacji zależy więc ile wolnej mocy przewidujesz dla filtra.

    4\/3!!
  • Poziom 35  
    Ok, zasada działania filtra IIR mniej lub bardziej rozpracowana ;]

    No i zrobiłem symulację, nadal wszystko wygląda tak, jak tego oczekiwałem - odpowiedni zoom pokazuje obecność "liczby w punkcie", czyli są sample połączone liniami (aby przebieg sprawiał wrażenie ciągłego) ;]
    Algorytm szukający przesunięć w fazie nie wymaga czestotliwości wzorcowej - planuję implementację "szukacza", który czytając FIFO (zapełniane przez filtr w przerwaniu, co sampel), będzie wyznaczał stałą o nazwie co_ile_próbek_jest_szczyt. Jako, że nie jest mi potrzebna informacja o ile wystąpiło przesunięcie ani przez jaki czas jest przesunięcie, algorytm ustawi flagę gdy analizując nowe próbki trafi na
    Code:

    bierzace_co_ile_próbek_jest_szczyt(+-tolerancja) != wzorcowe_co_ile_próbek_jest_szczyt

    wyłapując dokładnie moment kiedy sygnał właśnie się przesunął w fazie. To, że analizując kolejne próbki znowu co_ile_próbek_jest_szczyt będzie bliska/równa wzorcowi, to wiem, ale w niczym to już nie przeszkadza.

    Są w tym jakieś dziury?
  • Poziom 38  
    __Grzegorz__ napisał:
    - zrób sobie małą symulację w dowolnym programie do obróbki dźwięku. Stwórz nowy plik, z f samplowania 96kHz i wygeneruj przebieg powiedzmy 41kHz. Zrób zoom na poszczególne próbki i ... wyciągnij wnioski...


    Nie szkodzi, że to w ogóle nie będzie podobne do sygnały wejściowego. Mimo wszystko i tak w 100% da się odtworzyć sygnał oryginalny (Jedynym warunkiem jest pozbycie się aliasingu).
  • Poziom 35  
    Freddie Chopin napisał:
    Jeśli uda Ci się sprawę rozwiązać przy użyciu fixed-point, to mnie by się chyba nie chciało kombinować z IIR, zysk wydajności nie będzie duży. Z drugiej strony LPC11xx jakiejś specjalnej mocy nie mają, od Twojej aplikacji zależy więc ile wolnej mocy przewidujesz dla filtra.

    Fixed point to zupełna podstawa do dalszej dyskusji; tutaj zupełnie nie przewiduję żadnych problemów - tak jak napisałem, problemem nie jest implementacja, tyle, że muszę wiedzieć, co implementować ;]

    Sądzę, że IIR będzie znacznie wydajniejszy, niż FIR; nie wyobrażam sobie w przerwaniu co 11us mielić forem np. 64 próbki, i jeszcze dokonywać na nich pokręconych operacji matematycznych; zdaje się, że gdzieś widziałem po prostu rekurencyjną funkcję która realizując filtr zmniejszała ilość operacji co próbkę do minimum...
    Chcę oczywiście skorzystać z gotowych obliczarek współczynników do takiego filtra, więc sądzę, że kwestię stabilności mogę tymczasowo odsunąć na później. Dodatkowo, w razie problemów z samym filtrem, można go obudować logiką resetującą/wstrzymującą/robiącą_mu_cos_innego.

    Dodano po 1 [minuty]:

    gaskoin napisał:
    Mimo wszystko i tak w 100% da się odtworzyć sygnał oryginalny (Jedynym warunkiem jest pozbycie się aliasingu).

    Dlatego też konieczny jest filtr antialiasingowy, o którym pisałem wcześniej. To w końcu tylko jeden opamp...
    Nie potrzeba mi również widzieć po stronie "za filtrem" ani "przed filtrem" tego sinusa, który faktycznie jest widoczny po stronie analogowej. Tam może być dowolny krzak, byle by miał gdzieś zdefiniowane zbocze/szczyt występujące skończoną (i stałą) ilość razy na jeden okres.
  • Pomocny post
    Poziom 27  
    aliasing pomijam, bo to "oczywista oczywistośc" ;)

    chodziło mi o żałosną rozdzielczość czasową takiego pomiaru zmiany fazy.
    Przy próbkowaniu 90kHz, wartość próbki będzie stała w czasie 11,1us.
    Okres przebiegu 40kHz to 25us, praktycznie co 2 próbka to będzie szczyt przebiegu 40kHz (co jakiś czas co 3 próbki).
    Inna kwestia, że ten szczyt będzie "pływał"...

    41kHz przy fs = 96kHz:
    [ARM] LPC11xx i cyfrowa filtracja

    No chyba, że czegoś nie załapałem w działaniu algorytmu...



    Ale już wiem jak to usprawnić :)
    Zmień znak co drugiej próbki, i z 40kHz spróbkowanych 90kHz zrobi się 5kHz spróbkowane 90kHz (inwersja widma).
    to da 18 próbek na okres, i zwiększy dokładność pomiaru...
  • Poziom 35  
    Zgadza się, o tym nie pomyslałem ;/

    sądzę, aby prawidłowo móc mierzyć czas od szczytu według mojego zamysłu, potrzebuję samplować ten przebieg z częstotliwością wielokrotnie większą, a nie nieco ponad 2 razy większą. Szacuję, że 250ksps to minimum, bo da to 6.25 próbek na okres, więc znacznie lepiej niż przy 90kHz, ale o jakiejkolwiek precyzji tej detekcji przesunięcia w fazie można zapomnieć...

    Ale próbkowanie 250ksps juz znacząco obciąży procesor, wiec patent odpada. Chyba będę musiał pokombinować jednak przy torze analogowym, dostawić analogowy filtr, wzmocnić do "prostokąta", i timerem+przerwaniem badać to przesunięcie w fazie...

    __Grzegorz__ napisał:
    Zmień znak co drugiej próbki, i z 40kHz spróbkowanych 90kHz zrobi się 5kHz spróbkowane 90kHz (inwersja widma).

    Mniej lub bardziej wyobrażam sobie na czym to polega, 18 próbek na okres już jest nieźle, ale gdzie jest haczyk?
  • Poziom 27  
    nie ma, tylko niebezpieczeństwo aliasingu częstotliwości.
    Taka prosta sztuczka DSP...

    Jak spróbkujesz to nie 90k, ale np 81kHz, to po odwróceniu znaku co drugiej próbki będziesz miał sygnał 500Hz... (160 próbek na okres)... :)
  • Poziom 35  
    Nadal nie do końca rozumiem jak ten patent działa. 160próbek na okres to już zupełnie cudo, i pozwoli na nader precyzyjną detekcję przesunięcia w fazie.
    Tylko - czy jest w necie taki dokument który opisuje na czym ta inwersja widma polega? Po googlowaniu "inwersja widma" wyskakują mi jakieś niewiele z DSP związane dywagacje naukowe ;]
    No i przydałoby się mieć ten wzór według którego policzyłeś ze z 40kHz zrobi się 500Hz przy próbkowaniu 81kHz...

    Mam tylko wątpliwości co do zmiany znaku - wszystkie próbki siłą rzeczy będą miały znak dodatni (bo tak je widzi ADC), czy tu wystarczy po prostu na pałę zmieniać znak co drugiej próbki?
  • Poziom 27  
    nie, trzeba będzie odjąć połowę zakresu przetwornika, albo zrobić prosty filtr DC w postaci prostego filtru górnoprzepustowego IIR :)

    Podstawy teoretyczne:
    cos(a) * cos (b) = 1/2 * [cos (a+b) + cos(a-b)].

    Tak, będzie aliasing, ale pożyteczny akurat tutaj :)

    Dokładniej:
    mamy sygnał 40kHz. (załóżmy, że stały), i częstotliwość próbkowania zmienną.

    Na początek 90kHz.
    Czyli pasmo od 0 do 45kHz. Zmiana znaku co drugiej próbki odpowiada wymnożeniu oryginału przez częstotliwość będącą połową fs, czyli przez 45kHz.

    Zatem powstaną 2 składowe: -5kHz i 85kHz. a pierwsza, po aliasingu (wzgl. 0Hz) znajdzie się w 5kHz,
    85kHz (zawinięty wzgl. 45kHz) też trafi na 5kHz...)

    Mamy 5kHz, przy fs - 90kHz, czyli 18 próbek na okres jak nic...

    No ot teraz 81kHz... (fs = 40,5kHz),
    różnica 40k i 40,5k będzie -0,5kHz, suma 80,5, po zawinięciu wzgl fs/2 też da 500...

    500Hz przy fs=81kHz to 162 próbki...
  • Poziom 35  
    I tak nie załapałem o co chodzi z tym wzorem, ale sięgam właśnie do stosownej literatury ;] Z pokazanych tam wzorów na bandpass sampling sądzę, że częstotliwością próbkowania można zjechać jeszcze niżej, odciążając procesor ;]
    No i o filtrach też tam jest, sądzę, że sobie jakoś poradzę z postawionym tu zadaniem...

    Dodano po 5 [godziny] 11 [minuty]:

    Tak w skrócie to samo napisane jest w książce którą zacząłem maniakalnie czytać, czyli R.G. Lyons - Understanding Digital Signal Processing ;)
    Dzięki wielkie za naprowadzenie - chyba wezmę się za dsp tak, jak to powinien cywilizowany człowiek zrobić ;] Zrozumiałem, że ograniczając pasmo, aliasing pozwala na rekonstrukcję przebiegu z danego pasma próbkując wolniej niż 2*fmax...
  • Poziom 2  
    Cytat:
    Tak w skrócie to samo napisane jest w książce którą zacząłem maniakalnie czytać, czyli R.G. Lyons - Understanding Digital Signal Processing


    Ta książka, od dłuższego czasu, jest też w polskim wydaniu : "Wprowadzenie do cyfrowego przetwarzania sygnałów" w przekładzie Jana Zarzyckiego, może Ci będzie łatwiej z tym wydaniem.
  • Poziom 26  
    @nsvinc rozważałeś użycie DFT? tylko jeden prążek 40kHz a na wyjściu dostajesz amplitudę[R] i przesunięcie fazowe[I].
  • Poziom 35  
    eee...to ma sens ;] Tyle, że na DFT się znam jeszcze mniej niż na filtrach ;] Możesz mniej więcej w stanie ocenić ile to zużyje czasu, takie obliczanie co sampel? Na czym mniej więcej polega policzenie DFT dla jednego prążka?...
  • Specjalista - Mikrokontrolery
    z tego co mi wiadomo wynikiem DFT jest liczba zespolona ale interpretacja nie jest taka jak przedstawiłeś (Re - amplituda, Im - faza) tylko należy przekształcić sobie tą liczbę na reprezentację "kątową" i wtedy moduł odpowiada amplitudzie, a kąt - fazie.

    @nsvinc - DFT czy FFT to z grubsza to samo, nie liczysz tego co sampla, tylko dla określonej ilości próbek (co przekłada się na rozdzielczość takiego wyliczenia). Nie dostaniesz w wyniku JEDNEGO prążka, ale po prostu dla tych 40kHz będzie właśnie jeden. Jeszcze lepszym wyjściem niż DFT/FFT jest tzw. algorytm Goertzla - http://en.wikipedia.org/wiki/Goertzel_algorithm . Jego zadaniem jest wykrycie JEDNEJ konkretnej częstotliwości. Nie jestem jednak pewien, czy w wyniku dostajesz też fazę...

    4\/3!!
  • Poziom 26  
    @nsvinc złożoność obliczeniowa dla jednego prążka przy DFT jest pomijalna jeżeli masz FPU.
    Mały opis i przykładowy program do liczenia DFT https://www.elektroda.pl/rtvforum/viewtopic.php?p=6755646#6755646

    @Freddie Chopin Faktycznie ale wyciągnięcie fazy z liczby zespolonej jest banalne.
    Z DFT możesz policzyć tylko 1 prążek, a z FFT musisz liczyć wszystkie.
  • Poziom 27  
    1). Goertzel nie daje info o fazie.
    2). W DFT/FFT, podczas kolejnych obliczeń, faza będzie "skakać" praktycznie zupełnie przypadkowo, w zależności od tego jak "wstrzelisz się" oknem pomiarowym w przebieg, a z każdym pomiarem wstrzelisz się na pewno inaczej...

    Osobiście spróbował bym jeszcze czegoś innego.
    Najpierw filtracja pasmowa, aby uzyskać w miarę czyste 40k,
    a później zrobienie z tego sygnału analitycznego (z wykorzystaniem transformaty Hilberta).
    Mając sygnał analityczny można wyliczać zmianę kąta wektora rysującego ten sygnał (przyrost fazy co próbkę) (różnica atan(Im/Re) dla sąsiednich próbek),
    i mieć kontrolę przyrostu fazy sygnału na bieżąco (co próbkę).

    Kod C transformatora Hilberta można uzyskać na szybko tutaj:
    http://www-users.cs.york.ac.uk/~fisher/mkfilter/
  • Poziom 27  
    Kolejny, prostszy (obliczeniowo) pomysł: operowanie w tzw. baseband, czyli:

    - wymnożenie oryginału przez oscylator zespolony o częstotliwości 40kHz
    ->wejście jako plik stereo,
    ->lewy kanał mnożymy przez sinus(2*pi*40000*t), i mamy część zespoloną iloczynu Im1(n),
    ->prawy przez cosinus(2*pi*40000*t), i mamy część rzeczywistą iloczynu Re1(n);
    oscylator na LUT lub NCO, jak kto lubi i ma zasoby;
    - wynik mnożenia w obydwu kanałach na filtr dolnopasmowy ~20Hz, jakiś prosty IIR nawet pierwszego rzędu, dostajemy Im1'(n) i Re1'(n);

    To co wyjdzie po filtrze DP, to praktycznie będzie faza w czystej postaci.
    obliczenie atan(Im1'(n)/Re1'(n) da ci bieżącą fazę sygnału, Ciebie pewnie będzie interesować różnica dla sąsiednich próbek...

    Jeżeli częstotliwość w sygnale odbiegnie od 40kHz, będzie np 40001, to w wyniku działania ww algorytmu, na wyjściu FDP otrzymasz liniowy (stały) przyrost fazy co próbkę, co jest łatwo wyeliminować...
  • Poziom 35  
    o, to juz jest naprawdę niezły patent ;]

    Czy "oryginał" to są surowe cyfrowe sample, czy mnożyć analogowo poza prockiem?
  • Poziom 27  
    oryginał jest już zsamplowany...

    W załączniku pliki testowe.
    base.wav - 500Hz zmodulowana faza, zmienia się co ok. 10sek o pi/4 (przyrost)
    base_po_mnożeniu_z_oscylatorem.wav - plik źródłowy, jeden kanał wymnożony przez sin, drugi przez cos przebiegu o częstotliwości 500Hz
    base_po_mnożeniu_z_oscylatorem_po_FDP.wav - wynik mnożenia przefiltrowany filtrem dolnoprzepustowym pierwszego rzędu fg = 20Hz

    Oglądając ostatni plik w GoldWave, z wizualizacją XYGraph - pięknie widać zdemodulowaną fazę...0, po 10 sek - 45st, 90, 135, 180 i 235 :)