W materiale znajdziecie wprowadzenie do transformacji Fouriera z teorią ograniczoną do minimum. Jest to propozycja zapoznania się z tematem poprzez praktyczne eksperymenty, następnie intuicyjne wyczucie do czego może przydać się FFT. Jeżeli odstrasza Cię skomplikowana matematyka ten materiał może być pomocny. Jeżeli matematyka to twój żywioł, pamiętaj że celowo pominę i uproszę bardzo wiele rzeczy wychodząc z założenia, że od czegoś trzeba zacząć a później we własnym zakresie można szukać dalej. Do eksperymentów wykorzystamy środowisko Arduino, ESP32 oraz monochromatyczny wyświetlacza LCD 128x64px wyposażony w magistralę SPI. Moduł ESP32 dostępny był w gadżetach elektroda.pl, informacje jak skonfigurować środowisko Arduino do pracy z ESP32 znajdziecie tutaj: konfiguracja modułu Wi-Fi i Bluetooth ESP32 w Arduino.
W materiale znajdziecie zdjęcia i filmy prezentujące uzyskane efekty, dostępny jest też kod wykorzystanego programu co ułatwi własne próby praktyczne.
Transformacja Fouriera pozwala na przejście z dziedziny czasu (w praktyce np. bufor z próbkami z ADC - przetwornika analogowo-cyfrowego, pobieranymi z określoną częstotliwością) do dziedziny częstotliwości, czyli w praktyce posiadamy informację o amplitudach (lub jak wolisz mocach) na kolejnych pasmach częstotliwości. Dziedzinę czasu znasz dobrze np. z ekranu oscyloskopu, czyli kolejne wartości próbek sygnału w czasie. Reprezentację częstotliwościową sygnału możesz porównać do kręcenia gałką w odbiorniku radiowym i sprawdzaniu poziomu sygnału na poszczególnych częstotliwościach. Możesz spotkać się z implementacją dyskretnej transformacji Fouriera jako DFT (discrete Fourier transform) której implementacja jest dość prosta (pętla for wewnątrz drugiej pętli for operująca na danych wejściowych z bufora próbek) jednak złożoność obliczeniowa DFT to O(N?) czyli wraz ze zwiększającą się ilością danych wejściowych (długością bufora) szybko rośnie ilość potrzebnych operacji (czyli czas wykonania transformacji). FFT (fast Fourier transform) posiada bardziej skomplikowaną implementację ale jej złożoność obliczeniowa jest mniejsza O(N*log2(N)) co pozwala na szybsze wykonanie przekształcenia dzięki mniejszej liczbie potrzebnych do wykonania operacji. Ilość danych wejściowych dla FFT to potęga 2 (np. 8,16,32,64,128 itd.).
Aby dodać bibliotekę FFT do środowiska Arduino wybieramy:
Skic->dołącz bibliotekę->zarządzaj bibliotekami
wyszukujemy "fft" i wybieramy arduinoFFT.
Sygnałem wejściowym dla transformacji będą próbki z przetwornika ADC 12b w ESP32. Próbki będziemy pobierali z częstotliwością 40kHz i trafią one do bufora o długości 128 próbek. Próbkowanie z częstotliwością 40kHz pozwoli na analizę sygnałów wejściowych o częstotliwości do 20kHz (częstotliwość Nyquista). Czyli górna granica częstotliwości sygnału który będziemy mogli analizować wynosi połowę częstotliwości próbkowania. Napięcie które możemy podać na ADC mieści się w przedziale 0-3.3V, na etapie testów sygnał podamy poprzez rezystor 10kom. Pobieranie kolejnych próbek z ADC będziemy wyzwalali timerem. Gdy uzbieramy 128 próbek uruchomimy FFT i wyświetlimy dane na wyświetlaczu. Dane w buforze próbek przed wykonaniem FFT modyfikowane są przez funkcję okna czasowego (np. okno Hanninga, Hamminga itp.) zmniejsza to przeciek widmowy a w praktyce polepsza to jakość danych jakie uzyskamy. Operację mnożenia sygnału przez okno czasowe można porównać do np. łagodnego "podgłaśniania" amplitudy na początku utworu i "wyciszania" na jego końcu.
Wynikiem FFT będą dwa bufory danych, w każdym z buforów długość użytecznych dla nas danych będzie dwukrotnie mniejsza niż długość bufora wejściowego z próbkami z ADC. Kolejne pary danych z buforów będą częściami rzeczywistymi i urojonymi liczb zespolonych. Graficznie wynik przekształcenia można przedstawić tak:
W zerowym elemencie tablic wyjściowych znajdują się informacje o składowej stałej sygnału, w kolejnych elementach tablicy liczby zespolone (szare strzałki pokazują pary Re, Im). Liczby zespolone opisują kolejne pasma częstotliwości badanego sygnału rzeczywistego. Górna częstotliwość badanego sygnału w przykładzie wynosi 20kHz, mamy 64 liczby zespolone, czyli szerokość każdego z pasm wynosi 312.5Hz. Mamy 64 punkty określające sygnał w dziedzinie częstotliwości, pierwszy element odnosi się do częstotliwości 312.5Hz, kolejny 625Hz itd.
Warto w tym miejscu przypomnieć, że:
-częstotliwość próbkowania Fs wyznacza maksymalną częstotliwość (Fs/2) jaką możemy analizować w sygnale wejściowym
-długość bufora N wpływa na ilość punktów FFT (N/2) co określa rozdzielczość z jaką badamy sygnał w dziedzinie częstotliwości
-długość bufora wpływa na ilość potrzebnych do wykonania operacji, czyli czas wykonania FFT.
Liczby zespolone przedstawimy graficznie, odkładając składową rzeczywistą na osi X, a składową urojoną na osi Y. Przykładowa liczba zespolona z=3+4i będzie wyglądać tak:
Moduł z liczby zespolonej (długość strzałki) niesie informację o mocy (amplitudzie) na danej częstotliwości analizowanego sygnału. Moduł przykładowej liczby "z" można obliczyć z tw. Pitagorasa (pierwiastek z sumy kwadratów przyprostokątnych) i otrzymamy |z|=5 (długość przeciwprostokątnej). Kąt między "strzałką" a osią X informuje o fazie sygnału i można go obliczyć arctg(Im/Re). W taki sposób przeszliśmy z dziedziny czasu do dziedziny częstotliwości.
Wyświetlacz LCD obsłużymy poprzez dołączenie do środowiska Arduino biblioteki U8g2:
Skic->dołącz bibliotekę->zarządzaj bibliotekami
wyszukujemy ST7565 i wybieramy U8g2.
Wykorzystany monochromatyczny wyświetlacz graficzny LCD COG 128x64px oparty jest o sterownik ST7565 i komunikuje się z wykorzystaniem magistrali SPI. Niestety zastosowana wersja LCD-AG-C128064CF 128*64 ST7565R wymaga podłączenia zewnętrznych kondensatorów 1uF, ale dostępne są moduły z kondensatorami i wyprowadzeniami SPI na płytce. Z biblioteką U8g2 nie musimy ograniczać się do jednego rodzaju sterownika czy interfejsu, zmieniając ustawiania inicjalizacji wyświetlacza łatwo dostosujemy kod programu do innego typu wyświetlacza https://github.com/olikraus/u8g2/wiki/u8g2setupcpp . Dla posiadanego LCD konfiguracja wygląda tak:
U8G2_ST7565_NHD_C12864_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 5, /* dc=*/ 4, /* reset=*/ 16);
Poniżej schemat wyprowadzeń wyświetlacza i sposób podłączenia kondensatorów:
Podłączenie do ESP32 możemy wykonać na płytce stykowej.
Badany sygnał wejściowy podajemy na G34 (wejście ADC) pamiętając o dopuszczalnym zakresie napięć 0-3.3V
Napięcie zasilania dla LCD pobieramy z wyprowadzenia 3.3V podobnie jak masę GND.
Przycisk boot (G0) będzie przełączał funkcje programu (dziedzina czasu, FFT moce, FFT faza).
SPI wyprowadzone jest na G18 (CLK), G23 (DATA), G5 (CS).
Dodatkowo linie sterujące LCD G16 (RST) oraz G4 (D/C).
Całość po podłączeniu na płytkach stykowych wygląda tak:
Biblioteka nie do końca dobrze współpracuje z wybranym wyświetlaczem i wyświetlany obraz jest przesunięty w prawo (widoczne losowe kropki w pionowym pasku wyświetlacza po lewej). Zaletą wyświetlacza jest jego duży rozmiar co poprawia czytelność. Jeżeli wiesz jak wyeliminować opisany efekt, napisz proszę w tym temacie.
(Problem przesunięcia rozwiązany dzięki podpowiedzi piotr_go szczegóły poniżej.)
Dziedzina czasu jest dobrze znana każdemu kto korzystał z oscyloskopu. Na początek sprawdźmy czy pobieranie próbek działa prawidłowo oraz czy uda się wyświetlić zawartość bufora w postaci graficznej na LCD. Tak wygląda efekt działania programu w trybie dziedziny czasu na zdjęciu oraz filmie:
Dla prostych przebiegów okresowych można oszacować "na oko" częstotliwość, fazę i amplitudę, dla bardziej złożonych sygnałów byłoby to trudne. Na wejście układu zostały podane sygnały z dwóch generatorów, oba sygnały zostały podane przez osobne rezystory 10kom na wejściu ADC mamy sumę sygnałów z obu generatorów, pofalowana sinusoida do efekt podania dwóch sygnałów sinusoidalnych o różnych częstotliwościach.
Dziedzina częstotliwości to funkcja wyświetlania gdzie wykorzystamy wyniki działania FFT. Na zdjęciu poniżej widać "prążki" na częstotliwościach odpowiadających częstotliwościom sygnałów podawanych na wejście ADC. Na filmie zobaczycie zmniejszanie częstotliwości sygnału na wyjściu jednego z generatorów, następnie zmniejszanie amplitudy sygnału na wyjściu drugiego generatora. W prawym dolnym rogu widoczny podgląd na ekran oscyloskopu (dziedzina czasu).
Faza sygnału na określonej częstotliwości jest możliwa do obliczenia podobnie jak amplituda zgodnie z opisem w części o liczbach zespolonych. Znacznie bardziej popularne jest określanie amplitudy (mocy) sygnału na określonej częstotliwości. Spróbujmy narysować wykres fazowy w zależności od częstotliwości. Trzeba pamiętać o tym że sygnał wejściowy nie jest zsynchronizowany z próbkowaniem (płyniecie sinusoidy w trybie prezentacji w dziedzinie czasu). Podobnie na wykresie fazowym wartość fazy będzie się stopniowo zmieniać w miarę jak sinusoida będzie "płynąć" i będzie zmieniać się faza początkowa. Druga sprawa to skończona dokładność reprezentacji liczb w systemie komputerowym oraz fakt, że arctg będzie obliczany ze stosunku dwóch liczb (często prezentujących szum). Liczby zespolone o małej wartości modułu (szum, pomijalne dane) mogą generować informacje o fazie podobne do liczb o dużej wartości modułu (częstotliwości gdzie moce sygnału są większe i dane są istotne). W przeciwieństwie do wartości modułu z liczby zespolonej, przesunięcia fazowe nie pokażą nam gdzie występuje sygnał o większej amplitudzie, dlatego wykres fazowy może przypominać szum. Wprowadźmy obliczanie fazy tylko w punktach gdzie moduł z liczby zespolonej będzie przekraczał określoną wartość progową (np. 1/100 wartości maksymalnej). Poniżej zdjęcie i film prezentujących wykres fazowy wykorzystujący takie "maskowanie" w zależności od wartości modułu liczby zespolonej, na filmie zauważycie ciągłą zmianę wartości fazy, oraz nagranie "płynięcia" sinusa w trybie dziedziny czasu.
Podłączenie innego wyświetlacza z wykorzystaniem U8g2 ogranicza się do zmiany jednej linijki w programie, oraz podłączeniu wyświetlacza pod odpowiednie wyprowadzenia SPI. Wypróbujmy wyświetlacz OLED ze sterownikiem SSD1306, który został wykorzystany podczas testów cyfrowego czujnika indeksu UV SI1132.
Zmieniamy linijkę:
U8G2_ST7565_NHD_C12864_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 5, /* dc=*/ 4, /* reset=*/ 16);
na:
U8G2_SSD1306_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, 5, 4, 16);
Oraz usuwamy linijkę: u8g2.setContrast(255);
Podłączamy wyświetlacz pod odpowiednie wyprowadzenia modułu ESP32:
Program wyświetla dane na nowym wyświetlaczu OLED:
Na wejście układu łatwo możemy podać sygnał z mikrofonu elektrytowego:
Do FFT istnieje "odwrotny" algorytm IFFT, który pozwala na przejście z dziedziny częstotliwości do dziedziny czasu.
Poniżej do pobrania kod programu pod Ardino dla ESP32, pamiętajcie o dołączeniu biblioteki arduinoFFT i U8g2 oraz dostosowaniu środowiska Arduino do obsługi ESP32. Kod programu można wykorzystać na płytce innej niż ESP32 po zmianach m.in wyzwalania pobierania próbek oraz konfiguracji ADC.
Testy przeprowadzone w środowisku Arduino 1.8.3.
Jaki masz pomysł na wykorzystanie FFT, czy udało się wykonać próby praktyczne, a może masz duże doświadczenie w cyfrowym przetwarzaniu sygnałów i chcesz poruszyć tematy związane z DSP?
W materiale znajdziecie zdjęcia i filmy prezentujące uzyskane efekty, dostępny jest też kod wykorzystanego programu co ułatwi własne próby praktyczne.
Transformacja Fouriera pozwala na przejście z dziedziny czasu (w praktyce np. bufor z próbkami z ADC - przetwornika analogowo-cyfrowego, pobieranymi z określoną częstotliwością) do dziedziny częstotliwości, czyli w praktyce posiadamy informację o amplitudach (lub jak wolisz mocach) na kolejnych pasmach częstotliwości. Dziedzinę czasu znasz dobrze np. z ekranu oscyloskopu, czyli kolejne wartości próbek sygnału w czasie. Reprezentację częstotliwościową sygnału możesz porównać do kręcenia gałką w odbiorniku radiowym i sprawdzaniu poziomu sygnału na poszczególnych częstotliwościach. Możesz spotkać się z implementacją dyskretnej transformacji Fouriera jako DFT (discrete Fourier transform) której implementacja jest dość prosta (pętla for wewnątrz drugiej pętli for operująca na danych wejściowych z bufora próbek) jednak złożoność obliczeniowa DFT to O(N?) czyli wraz ze zwiększającą się ilością danych wejściowych (długością bufora) szybko rośnie ilość potrzebnych operacji (czyli czas wykonania transformacji). FFT (fast Fourier transform) posiada bardziej skomplikowaną implementację ale jej złożoność obliczeniowa jest mniejsza O(N*log2(N)) co pozwala na szybsze wykonanie przekształcenia dzięki mniejszej liczbie potrzebnych do wykonania operacji. Ilość danych wejściowych dla FFT to potęga 2 (np. 8,16,32,64,128 itd.).
Aby dodać bibliotekę FFT do środowiska Arduino wybieramy:
Skic->dołącz bibliotekę->zarządzaj bibliotekami
wyszukujemy "fft" i wybieramy arduinoFFT.
Sygnałem wejściowym dla transformacji będą próbki z przetwornika ADC 12b w ESP32. Próbki będziemy pobierali z częstotliwością 40kHz i trafią one do bufora o długości 128 próbek. Próbkowanie z częstotliwością 40kHz pozwoli na analizę sygnałów wejściowych o częstotliwości do 20kHz (częstotliwość Nyquista). Czyli górna granica częstotliwości sygnału który będziemy mogli analizować wynosi połowę częstotliwości próbkowania. Napięcie które możemy podać na ADC mieści się w przedziale 0-3.3V, na etapie testów sygnał podamy poprzez rezystor 10kom. Pobieranie kolejnych próbek z ADC będziemy wyzwalali timerem. Gdy uzbieramy 128 próbek uruchomimy FFT i wyświetlimy dane na wyświetlaczu. Dane w buforze próbek przed wykonaniem FFT modyfikowane są przez funkcję okna czasowego (np. okno Hanninga, Hamminga itp.) zmniejsza to przeciek widmowy a w praktyce polepsza to jakość danych jakie uzyskamy. Operację mnożenia sygnału przez okno czasowe można porównać do np. łagodnego "podgłaśniania" amplitudy na początku utworu i "wyciszania" na jego końcu.
Wynikiem FFT będą dwa bufory danych, w każdym z buforów długość użytecznych dla nas danych będzie dwukrotnie mniejsza niż długość bufora wejściowego z próbkami z ADC. Kolejne pary danych z buforów będą częściami rzeczywistymi i urojonymi liczb zespolonych. Graficznie wynik przekształcenia można przedstawić tak:

W zerowym elemencie tablic wyjściowych znajdują się informacje o składowej stałej sygnału, w kolejnych elementach tablicy liczby zespolone (szare strzałki pokazują pary Re, Im). Liczby zespolone opisują kolejne pasma częstotliwości badanego sygnału rzeczywistego. Górna częstotliwość badanego sygnału w przykładzie wynosi 20kHz, mamy 64 liczby zespolone, czyli szerokość każdego z pasm wynosi 312.5Hz. Mamy 64 punkty określające sygnał w dziedzinie częstotliwości, pierwszy element odnosi się do częstotliwości 312.5Hz, kolejny 625Hz itd.
Warto w tym miejscu przypomnieć, że:
-częstotliwość próbkowania Fs wyznacza maksymalną częstotliwość (Fs/2) jaką możemy analizować w sygnale wejściowym
-długość bufora N wpływa na ilość punktów FFT (N/2) co określa rozdzielczość z jaką badamy sygnał w dziedzinie częstotliwości
-długość bufora wpływa na ilość potrzebnych do wykonania operacji, czyli czas wykonania FFT.
Liczby zespolone przedstawimy graficznie, odkładając składową rzeczywistą na osi X, a składową urojoną na osi Y. Przykładowa liczba zespolona z=3+4i będzie wyglądać tak:

Moduł z liczby zespolonej (długość strzałki) niesie informację o mocy (amplitudzie) na danej częstotliwości analizowanego sygnału. Moduł przykładowej liczby "z" można obliczyć z tw. Pitagorasa (pierwiastek z sumy kwadratów przyprostokątnych) i otrzymamy |z|=5 (długość przeciwprostokątnej). Kąt między "strzałką" a osią X informuje o fazie sygnału i można go obliczyć arctg(Im/Re). W taki sposób przeszliśmy z dziedziny czasu do dziedziny częstotliwości.
Wyświetlacz LCD obsłużymy poprzez dołączenie do środowiska Arduino biblioteki U8g2:
Skic->dołącz bibliotekę->zarządzaj bibliotekami
wyszukujemy ST7565 i wybieramy U8g2.
Wykorzystany monochromatyczny wyświetlacz graficzny LCD COG 128x64px oparty jest o sterownik ST7565 i komunikuje się z wykorzystaniem magistrali SPI. Niestety zastosowana wersja LCD-AG-C128064CF 128*64 ST7565R wymaga podłączenia zewnętrznych kondensatorów 1uF, ale dostępne są moduły z kondensatorami i wyprowadzeniami SPI na płytce. Z biblioteką U8g2 nie musimy ograniczać się do jednego rodzaju sterownika czy interfejsu, zmieniając ustawiania inicjalizacji wyświetlacza łatwo dostosujemy kod programu do innego typu wyświetlacza https://github.com/olikraus/u8g2/wiki/u8g2setupcpp . Dla posiadanego LCD konfiguracja wygląda tak:
U8G2_ST7565_NHD_C12864_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 5, /* dc=*/ 4, /* reset=*/ 16);
Poniżej schemat wyprowadzeń wyświetlacza i sposób podłączenia kondensatorów:

Podłączenie do ESP32 możemy wykonać na płytce stykowej.
Badany sygnał wejściowy podajemy na G34 (wejście ADC) pamiętając o dopuszczalnym zakresie napięć 0-3.3V
Napięcie zasilania dla LCD pobieramy z wyprowadzenia 3.3V podobnie jak masę GND.
Przycisk boot (G0) będzie przełączał funkcje programu (dziedzina czasu, FFT moce, FFT faza).
SPI wyprowadzone jest na G18 (CLK), G23 (DATA), G5 (CS).
Dodatkowo linie sterujące LCD G16 (RST) oraz G4 (D/C).

Całość po podłączeniu na płytkach stykowych wygląda tak:

Biblioteka nie do końca dobrze współpracuje z wybranym wyświetlaczem i wyświetlany obraz jest przesunięty w prawo (widoczne losowe kropki w pionowym pasku wyświetlacza po lewej). Zaletą wyświetlacza jest jego duży rozmiar co poprawia czytelność. Jeżeli wiesz jak wyeliminować opisany efekt, napisz proszę w tym temacie.
(Problem przesunięcia rozwiązany dzięki podpowiedzi piotr_go szczegóły poniżej.)
Dziedzina czasu jest dobrze znana każdemu kto korzystał z oscyloskopu. Na początek sprawdźmy czy pobieranie próbek działa prawidłowo oraz czy uda się wyświetlić zawartość bufora w postaci graficznej na LCD. Tak wygląda efekt działania programu w trybie dziedziny czasu na zdjęciu oraz filmie:


Dla prostych przebiegów okresowych można oszacować "na oko" częstotliwość, fazę i amplitudę, dla bardziej złożonych sygnałów byłoby to trudne. Na wejście układu zostały podane sygnały z dwóch generatorów, oba sygnały zostały podane przez osobne rezystory 10kom na wejściu ADC mamy sumę sygnałów z obu generatorów, pofalowana sinusoida do efekt podania dwóch sygnałów sinusoidalnych o różnych częstotliwościach.
Dziedzina częstotliwości to funkcja wyświetlania gdzie wykorzystamy wyniki działania FFT. Na zdjęciu poniżej widać "prążki" na częstotliwościach odpowiadających częstotliwościom sygnałów podawanych na wejście ADC. Na filmie zobaczycie zmniejszanie częstotliwości sygnału na wyjściu jednego z generatorów, następnie zmniejszanie amplitudy sygnału na wyjściu drugiego generatora. W prawym dolnym rogu widoczny podgląd na ekran oscyloskopu (dziedzina czasu).

Faza sygnału na określonej częstotliwości jest możliwa do obliczenia podobnie jak amplituda zgodnie z opisem w części o liczbach zespolonych. Znacznie bardziej popularne jest określanie amplitudy (mocy) sygnału na określonej częstotliwości. Spróbujmy narysować wykres fazowy w zależności od częstotliwości. Trzeba pamiętać o tym że sygnał wejściowy nie jest zsynchronizowany z próbkowaniem (płyniecie sinusoidy w trybie prezentacji w dziedzinie czasu). Podobnie na wykresie fazowym wartość fazy będzie się stopniowo zmieniać w miarę jak sinusoida będzie "płynąć" i będzie zmieniać się faza początkowa. Druga sprawa to skończona dokładność reprezentacji liczb w systemie komputerowym oraz fakt, że arctg będzie obliczany ze stosunku dwóch liczb (często prezentujących szum). Liczby zespolone o małej wartości modułu (szum, pomijalne dane) mogą generować informacje o fazie podobne do liczb o dużej wartości modułu (częstotliwości gdzie moce sygnału są większe i dane są istotne). W przeciwieństwie do wartości modułu z liczby zespolonej, przesunięcia fazowe nie pokażą nam gdzie występuje sygnał o większej amplitudzie, dlatego wykres fazowy może przypominać szum. Wprowadźmy obliczanie fazy tylko w punktach gdzie moduł z liczby zespolonej będzie przekraczał określoną wartość progową (np. 1/100 wartości maksymalnej). Poniżej zdjęcie i film prezentujących wykres fazowy wykorzystujący takie "maskowanie" w zależności od wartości modułu liczby zespolonej, na filmie zauważycie ciągłą zmianę wartości fazy, oraz nagranie "płynięcia" sinusa w trybie dziedziny czasu.

