Witam,
Chciałbym napisać filtr cyfrowy na mikrokontrolerze lecz wcześniej chciałbym sam algorytm napisać na PCcie. O ile algorytm znalazłem to nie wiem jak przygotować sobie dane dla takiego programu. Otóż chciałbym miec w pliku np. 256 próbek sygnału np. trójkątnego lub jakiegoś audio ale próbkowanych z częstotliwością np. 30kHz, wartość próbek musi być 8-bitowa (7bitów plus znak). Jest może jakiś soft którym można wygenerować takie próbki?
Chyba najprościej samemu spłodzić jakieś maleństwo w C, sam tak zresztą robię, kiedy muszę wygenerować jakieś tablice.
Nawet jeżeli nie masz zainstalowanego kompilatora dla PC, to możesz to może się tym zająć sam AVR, wypełniając tablicę na początku programu.
Zrób sinusoidę jaka cię interesuje, dodaj do tego następną o wyższej częstotliwości i mniejszej amplitudzie (zakłócenie) i masz gotowy sygnał do filtrowania
Witam,
Przepraszam że długo nie pisałem ale chwilowo mnie wcięło
1. Czyli ok, sinusoidę robię sobie z równania y=sin(2*PI*frg*time), gdzie time wstawiam w zależności co ile chce próbki.
Pytanie do shg (lub kogoś kto sie orientuje):
Chcąc zrobić np. filtr pasmowo przepustowy 2kHz-10kHz dla sygnału audio to z jaką częstotliwością muszę próbkować? 2x pasmo Audio czyli ok. 40kHz? Czy atmega8 da radę, zgodnie z dokumentacją ADC w atmedze działa max 15kHz, ale podobno da się go jakoś "podkręcić".
O ile dobrze rozumiem to próbek do filtów IIR nie muszę gromadzić tak jak w FFT.
Dla filtrów dolno przepustowych np do 1kHz muszę zmniejszyć częstotliwość próbkowania tak żeby zgromadzić cały okres czy nie?
Pytam bo nie mogę sobie poukładać informacji o filtrowaniu.
Częstotliwość próbkowania powinna być co najmniej dwukrotnie większa od szerokości pasma przetwarzanego sygnału.
Z jaka częstotliwością będziesz próbkował, zależy też od tego, co masz na wejściu, dobrze jest sygnał potraktować filtrem anty-aliasingowym.
ADC da się bez problemu kręcić wyżej, rośnie tylko poziom szumów.
Do IIRa trzeba przechowywać próbki, ale zazwyczaj dużo mniej (tyle, ile wynosi rząd mianownika).
Dla IIR nie potrzebujesz bufora, który będzie przechowywał cały okres sygnału.
Cały problem z IIR polega na tym, że wymagają większej dokładności obliczeń i mogą okazać się niestabilne.
shg: Co według Ciebie jako specjalisty w tej dziedzinie (czytałem większość Twoich postów) było by lepsze do sterowania 3 diodami które mają reagować na jakiś poziom RMS sygnału audio w trzech pasmach. Ograniczeniem jest atmega8 (chodzi o wielkość kostki). I czy konieczny jest filtr anty-aliasingowy, a jeśli tak to jak taki filtr sie robi?
Czy do DFT muszę zebrać próbki z całego okresu, chodzi mi o dolny zakres niskich częstotliwości, niestety RAM nie jest zbyt duży?
IIR to ogólnie mówiąc spory problem. Wymaga dużej dokładności obliczeń, najlepiej float, co w czasie rzeczywistym jest na AVR mało realne. Można też przeprowadzać obliczenia stałoprzecinkowe, ale takie filtry powinny być bardzo starannie przetestowane przed użyciem.
Można FIR, bez problemu da się uruchomić na stałym przecinku i mogą okazać się wydajniejsze od IIR, a na pewno prostsze do uruchomienia.
Można też użyć FFT. AVR jest w stanie obrabiać kilkanaście tysięcy próbek w ciągu sekundy (FFT stąd: http://elm-chan.org/works/akilcd/report_e.html ), da się też szybciej, ale najprzód musi mi się chcieć przepisać procedurę z C na asembler.
Przy wszystkich metodach największym problemem są niskie częstotliwości, które w wypadku IIR wymagają ogromnej dokładności, w wypadku FIR dużego rozmiaru jądra przekształcenia, a w wypadku FFT dużego rozmiaru transformaty. Nie ma zatem po co niepotrzebnie podnosić częstotliwości próbkowania. Do efektów wizualnych w zupełności wystarczy, gdy za wysokie tony będzie uważane wszystko powyżej 3-4kHz.
Reakcja na określony poziom wartości skutecznej jest raczej pomysłem złym, do każdego utworu trzeba by dobierać wartości progów indywidualnie. Nawet jeżeli korzysta się z ReplayGain.
Moja sugestia to reakcja na określony próg pochodnej wartości skutecznej.
Filtr antyaliasingowy jest raczej konieczny, chyba że chcesz żeby LEDy odpowiadające niskim częstotliwościom zapalały się przy częstotliwościach wysokich (wyższych od częstotliwości próbkowania).
Robi się go tak, że sygnał analogowy doprowadza się do mikrokontrolera przez filtr dolnoprzepustowy, którego pasmo zaporowe leży poniżej połowy częstotliwości próbkowania. Najprościej zastosować scalony filtr z przełączanymi pojemnościami, ale to raczej droga zabawa, tańsze ale i gorsze (albo lepsze i droższe) są filtry aktywne na wzmacniaczach operacyjnych. Do projektowania takich filtrów jest cała kupa programów.
Do DFT trzeba zebrać cały okres sygnału o częstotliwości takiej jak częstotliwość "najniższego" prążka (nie licząc składowej stałej oczywiście).
Najprościej - odejmujesz wartość poprzedniego pomiaru RMS od aktualnego. Można też z większej ilości punktów liczyć, ale wtedy się to trochę komplikuje.
Chyba zdecyduję się na FFT które zrobiliście z kolega hunterhouse, tylko przepiszę to na C i kompilator GCC.
Jaka jest częstotliwość "najniższego" prążka? Jeśli 6kHz podzielę na 64 prążki to najniższy ma 6kHz/64 = 93,75? Czyli muszę pobrać 128 probek z czestotliwoscią 12kHz i nie muszę dzielić pasma na niskie częstotliwości i wysokie.
Podsumowując:
Przepuszczamy tylko 6kHz z pasma audio przez filtr DP. Czyli próbkowanie ADC muszę mieć 12kHz a to się da zrobić spokojnie na 8-bitach (większej precyzji nie potrzebuję).
Tak przefiltrowany sygnał podaję przez kondensator na dwa rezystory które dodają składową stałą 2,5V.
Teraz robimy DFT, chcąc uzyskać 64 prążki (czyli podział tego pasma 6kHz co 93,75 Hz ), pobieram 128 próbek sygnału z częstotliwością 12kHz. Myślę że odświeżanie około 8 razy na sekundę spokojnie się wyrobi.
Po obliczeniu DFT mam dwie tablice Re[64] i Im[64], obliczam amplitudy wszystkich prążków i na ich podstawie robię to co chcę.
Odświeżanie w C uzyskasz większe niż 8 razy na sekundę, spokojnie powyżej 20.
Z niskimi częstotliwościami - problem, jeżeli chciałbyś robić analizator widma. Najniższa to 93,75Hz, ale niezupełnie, bo ten prążek będzie reagował również na częstotliwości wyższe i niższe. W Twoim wypadku to raczej nie ma znaczenia. Zsumuj (ewentualnie mnożąc przez odpowiednie wagi) pierwsze kilka prążków, powiedzmy do okolic 250Hz i niech ta wartość odpowiada za niskie tony.
Wielkie dzięki, czyli stwierdzam że moje rozumowanie w poście wyżej jest poprawne, gdyż nie zwróciłeś mi uwagi.
Myślę o takim podziale pasma:
< 250Hz
250-2kHz
> 2kHz (czyli 2-6kHz)
Koncepcja oczywiście w porządku.
Wysokie tony może troszkę wyżej, jak pisałem, powyżej 3kHz, zresztą w odtwarzaczu muzyki za pomocą equalizera sobie sprawdź jak mniej więcej będzie ten podział "wyglądał".