Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Analiza napięcia zmienn.w czasie z przetwornika A/C - rozkład na częstotliwości

rezontor 11 Feb 2012 23:27 5974 55
Tespol
  • #31
    rezontor
    Level 15  
    Częstotliwość próbkowania zwiększyłem do 250Hz - i wskazania jakby trochę się poprawiły... najlepiej pokazuje częstotliwość 8-13Hz - takich będę akurat potrzebował...
    W tym kodzie zmienne oznaczone % mają być typu Long, a pozostałe wystarczą Integer? Z jakimi wartościami mam do czynienia w innych zmiennych?
  • Tespol
  • #32
    gaskoin
    Level 38  
    raczej floaty

    Możesz też zastosować się do tego co napisał krru i tak jak pisałem wcześniej przyspieszyć ten kod o jakieś 50% stosując rzeczywiste FFT. Kod jest w tej samej książce kilka stron dalej więc powinieneś go znaleźć.
  • #33
    rezontor
    Level 15  
    gaskoin wrote:
    raczej floaty

    w Bascomie zastosuję Single, czyli zmienną która może przechowywać dowolną zmienną stało lub zmiennoprzecinkową pojedynczej precyzji.
    Tak się zastanawiam, o ile procent FFT jest szybsza od DTF z tego kodu:
    https://obrazki.elektroda.pl/1228143400_1328727266.gif

    ?
    Może [jak nie wiele] to warto zastosować DTF /prostszy dużo algorytm/?
  • Tespol
  • #34
    gaskoin
    Level 38  
    Już odpowiadałem na to pytanie. Nie da się odpowiedzieć ile % bo zależność jest nieliniowa. Prosty przykład - dla 5 próbek FFT jest wolniejszy, a dla 300 szybszy. Czym więcej próbek tym wyraźniejsza jest różnica.

    Uwierz mi - wzoru korelacyjnego nie stosuje się dla liczby próbek > 64. Wynik otrzymasz taki sam. W przypadku DFT będzie on jednak trochę mniej dokładny i wolniej otrzymany.

    Złożoność czasowa DFT jest rzędu N^2 natomiast FFt jest to N* log (N).

    przy 256 próbkach DFT trwa 65536 * jakaś tam stały współczynnik czasu
    FFT będzie trwało 2048* stały współczynnik (jest on z reguły mniejszy niż w przypadku DFT).

    Dla porównania w książce z której jest ten kod masz podane te stałe. Dla Pentium 100MHz jest to odpowiednio 25us i 10us. Czyli Twoją transformatę DFT liczy ponad 1.5 sekundy (zauważ, że Twój biedny AVR będzie liczył to dużo dłużej)
    Natomiast FFT policzy w 20ms.

    Dla większej różnicy 4096 próbek DFT policzy w 7 minut a FFT w pół sekundy.
    Widzisz różnicę czy dalej mam Ci mówić że wzór korelacyjny jest bez sensu ?
  • Helpful post
    #35
    Ostry23
    Level 18  
    rezontor wrote:
    Zastosowałem lepszy filtr aktywny antyaliasingowy, oraz podałem na we całą sinusoidę - i dalej to samo.. Coś może z algorytmem tym nie tak..

    No właśnie, jaki zastosowałeś filtr? Jaka częstotliwość odcięcia, rodzaj charakterystyki? Tak jak pisze krru, lepiej sobie odpowiednio daleko odsunąć f_3dB od twojego pasma użytecznego (żeby nie mieć zafalowań pasma i wyraźnych zmian fazy na granicach twojego użytecznego) oraz próbkować z odpowiednio większą częstotliwością. Dzięki temu wystarczy ci łagodnie opadanie ch-ki amplitudowej filtru (np. 40dB/dekadę, czyli filtr dwubiegunowy) co jest łatwiej zrealizować niż dokładny filtr o większej liczbie biegunów.

    A co do samego fft - nie wypowiadam się nt. implementacji w bascomie, gdyż piszę w C, ale jeśli chodzi o samo wyznaczanie widma - nikt tu nie wspomniał o oknach i przecieku. Pamiętaj, że przy zwykłym oknie prostokątnym przeciek może być spory (to oczywiście zależy od sygnału, bo jak się uda trafić z długością okna w okres i podasz czystego sinusa, to przecieku nie będzie). W każdym razie jeśli zależy ci na minimalizacji przecieku, musiałbyś jakieś okno zastosować. A żeby nie musieć mnożyć każdej próbki przez funkcję okna, możesz je sobie stablicować, jeśli tylko masz wystarczająco dużo wolnego ramu/flasha/eepromu, co tam sobie wolisz :). Trochę zajmie wklepanie takiej tablicy do kodu, ale robisz to tylko raz. A dzięki stablicowaniu narzut czasowy na przetworzenie spróbkowanego sygnału przez funkcję okna będzie niewielki.

    Hmm, dopiero teraz widzę, że po stablicowaniu samej funkcji i tak nie unikniesz jednego mnożenia na każdą próbkę sygnału. Cofam wcześniejsze słowa o małym narzucie czasowym :)
    No chyba, że byś sobie stablicował każdą możliwą wartość z ADC z każdą możliwą próbką funkcji okna a to już jest 2^n x N, gdzie n to liczba bitów ADC a N długość transformaty. Ale trochę byś się musiał w kodzie naklepać, żeby popodstawiać te wartości... no i wychodzi na to, że zmieściłoby się toto tylko we flashu a i tak musiałbyś ograniczyć n i N. W każdym razie jest to do zrobienia, ale czy tak się to w praktyce robi, tego nie wiem. Jeśli tak, to pewnie tylko na układach bez sprzętowego mnożenia.
  • #36
    gaskoin
    Level 38  
    Nie proponowałem tych rozwiązań ze względu na bascoma i AVR. Najlepiej tak jak piszą koledzy zwiększyć częstotliwość próbkowania i zastosować jakiś prosty filtr RC a samą filtrację przeprowadzić programowo. Można taki sygnał przepuścić przez np okno Hamminga lub Blackmana okienkowanego funkcją sinc i dopiero potem wykonywać dalsze obliczenia, ale ten avr w bascomie po zebraniu 1024 próbek liczyłby to do końca życia :)

    Można podać jak się to robi "normalnie" ale zauważcie, że autor nie ma tyle mocy obliczeniowej

    Ostry23 wrote:
    ale czy tak się to w praktyce robi, tego nie wiem. Jeśli tak, to pewnie tylko na układach bez sprzętowego mnożenia.


    W rzeczywistości do DSP (metody) używa się DSP (procesora sygnałowego) :)
    One są idealne do takich obliczeń, przy 40MHz, które wydają się śmieszne, można na nich uzyskać nawet i 300 MIPSów lub FLOPSów
  • #37
    Ostry23
    Level 18  
    gaskoin wrote:
    W rzeczywistości do DSP (metody) używa się DSP (procesora sygnałowego) :)
    One są idealne do takich obliczeń, przy 40MHz, które wydają się śmieszne, można na nich uzyskać nawet i 300 MIPSów lub FLOPSów

    No tak, tyle to i ja wiem ;). No ale w DSP-kach masz bufory na sygnał wejściowy i na współczynniki, masz sprzętowy bufor cykliczny do przesuwania okna po sygnale wejściowym, sprzętowy "multiply and accumulate" oraz odwracanie nibbles w bajcie (dobrze mówie?) przydatne właśnie przy FFT. Ja pisałem pod kątem ośmiobitowców, bo z tym się przecież męczy autor projektu :). I tu mi przychodzi do głowy jedynie tablicowanie, no chyba, że nie zależy nam na czasie i możemy sobie wyznaczać fft "offline" i czekać aż się te wszystkie mnożenia wykonają.
  • #38
    rezontor
    Level 15  
    Ostry23 wrote:
    No właśnie, jaki zastosowałeś filtr? Jaka częstotliwość odcięcia, rodzaj charakterystyki?

    fc=35Hz, filtr Butterwortha, 20dB/okt

    Dodano po 39 [minuty]:

    w(n) = 0.53836-0.46164 cos(2PI n / N-1)
    -dla okna Hamminga.

    Czyli najlepiej zastosować jeszcze okno np. Hamminga i da to lepsze rezultaty niż przy używaniu okna prostokątnego (tj. bez żadnego okna)?

    Liczbę próbek ograniczyłem do 128 z powodu braku pamięci, więc czas obliczania powinien się znacząco skrócić.

    Czyli teraz dla każdej pojedynczej próbki n obliczam nową wartość zgodnie ze wzorem pokazanym wyżej, wstawiając za N liczbę próbek, czyli 128, tak?
  • Helpful post
    #39
    Ostry23
    Level 18  
    rezontor wrote:
    fc=35Hz, filtr Butterwortha, 20dB/okt

    chyba 20dB/dek czyli 6dB/okt. 20dB/okt jest raczej trudne do realizacji, bo to jakieś 3 bieguny i trochę ;P

    Dobrze pamiętam, że chciałeś analizować sygnał o paśmie od DC do 35 Hz właśnie? Jeśli tak, to nie możesz dać filtru o fc=35 Hz bo dla tej częstotliwości masz przecież 3dB spadku wzmocnienia, czyli wzmocnienie dla fc to już tylko 0,708 wzmocnienia dla DC. Jeśli nie chcesz wpływać filtrem na interesujące cię pasmo, to musisz odsunąć fc, w tym wypadku dałbym fc rzędu 100-200 Hz a próbkował z f=1kHz (dlatego tak dużo, żebyś dla fsample/2 miał już jakieś sensowne tłumienie filtru, żeby zminimalizować ewentualny aliasing).

    Quote:
    w(n) = 0.53836-0.46164 cos(2PI n / N-1)
    -dla okna Hamminga.
    Czyli najlepiej zastosować jeszcze okno np. Hamminga i da to lepsze rezultaty niż przy używaniu okna prostokątnego (tj. bez żadnego okna)?

    No tak, każde okno inne niż prostokątne zmniejszy tzw. przeciek. Funkcję okna koniecznie stablicuj, potem i tak musisz wykonać przemnożenie sygnału przez okno . Chyba, że zrobisz tak, jak wymyśliłem wcześniej, ale tak jak pisałem, trochę zajmie stablicowanie tego; no i stablicować wartości sygnał(n)*okno(n) da się tylko, gdy próbki sygnału będa typu integer. Jeśli chcesz używać float'ów, stablicowanie odpada. Ale dla float'ów można zapomnieć o realnym czasie przetwarzania.

    Quote:
    Czyli teraz dla każdej pojedynczej próbki n obliczam nową wartość zgodnie ze wzorem pokazanym wyżej, wstawiając za N liczbę próbek, czyli 128, tak?

    Powyższy wzór to sama funkcja okna, dopiero potem mnożysz x(n)*w(n).
  • #40
    rezontor
    Level 15  
    Ostry23 wrote:
    chyba 20dB/dek czyli 6dB/okt.

    - 6dB/okt., błąd się wkradł.

    Ostry23 wrote:
    Dobrze pamiętam, że chciałeś analizować sygnał o paśmie od DC do 35 Hz właśnie?

    Do 30 Hz po zmianie. Filtr fc=35Hz. Obecne próbkowanie: f= 125Hz (więcej nie dam, bo wtedy dokładność [przy 128 próbkach] przedstawienia udziału danej częstotliwości w całym sygnale zmaleje), liczba próbek to jak napisałem - 128.

    Ostry23 wrote:
    Ale dla float'ów można zapomnieć o realnym czasie przetwarzania.

    Nie jest to parametr krytyczny. Zadowalający czas przetworzenia 128 próbek - 0.5sek-1s
    Ostry23 wrote:
    Funkcję okna koniecznie stablicuj

    raczej już nie będę miał pamięci, bo bardzo jest zajęta.
    Ostry23 wrote:
    Jeśli chcesz używać float'ów

    Operuję na zmiennych stało/zmiennoprzecinkowych pojedynczej precyzji tj Single. Więc tablicowanie odpada.

    Czyli pobieram wynik z przetwornika (0-1023), następnie ten wynik- mnożę przez funkcję:
    Code: vb
    Log in, to see the code

    Czy jest ok.?
  • Helpful post
    #41
    Ostry23
    Level 18  
    rezontor wrote:
    Do 30 Hz po zmianie. Filtr fc=35Hz. Obecne próbkowanie: f= 125Hz (więcej nie dam, bo wtedy dokładność [przy 128 próbkach] przedstawienia udziału danej częstotliwości w całym sygnale zmaleje), liczba próbek to jak napisałem - 128.
    W takim razie musisz się liczyć z przekłamaniem sygnału na granicach pasma. Możesz to próbować kompensować w sofcie mnożąc otrzymane fft przez funkcję odwrotną do ch-ki amplitudowej filtru (kolejne mnożenia), ale weź pod uwagę, że z racji rozrzutów elementów R i C w filtrze, nigdy nie ma on dokładnie takiej ch-ki jak to wynika z obliczeń.

    Aha, jeśli używasz Vref wbudowanego w Atmega8 (wartośc 2,56V to sugeruje) to zapomnij o dokładności bezwzględnej - to napięcie ma rozrzut od 2,4 do 2,7V. Jeśli chcesz mierzyć dokładnie postaw na zewnątrz coś lepszego, np. REF192 albo zrób źródełko na TL431 czy innym podobnym. Ewentualnie podepnij AVCC pod AREF, przy założeniu że twoje AVCC pochodzi z w miarę dokładnego źródła napięcia. Ale wbudowanego Vref bym unikał. Ostatnio w jednym projekcie mierzyłem to napięcie na 8 różnych płytkach. Na jednej było ok. 2,5V, na 7 było więcej niż 2,6.

    Analizujesz sygnał od DC, czy jakiejś małej częstotliwości? Jeśli od DC to musisz użyć wzmacniacza o odpowiednio małym napięciu offsetu albo je kompensować (piszesz, że analizujesz z ADC pełną wartość 10bitową, co dla Vref=2560mV daje 1LSB=2.5mV). Jeśli nie od DC i jeśli odcinasz składową stałą, parametry dot. offsetu wzmacniacza nie są tak istotne.
    Zaraz zaraz, chyba się rozpędziłem. Napisałeś, że masz filtr 6dB/okt czyli pewnie sekcja RC, czyli o wzmacniaczu zapominamy.
    Możesz pokrótce opisać jak wygląda tor sygnału od źródła do ADC? Jaka jest Zwy źródła, widziana przez źródło Zwe, co jest dalej po drodze?

    Aha, masz rację, że nie chcesz zwiększać fsample mając N=128. Ten "udział danej częstotliwości" to po prostu rozdzielczość FFT.

    Quote:
    Nie jest to parametr krytyczny. Zadowalający czas przetworzenia 128 próbek - 0.5sek-1s
    Nie sądzę, żeby udało się to osiągnąć, ale bardziej obstawiam, niż wiem. Nie liczyłem, nie wypowiadam się :). A sprawdzałeś ile mniej więcej trwa pod Bascomem jedno mnożenie?

    Quote:
    raczej już nie będę miał pamięci, bo bardzo jest zajęta.
    Rozumiem, że brakuje ci ramu i może też flasha, ale może masz 128 bajtów EEPROMu? Nie wiem jak jest w Bascomie, ale w w avr-libc są makra służące do deklaracji, zapisu i odczytu danych z EEPROM. A jeśli w Bascomie tego nie ma, to może da się wstawić assembler?

    Quote:

    Czyli pobieram wynik z przetwornika (0-1023), następnie ten wynik- mnożę przez funkcję:
    Code: vb
    Log in, to see the code

    Czy jest ok.?

    No niby tak, ale to się przecież będzie liczyło wieki.
  • #42
    rezontor
    Level 15  
    Ostry23 wrote:
    Analizujesz sygnał od DC, czy jakiejś małej częstotliwości?

    Zastosowany został filtr górnoprzepustowy i od kilku Hz przepuszcza dopiero sygnał.
    Ostry23 wrote:
    Nie sądzę, żeby udało się to osiągnąć

    Przetestuję i zobaczę, ale dla częstotliwości zegara taktującego atmegę równej 16MHz to powinno dość krótko chyba trwać. Zobaczę i zmierzę w praktyce.

    Tablicę można zrobić, tylko do tablicy nie mogę wpisywać wartości Single, a zmienna całkowita Integer jest chyba niewystarczająca? Nie będzie dużych przekłamań jak będę zaokrąglał wartości?
  • #43
    Ostry23
    Level 18  
    rezontor wrote:
    Przetestuję i zobaczę, ale dla częstotliwości zegara taktującego atmegę równej 16MHz to powinno dość krótko chyba trwać. Zobaczę i zmierzę w praktyce.
    Szczerze mówiąc nie wiem, ile będzie trwało. Nie wiem też, jak to skompiluje Bascom. Najlepiej sprawdź.

    Quote:
    Tablicę można zrobić, tylko do tablicy nie mogę wpisywać wartości Single, a zmienna całkowita Integer jest chyba niewystarczająca? Nie będzie dużych przekłamań jak będę zaokrąglał wartości?
    No tak, single nie stablicujesz ;). Czyli musisz robić te mnożenia, ale skoro mówisz, że nie zależy na szybkości, to ok.
    Sam jestem ciekaw jak Ci to wyjdzie. Wrzucisz jakiś filmik jak już będzie to w miarę działać?
    Byłbym zapomniał był - dzięki za punkty.
  • #44
    gaskoin
    Level 38  
    rezontor wrote:

    Zastosowany został filtr górnoprzepustowy i od kilku Hz przepuszcza dopiero sygnał.


    A co z dolnoprzepustowym bo się chyba zgubiłem? :)

    rezontor wrote:

    Czyli najlepiej zastosować jeszcze okno np. Hamminga i da to lepsze rezultaty niż przy używaniu okna prostokątnego (tj. bez żadnego okna)?


    Dla sygnału AC tak. Wyciek (czy jak to kolega określił "przeciek" :P) widma bierze się stąd, że DFT jest trochę tworem sztucznym, ponieważ sama transformata fouriera zakłada, że badany sygnał jest ciągły i okresowy. Sztuczka polega na tym, że sygnały nieokresowe, traktuje się jak okresowe z okresem wynoszącym nieskończoność. Inna polega na tym, że badany fragment sygnału traktowany jest jako jeden okres nieskończonego sygnału ciągłego okresowego. Ponieważ pierwsza próbka, jest tak jakby następną próbką po ostatniej próbce (bo sygnał jest okresowy, sorki, nie chce mi się obrazka rysować :P) to w rzeczywistych sygnałach zawsze prowadzi to do nieciągłości na krańcach sygnału. Wprowadza to dodatkowe częstotliwości, wyciek i choroby serca. Po to stosuje się okna, żeby przebiegi te wygładzić. Oczywiście chodzi o dziedzine częstotliwości, bo takie zabiegi są dla niej jak SPA, lecz w dziedzinie czasu informacje są niszczone.

    Musiał byś też popróbować różne okna, dla innych okien możesz uzyskać lepsze rezultaty (lub gorsze :) ) jako, że nie znamy źródła sygnału.
  • Helpful post
    #45
    Ostry23
    Level 18  
    gaskoin wrote:
    A co z dolnoprzepustowym bo się chyba zgubiłem? :)

    Podejrzewam, że koledze rezontorowi chodziło o pasmowoprzepustowy... miejmy nadzieję :)

    gaskoin wrote:
    Wyciek (czy jak to kolega określił "przeciek" :P)

    hmm... tak to u mnie określali prowadzący na studiach... zresztą, taka właśnie nazwa polska (odpowiednik angielskiego leakage) pojawia się w literaturze nt. DSP. Wydaje mi się, że w polskim tłumaczeniu Lyonsa tak to się właśnie nazywa. A nazwy "przeciek" używają też np. tutaj: http://zet10.ipee.pwr.wroc.pl/record/116/files/fft.pdf

    gaskoin wrote:
    Sztuczka polega na tym, że sygnały nieokresowe, traktuje się jak okresowe z okresem wynoszącym nieskończoność

    Rozumiem, że masz na myśli okres wynoszący N (czyli długość transformaty) w przeliczeniu na czas (bo wiemy co ile czasu pobieramy jedną próbkę, czyli mówiąc po inżyniersku znamy częstotliwość próbkowania) a nieskończony to jest czas trwania sygnału. Czyli tak jak mówisz sytuacja sztuczna. Jak wiadomo w przyrodzie sinus nie występuje, a to co mamy z generatora to jedynie mierne odbicie idei sinusa, jakby to powiedział Platon ;P.
    Inna rzecz, że w międzyczasie z sygnału ciągłego w czasie i amplitudzie (taki sygnał analizujemy przy pomocy transformaty fouriera) przechodzimy w domenę cyfrową czyli konwertujemy sygnał na sygnał dyskretny w czasie i amplitudzie a do analizy takiego zastosowanie ma dyskretna transformata fouriera, czyli nasze DFT.

    gaskoin wrote:
    Ponieważ pierwsza próbka, jest tak jakby następną próbką po ostatniej próbce (bo sygnał jest okresowy, sorki, nie chce mi się obrazka rysować :P) to w rzeczywistych sygnałach zawsze prowadzi to do nieciągłości na krańcach sygnału. Wprowadza to dodatkowe częstotliwości, wyciek i choroby serca. Po to stosuje się okna, żeby przebiegi te wygładzić. Oczywiście chodzi o dziedzine częstotliwości, bo takie zabiegi są dla niej jak SPA, lecz w dziedzinie czasu informacje są niszczone
    No lepiej bym tego nie ujął.
    I dodam jeszcze, że fft, zgodnie z tym co gaskoin mówi, nie jest prawdziwym widmem sygnału, tylko jest tak jakby widmem tego okresowego rozciągnięcia sygnału w - i +∞. Jeśli N próbek akurat obejmuje pełen okres sygnału wejściowego (marna szansa, chociażby dlatego, że 2 częstotliwości nigdy się dokładnie w czasie nie zgrają) to przecieku nie będzie.

    gaskoin wrote:
    Musiał byś też popróbować różne okna, dla innych okien możesz uzyskać lepsze rezultaty (lub gorsze :) ) jako, że nie znamy źródła sygnału.
    Podpisuję się pod tym. Najlepiej zrób nam ładne analizy dla różnych okien i wrzuć wyniki, będą dla potomności.
  • #46
    gaskoin
    Level 38  
    U mnie na studiach mówili 'wyciek', ale wtedy mało słuchałem na zajęciach :P
    W polskim tłumaczeniu W. Smitha także pojawia się słowo wyciek, ale mniejsza z tym jak to się nazywa. Jak się spojrzy na wykres to widać, że widmo się jakby "wylewa".

    Ostry23 wrote:
    Rozumiem, że masz na myśli okres wynoszący N

    Nie miałem na myśli okresu wynoszącego N. Miałem na myśli transformację Fouriera ogólnie, co w tym szczególnym przypadku sprowadza się do tego co napisałeś.

    Ostry23 wrote:
    Inna rzecz, że w międzyczasie z sygnału ciągłego w czasie i amplitudzie (taki sygnał analizujemy przy pomocy transformaty fouriera) przechodzimy w domenę cyfrową czyli konwertujemy sygnał na sygnał dyskretny w czasie i amplitudzie a do analizy takiego zastosowanie ma dyskretna transformata fouriera, czyli nasze DFT.


    Właśnie charakterystyka, nazwijmy to "filtra", przez który przechodzi sygnał, który w tym filtrze zamieniany jest na postać cyfrową, powoduje, że widmo jest powielone. Można to usunąć potem filtrem rekonstrukcyjnym o odwrotnej charakterystyce, ale mniejsza o to, bo nie o to chodzi w temacie :P

    Dodam że wyciek można także zredukować zwiększając długość transformaty, ale chyba serio ten AVR padnie.
  • #47
    rezontor
    Level 15  
    gaskoin wrote:
    A co z dolnoprzepustowym bo się chyba zgubiłem?

    Górnoprzepustowy filtr (na początku) odcina składową stałą i częstotliwość do kilku Hz. Jest to po prostu prosty filtr RC. Dalej, za kolejnymi stopniami wzmacniacza (przed przetwornikiem) znajduje się dopiero aktywny filtr dolnoprzepustowy.
  • #48
    Ostry23
    Level 18  
    gaskoin wrote:
    U mnie na studiach mówili 'wyciek', ale wtedy mało słuchałem na zajęciach :P
    W polskim tłumaczeniu W. Smitha także pojawia się słowo wyciek, ale mniejsza z tym jak to się nazywa. Jak się spojrzy na wykres to widać, że widmo się jakby "wylewa".

    No właśnie, wiadomo o co chodzi. Dla sinusa dostajemy zamiast cyfrowego odpowiednika prążka rozlane na boki cuś.

    gaskoin wrote:
    Właśnie charakterystyka, nazwijmy to "filtra", przez który przechodzi sygnał, który w tym filtrze zamieniany jest na postać cyfrową, powoduje, że widmo jest powielone.

    No tak, próbkowanie to mnożenie sygnału przez dystrybucję Diraca (w idealnym przypadku, bo w rzeczywistym zamiast dystrybucji mamy po prostu wąziutkie prostokąty) czyli w domenie częstotliwości odpowiada to splotowi widma sygnału z dystrybucją grzebieniową (czyli transformatą dystrybucji) - stąd te powielenia. Ale żeśmy zabrnęli w rozważania :). Mam nadzieję, że to nie zamiesza to za bardzo autorowi wątku.

    gaskoin wrote:
    Można to usunąć potem filtrem rekonstrukcyjnym o odwrotnej charakterystyce, ale mniejsza o to, bo nie o to chodzi w temacie :P

    Jeśli dobrze zrozumiałem piszesz o błędzie apertury wynikającym z nieidealnego próbkowania? Czyli o kompensacji przekłamań widma, które wynikają z tego, że nigdy nie próbkujemy dystrybucją Diraca, tylko wąskimi prostokątami, bo samplowanie sygnału w ADC musi trwać dłużej niż 0.
    No, to teraz dopiero zamieszaliśmy rezontorowi ;)

    Quote:
    Dodam że wyciek można także zredukować zwiększając długość transformaty, ale chyba serio ten AVR padnie.

    No tak. Na zdrowy rozum można to rozumieć tak, że jeśli nasze okno obserwacji obejmie nie np. pól okresu a kilka i trochę, to powielenie w -∞ i +∞ tych kilku i trochę da wciąż sygnał przypominający oryginał. A jeśli powielimy marne pól okresu, to po rozciągnięciu kształt może mocno odbiegać od oryginału.
  • #49
    rezontor
    Level 15  
    Czy można zastąpić zmienne rzeczywiste całkowitymi? Czy nie pogorszy to znacząco dokładności?
  • Helpful post
    #50
    krru
    Level 33  
    W moim przypadku (ten EKG), ponieważ ten TMS miał tylko arytmetykę stałoprzecinkową, stosowana była taka arytmetyka mieszana - FFT było liczone stałoprzecinkowo (dokładnie to zaprzecinkowo - liczby traktowane jako (-1, 1)), natomiast w przypadku wystąpienia przepełnienia (tylko podczas dodawania) wywoływana była prosta funkcja dzielącą każdą liczbę przez 4 (chyba) i zwiększająca licznik. Działało to trochę jak liczby zmiennoprzecinkowe, tylko wykładnik był wspólny. Przy przetwarzaniu prawdziwych sygnałów EKG zwykle przepełnienie występowało 2-3 razy na 512 próbek (dane 12 bitowe, obliczenia 16b).
    Dzięki właściwościom algorytmu FFT (liczenie in-place i dość proste obliczenie elementarne na 2 elementach) można było w dowolnym momencie zrobić takie przeskalowanie.
  • #51
    rezontor
    Level 15  
    Przepisałem kod na uC, jednak ciągle wychodzą jakieś bzdury typu wynik (wartość bezwzględna) jest ujemny... Pewnie dlatego, że przekraczane są pojemności zmiennych - zmienne są typu Long.

    Czy kod jest poprawny, czy coś zmienić. Przejrzałem już wiele razy i nie wiem co nie działa... Myślałem że stos się przepełnia - pozmieniałem wartości związane z stosem jednak bez skutku. Próbowałem wartości z przetwornika zmniejszać, a wynik wyjściowy dzielić - ale nic nie pomaga...
    Poniżej kod:

    Code: basic4gl
    Log in, to see the code
  • Helpful post
    #52
    krru
    Level 33  
    rezontor wrote:

    Code: basic4gl
    Log in, to see the code



    Od razu wspomnę, że nie znam Bascoma, więc mogę nie mieć racji, ale dla mnie wygląda
    podejrzanie wyrównywanie do całkowitej wyniku sin() i cos().
    To raczej nie ma sensu.

    Tak ogólie to sin i cos należy stablicować - tj obliczyć N poszczególnych wartości raz i potem korzystać z gotowych wartości z tablicy. Jak masz stałe N to wręcz można (o ile można w bascomie) zwalić to na kompilator.


    Polecam też następującą kolejność: najpierw najprostszy algorytm FFT na liczbach zmiennoprzecinkowych, potem stablicowanie sin/cos i sprawdzenie jak to się wyrabia z czasem. Dopiero na końcu optymalizacje niskopoziomowe - czyli np. przejście na stały przecinek (co nie oznacza liczb całkowitych).

    Nie wiem, na ile to urządzenie musi być autonomiczne, ale 250 - 500 próbek na sekundę (ile jest kanałów?) można przesłać po RS przy 9600-19200b/s i obrabiać dane na PC w czasie rzeczywistym, tam moc obliczeniowa jest znacznie większa. By uniknąć problemów z bezpieczeństwem można użyć laptopa na zasilaniu bateryjnym.
  • #53
    rezontor
    Level 15  
    krru wrote:
    ale dla mnie wygląda
    podejrzanie wyrównywanie do całkowitej wyniku sin() i cos().

    Tu wzorowałem się na kodzie ze strony http://www.dspguide.com/graphics/T_12_4.gif . Tam wynik także jest zamieniany na wartość całkowitą poleceniem CINT - ogólnie obliczenia są prowadzone z użyciem zmiennych całkowitych.
    krru wrote:
    najpierw najprostszy algorytm FFT na liczbach zmiennoprzecinkowych

    Niestety, ale program operujący na liczbach zmiennoprzecinkowych sypie się (wina Bascoma i jego ograniczeń). Najlepiej więc przeprowadzać obliczenia na l. całkowitych.
  • Helpful post
    #54
    krru
    Level 33  
    rezontor wrote:
    krru wrote:
    ale dla mnie wygląda
    podejrzanie wyrównywanie do całkowitej wyniku sin() i cos().

    Tu wzorowałem się na kodzie ze strony http://www.dspguide.com/graphics/T_12_4.gif . Tam wynik także jest zamieniany na wartość całkowitą poleceniem CINT - ogólnie obliczenia są prowadzone z użyciem zmiennych całkowitych.


    Chyba nie - nie wiem, co to za dialekt Basica, ale chyba zmienne z % na końcu są całkowite.
    Wtedy to co jest na podanym obrazku liczy na zmiennym przecinku. Liczby całkowite w tym kodzie to tylko liczniki pętli i indeksy tablic.
    Na powno wynik sin i cos nie jest konwertowany do wartości całkowitej.

    krru wrote:
    najpierw najprostszy algorytm FFT na liczbach zmiennoprzecinkowych

    Niestety, ale program operujący na liczbach zmiennoprzecinkowych sypie się (wina Bascoma i jego ograniczeń). Najlepiej więc przeprowadzać obliczenia na l. całkowitych.[/quote]

    Ale to nie jest proste - nie można tego liczyć traktując liczby jako całkowite, tylko jako stałoprzecinkowe, czyli ze stałym przesunięciem. Wtedy trzeba wykonywać korekcyjne
    przesunięcie po każdym mnożeniu. Np. jeśli z 16 bitów potraktujemy 15 jako ułamek i najstarszy bit jako znak, to po przemnożeniu mamy 2 bity przed przecinkiem (30 po) i trzeba
    wynik przesunąć w prawo o 1 bit.
  • #55
    rezontor
    Level 15  
    Więc tak.
    Wszystkie zmienne oprócz tablicowych , Tr,Ti, Ur,Ui,Sr,Si i tymczasowych(SINGLE) są zadeklarowane jako Integer.
    Jako że składnia Bascoma i Visual Basic jest podobne, przetestowałem ten kod na komputerze (przetwornik ADC robi pomiary i wysyła wyniki do PC) i okazuje się, że z oknem hamminga działa dużo lepiej od programów, które testowałem na pierwszej stronie tego tematu.
    -----

    Jeżeli robię symulacje owego kodu na komputerze - w symulatorze Bascoma - i wprowadzę pewne dane wyjściowe - np aby kolejne wartości tablicy Rex(x)=x+1 -> otrzymuję na wyjściu pewne liczby w zakresie 1-100 i wszystko przebiega ok.
    Natomiast jak owy kod testuję na procesorze - program drukuje poprawne liczby w zakresie 1-100 w terminalu, jednak po paru sekundach się zawiesza lub pracuje niestabilnie drukując w terminalu NAN (przekroczenie pojemności zmiennej), mimo że w zmiennej wartości nie są duże .

    Jeżeli program na procesorze poddaje FFT kolejne próbki z przetwornika ADC (128próbek), to wszystko jest ok dopóki wejście przetwornika jest zwarte do masy [wartość z przetwornika wynosi 0]. Jeżeli podam nawet bardzo małe napięcie na przetwornik [i wartość w zmiennej Napiecie z przetwornika >0] to program po chwili się zawiesza, a wcześniej na terminalu drukuje wartości NAN wskazujące na przekroczenie pojemności zmiennych lub przypadkowe znaki.
    Zmieniałem wartości odnoszące się do stosu - jednak nic to nie daje. Co może by tego przyczyną? Czyżby za mały stos w procesorze (Mega32)?

    Dodano po 5 [godziny] 40 [minuty]:

    Pomogło usunięcie procedury i włączenie jej kodu do podprogramu co4ms. Na tym etapie rozwiązanie liczone jest < 20ms. Muszę popracować jeszcze nad oknem i rozdzielczością.

    Czy dane wejściowe [wpisywane do tablicy Rex) muszą zawierać się w przedziale 1-128?
  • #56
    rezontor
    Level 15  
    W jakim zakresie mogą zawierać się dane wejściowe, które wpisuję do tablicy Rex do dalszego przetworzenia?