Podłączenie innego wyświetlacza z wykorzystaniem U8g2 ogranicza się do zmiany jednej linijki w programie, oraz podłączeniu wyświetlacza pod odpowiednie wyprowadzenia SPI. Wypróbujmy wyświetlacz OLED ze sterownikiem SSD1306, który został wykorzystany podczas testów cyfrowego czujnika indeksu UV SI1132.
Zmieniamy linijkę:
U8G2_ST7565_NHD_C12864_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 5, /* dc=*/ 4, /* reset=*/ 16);
na:
U8G2_SSD1306_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, 5, 4, 16);
Oraz usuwamy linijkę: u8g2.setContrast(255);
Podłączamy wyświetlacz pod odpowiednie wyprowadzenia modułu ESP32:

Program wyświetla dane na nowym wyświetlaczu OLED:


Na wejście układu łatwo możemy podać sygnał z mikrofonu elektrytowego:

Do FFT istnieje "odwrotny" algorytm IFFT, który pozwala na przejście z dziedziny częstotliwości do dziedziny czasu.
Poniżej do pobrania kod programu pod Ardino dla ESP32, pamiętajcie o dołączeniu biblioteki arduinoFFT i U8g2 oraz dostosowaniu środowiska Arduino do obsługi ESP32. Kod programu można wykorzystać na płytce innej niż ESP32 po zmianach m.in wyzwalania pobierania próbek oraz konfiguracji ADC.
Testy przeprowadzone w środowisku Arduino 1.8.3.
Jaki masz pomysł na wykorzystanie FFT, czy udało się wykonać próby praktyczne, a może masz duże doświadczenie w cyfrowym przetwarzaniu sygnałów i chcesz poruszyć tematy związane z DSP?
Cool? Ranking DIY