Spisu treści:

QuickFFT: szybkie FFT dla Arduino: 3 kroki
QuickFFT: szybkie FFT dla Arduino: 3 kroki

Wideo: QuickFFT: szybkie FFT dla Arduino: 3 kroki

Wideo: QuickFFT: szybkie FFT dla Arduino: 3 kroki
Wideo: Arduino АЧХ arduinoFFT.h разложение звука на частоты 2024, Czerwiec
Anonim
QuickFFT: szybkie FFT dla Arduino
QuickFFT: szybkie FFT dla Arduino

Typowe Arduino ma ograniczoną pamięć RAM i moc obliczeniową, a FFT jest procesem wymagającym dużej mocy obliczeniowej. W przypadku wielu aplikacji czasu rzeczywistego jedynym wymaganiem jest uzyskanie częstotliwości o maksymalnej amplitudzie lub wymagane do wykrycia szczytów częstotliwości.

W jednym z moich instrukcji przygotowałem kod do FFT, który można znaleźć tutaj: EasyFFT

Ten kod był w stanie wykonać FFT do 128 próbek na Arduino nano. Wyższa liczba próbek niż ta nie jest możliwa ze względu na ograniczoną pamięć Arduino. Zmodyfikowałem nieco funkcję, aby poprawić szybkość i zmniejszyć zużycie pamięci. Ta modyfikacja pozwala Arduino na pięciokrotnie szybsze wykonywanie FFT i zużywa prawie połowę pamięci. Ta instrukcja nie obejmuje pracy z FFT, referencje można znaleźć w EasyFFT.

Krok 1: Praca

Pracujący
Pracujący
Pracujący
Pracujący
Pracujący
Pracujący
Pracujący
Pracujący

Typowa funkcja FFT została zmodyfikowana, aby poprawić prędkość z mniejszą dokładnością. Jak pokazano na rysunku, sygnał testowy należy pomnożyć przez przebiegi sinusoidalne lub cosinusoidalne. Wartości te mogą mieścić się w zakresie od 0 do 1, więc wykonanie mnożenia zmiennoprzecinkowego jest koniecznością. w Arduino mnożenie zmiennoprzecinkowe jest powolne w porównaniu do operacji na liczbach całkowitych.

W tej funkcji fala sinusoidalna/kosinusoidalna jest zastępowana falą prostokątną. Ponieważ sygnał testowy musimy przemnożyć falą prostokątną, która może mieć wartość 0, 1 lub -1. Dzięki temu możemy zastąpić mnożenie zmiennoprzecinkowe prostym dodawaniem lub odejmowaniem liczb całkowitych. W przypadku Arduino dodawanie lub odejmowanie liczb całkowitych jest około 5 razy szybsze. To sprawia, że rozwiązywanie jest około 5 razy szybsze.

Dzięki tej modyfikacji teraz wartości bin częstotliwości mogą być przechowywane jako liczba całkowita (która wcześniej była zmiennoprzecinkowa) i otrzymujemy kolejną zaletę w postaci mniejszego zużycia pamięci. W Arduino Nano int zużywa 2 bajty pamięci, podczas gdy float zużywa 4 bajty pamięci. Dzięki tej przewadze w nowym kodzie jesteśmy w stanie wykonać FFT dla prawie 256 próbek (wcześniej 128 próbek).

W normalnym FFT musieliśmy przechowywać wartość sinus, aby przyspieszyć rozwiązanie. W nowej funkcji, ponieważ nie potrzebujemy już wartości sinus/cosinus, możemy ją wyeliminować i zaoszczędzić trochę pamięci.

Realizacja:

Implementacja tej funkcji jest prosta. Możemy po prostu skopiować funkcję na końcu kodu. Funkcję tę można wykonać za pomocą poniższego polecenia:

float f= Q_FFT(dane, 256, 100);W funkcji Q_FFT, dane: termin ten jest tablicą zawierającą wartości sygnałów, zalecana wielkość próbki to 2, 4, 8, 32, 64, 128, 256, 512, … i dalej. jeśli wielkość próbki nie należy do tych wartości, zostanie przycięta do najbliższej dolnej części wartości. na przykład, jeśli wielkość próbki wynosi 75, FFT zostanie przeprowadzone dla 64 numerów próbek. Maksymalna ilość wielkości próbki jest ograniczona dostępną pamięcią RAM w Arduino.

Drugi termin określa liczbę próbek w tablicy, a ostatni termin to częstotliwość próbkowania w Hz.

Krok 2: Kod

Ta sekcja wyjaśnia modyfikacje dokonane w kodzie EasyFFT, o których należy pamiętać podczas dokonywania modyfikacji w kodzie, 1. Jak wyjaśniono wcześniej, tutaj liczby całkowite są używane do wykonywania FFT. Int w Arduino jest liczbą 16-bitową i może zawierać wartości od -32768 do 32768. Gdy wartość tego int przekracza ten zakres, powoduje to problem. aby wyeliminować ten problem po każdym obliczeniu poziomu. jeśli którakolwiek z wartości przekroczy 15000 pełne tablice zostaną podzielone przez 100. Zapobiegnie to przepełnieniu int.

2. Obliczanie amplitudy: Aby obliczyć amplitudę, część rzeczywista i urojona musi zostać podniesiona do kwadratu i wymagany jest pierwiastek kwadratowy z sumy. podniesienie do kwadratu i pierwiastek kwadratowy z funkcji jest czasochłonne. aby przyspieszyć ten proces, ten kod po prostu wykona niektóre wielkości rzeczywistych i urojonych części. Jest to z pewnością mniej dokładne i w niektórych przypadkach może prowadzić do błędnego wniosku. możesz zdecydować się na powrót do metody Normal w celu obliczenia wielkości, ale zajmie to więcej czasu, a także musisz zrobić pewne porządki, aby zapisać te liczby.

3. Ten kod nie zawiera modułu do wykrywania wielu pików. Po prostu wybierze wartość z maksymalną amplitudą (z wyłączeniem pierwszej liczby, która jest przesunięciem DC). Jeśli potrzebujesz wielu pików, możesz odwołać się do kodu EasyFFT i dokonać wymaganej modyfikacji tutaj. W takim przypadku jakaś tablica/zmienna również musi być zadeklarowana jako zmienna globalna.

4. Funkcja zawiera następujący wiersz:

unsigned int Pow2[13]={1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};

zadeklarowanie powyższych zmiennych jako zmiennej globalnej (wklejenie jej na początku kodu) zaoszczędzi gdzieś 1 milisekundę czasu przy każdym wykonaniu.

5. W przeciwieństwie do funkcji EasyFFT, w której 5 górnych pików było przechowywanych w predefiniowanej tablicy. Ta funkcja zwróci wartość zmiennoprzecinkową. ta wartość reprezentuje częstotliwość o maksymalnej amplitudzie w Hz. Więc reprezentacja kodu będzie wyglądać mniej więcej tak.

zmiennoprzecinkowe f= Q_FFT(dane, 256, 100);

6. Wykrywanie szczytów: Po znalezieniu częstotliwości o maksymalnej amplitudzie funkcja ta wykorzystuje amplitudę częstotliwości tuż przed i po niej do obliczenia dokładnych wyników. Amplituda użyta w tym obliczeniu jest również sumą modułu (nie pierwiastka kwadratowego z sumy kwadratów)

jeśli Fn jest częstotliwością o maksymalnej amplitudzie, to częstotliwość można obliczyć z poniższego wzoru.

Rzeczywiste F= (A n-1 *Fn-1 + An-1 *Fn-1 + An-1 *Fn-1) / (An-1+An+An+1)

gdzie An jest amplitudą n częstotliwości, a Fn-1 jest wartością częstotliwości.

Krok 3: Wyniki:

Wyniki
Wyniki
Wyniki
Wyniki

Czas rozwiązywania pokazano na powyższym porównaniu obrazów z EasyFFT. Szybkość tego pokazana w porównaniu.

Dla przykładowych danych przedstawiono 3 fale sinusoidalne o różnych częstotliwościach. Wynik QuickFFT jest porównywany z danymi wyjściowymi Scilab. Jak widać na obrazku 3 piki o maksymalnej amplitudzie są zgodne z wyjściem Scilab. Jednak dane wyjściowe zawierają dużo szumów, które mogą być mylące w przypadku niektórych aplikacji. Dlatego zaleca się prawidłowe sprawdzenie kodu przed złożeniem wniosku.

Mam nadzieję, że ten kod okazał się przydatny w Twoim projekcie. W przypadku jakichkolwiek pytań lub sugestii prosimy o komentarz.

Zalecana: