Tartalomjegyzék:
- 1. lépés: Bevezetés a frekvenciaátalakításba
- 2. lépés: Gyors Fourier -transzformáció
- 3. lépés: A kód magyarázata
- 4. lépés: A kód magyarázata: FFT függvény
- 5. lépés: A kód tesztelése
- 6. lépés: Következtetés
Videó: EasyFFT: Gyors Fourier -transzformáció (FFT) Arduino számára: 6 lépés
2024 Szerző: John Day | [email protected]. Utoljára módosítva: 2024-01-30 09:39
A rögzített jel frekvenciájának mérése nehéz feladat lehet, különösen az Arduino esetében, mivel alacsonyabb a számítási teljesítménye. Vannak módszerek a nulla-keresztezés rögzítésére, ahol a frekvenciát úgy rögzítik, hogy ellenőrzik, hogy a jel hányszor lépi át a nulla vonalakat az adott időn belül. Ez a módszer nem működik, ha a jel különböző frekvenciák kombinációja.
Ezt valahogy nehéz kódolni, ha nem ilyen hátterű vagy. De barkácsoló lévén ez a kód nagyon hasznos lehet a zenével, a jelméréssel kapcsolatos különféle projekteknél. Ennek a projektnek az volt az indítéka, hogy készítsen egy kódot, amely könnyen megvalósítható az Arduino -n anélkül, hogy a háttérbe kerülne.
Ez a projekt nem az FFT működését magyarázza, hanem az FFT függvény alkalmazását. Ugyanezt a folyamatot a mellékelt videó is ismerteti.
Ha csak a kód alkalmazása érdekli, nem pedig annak magyarázata. Ugorhat közvetlenül a 3. lépésre.
1. lépés: Bevezetés a frekvenciaátalakításba
Bármely jel különböző szinuszos hullámok kombinációjából állhat össze. Tehát minden időalapú jel a különböző amplitúdójú szinuszok kombinációjaként is megjeleníthető.
Megpróbáltam elmagyarázni a DFT (diszkrét Fourier-transzformáció) működését az egyik előző utasításban (https://www.instructables.com/id/Arduino-Frequency…). Ezek a módszerek rendkívül lassúak bármilyen valós idejű alkalmazás esetén. ami szinte használhatatlanná teszi.
A képen egy jel látható, amely két f2 és f5 frekvencia kombinációja. Ezt a jelet megszorozzák az f1 – f5 értékű szinuszhullámokkal.
Matematikailag kimutatható, hogy két különböző frekvenciájú harmonikus adathalmaz szorzatának összeadása nullára hajlik (a nagyobb számú adat tésztaeredményhez vezethet). Esetünkben, ha ennek a két szorzási frekvenciának azonos (vagy nagyon közel) gyakorisága van, akkor a szorzás összege a nullától eltérő szám.
Tehát ha a jelünket megszorozzuk f1 -gyel, akkor a szorzás összegzése nulla lesz (valós alkalmazás esetén nulla közelében). hasonló a helyzet az f3, f4 esetében is. Az érték esetén azonban az f2 és f5 kimenet nem lesz nulla, de jelentősen magasabb, mint a többi érték.
Itt egy jelet 5 frekvenciával tesztelnek, ezért a jelet meg kell szorozni öt frekvenciával. Egy ilyen intenzív számítás hosszabb időt vesz igénybe. Matematikailag kimutatható, hogy N mintaszámhoz N*N komplex szorzás szükséges.
2. lépés: Gyors Fourier -transzformáció
A DFT gyorsabb kiszámítása érdekében James Cooley és John Tukey kifejlesztették az FFT algoritmust. Ezt az algoritmust a 20. század egyik legfontosabb algoritmusának is tekintik. A jel egy páratlan és páros szekvenciájú részre oszlik, ami számos szükséges számítást lecsökkent. Használatával a teljes szükséges komplex szorzás NlogN -re csökkenthető. ami jelentős javulás.
Az FFT mögötti matematika részletes megértéséhez hivatkozhat az alábbi hivatkozásokra, amelyekre a kód írásakor hivatkoztam:
1.
2.
3.
4.
3. lépés: A kód magyarázata
1. Gyors szinusz és koszinusz:
Számítás Az FFT többszörösei a különböző szinuszok és koszinuszok értékét. Az Arduino beépített funkciója nem elég gyors, és jó időbe telik a szükséges érték megadásához. Ez jelentősen lelassítja a kódot (megduplázza az időt 64 mintánál). Ennek a problémának a kiküszöbölésére a szinusz értéke 0 és 90 fok között 255 -ös többszöröseként kerül tárolásra. Ha így tesz, megszűnik a számok tárolásának úszóként való használata, és tárolhatjuk byte -ként, ami 1/4 helyet foglal el az Arduino -n. A sine_data -nak be kell illesztenie a kód tetejére, hogy globális változónak nyilvánítsa.
A sine_data -n kívül az f_peaks nevű tömb globális változóként deklarált. Az FFT funkció minden futtatása után ez a tömb frissül. Ahol az f_csúcsok [0] a domináns gyakoriság és a további értékek csökkenő sorrendben.
bájt sine_data [91] = {0, 4, 9, 13, 18, 22, 27, 31, 35, 40, 44, 49, 53, 57, 62, 66, 70, 75, 79, 83, 87, 91, 96, 100, 104, 108, 112, 116, 120, 124, 127, 131, 135, 139, 143, 146, 150, 153, 157, 160, 164, 167, 171, 174, 177, 180, 183, 186, 189, 192, 195, 198, 201, 204, 206, 209, 211, 214, 216, 219, 221, 223, 225, 227, 229, 231, 233, 235, 236, 238, 240, 241, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 253, 254, 254, 254, 255, 255, 255, 255}; float f_peaks [5];
Mivel a szinusz értékét 0 és 90 fok között tároltuk, a szinusz vagy a koszinusz bármely értéke kiszámítható. Az alábbi funkció a szám első fordulóját tizedesjegyig nullára adja, és visszaadja az értéket a tárolt adatokból. ez a módszer csak egy lebegő felosztást igényel. Ez tovább csökkenthető a szinuszértékek közvetlen tárolásával (nem 255 többszörös). de ez felfalja az Arduino memóriáját.
A fenti eljárás alkalmazása csökkenti a pontosságot, de javítja a sebességet. 64 pontért 8 ms, 128 pontért 20 ms előnyt biztosít.
4. lépés: A kód magyarázata: FFT függvény
Az FFT csak a minta 2, 4, 8, 16, 32, 64 és így tovább végrehajtható. ha az érték nem 2^n, akkor az érték alsó oldalát veszi fel. Például, ha a 70 -es minta méretét választjuk, akkor az csak az első 64 mintát veszi figyelembe, és kihagyja a többi részt.
Mindig ajánlott, hogy a minta mérete 2^n legyen. Melyik lehet:
2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, …
Két float out_r és out_im nagy mennyiségű memóriát vesz igénybe. az Arduino esetében a nano nem fog működni 128 (és egyes esetekben 128) -nál magasabb minták esetén a rendelkezésre álló memória hiánya miatt.
előjel nélküli int adatok [13] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};
int a, c1, f, o, x; a = N; for (int i = 0; i <12; i ++) // a szintek kiszámítása {if (data <= a) {o = i;}} int in_ps [data [o] = {}; // bemenet a szekvenáláshoz float out_r [adatok [o] = {}; // a transzformáció valós része float out_im [adatok [o] = {}; // az átalakítás képzeleti része
A további áramlás a következő:
1. A kód egy kicsit megfordított sorrendet generál az adott minta méretéhez (részletek a bitfordításról a hivatkozásokon: 2. lépés)
2. A generált sorrend szerint megrendelt bemeneti adatok, 3. FFT végrehajtva
4. A számított komplex szám amplitúdója, 5. A csúcsokat csökkenő sorrendben észleli és rendezi
6. az eredmények az f_peaks oldalról érhetők el.
[más adatok eléréséhez (a csúcsfrekvencia kivételével) a kódot módosítani kell, hogy a helyi változó átmásolható legyen valamely előre meghatározott globális változóba]
5. lépés: A kód tesztelése
Bemenetként egy minta háromszög hullámot adunk meg. ehhez a hullám mintavételi frekvenciája 10 Hz, maga a hullám frekvenciája pedig 1,25 Hz.
Amint a nyers kimenetből látható, az érték megegyezik a Scilab által kiszámított FFT -vel. ezek az értékek azonban nem pontosan ugyanazok, mint az alacsony pontosságú, de gyorsabb szinuszhullám.
A kimeneti frekvencia tömb frekvenciája 1,25 és 3,75. nem szükséges minden alkalommal pontos értéket kapni. ezeket a számokat általában frekvenciatartályoknak nevezik. így a kimeneti érték bárhol lehet a megadott tartályokon belül.
Sebesség:
az Arduino nano esetében:
16 pont: 4ms32 pont: 10ms 64 pont: 26ms 128 pont: 53ms
6. lépés: Következtetés
Ez az FFT kód valós idejű alkalmazásokban használható. Mivel a számítás befejezése körülbelül 30 ms -ot vesz igénybe. A felbontását azonban számos minta korlátozza. A minta számát az Arduino memória korlátozza. Az Arduino Mega vagy más nagyobb teljesítményű tábla pontossága javítható.
ha bármilyen kérdése, javaslata vagy javítása van, írjon megjegyzést.
Frissítés (2/5/21)
Frissítések: // ----------------------------- FFT funkció --------------- ------------------------------- // float FFT (int in , int N, float Frequency)
Az N adattípusa Integer (meglévő bájt) értékre változott, hogy támogassa a> 255 mintaméretet. Ha a minta mérete <= 128, akkor bájt adattípust kell használni.
Ajánlott:
Gyors váltó 50 dollár alatt! Kazeshifter Arduino állítható gyorsváltó: 7 lépés
Gyors váltó 50 dollár alatt! Kazeshifter Arduino állítható gyorsváltó: Szia, Superbike vagy motorkerékpár szerelmesei! Ezen az oktatóanyagon megosztom, hogyan lehet olcsón elkészíteni saját gyorsváltóját! Azoknak, akik lusták elolvasni ezt az oktatóanyagot, nézzék meg a videómat! Megjegyzés: Néhány kerékpárhoz már üzemanyag -befecskendező rendszert is használ
QuickFFT: Nagy sebességű FFT az Arduino számára: 3 lépés
QuickFFT: Nagy sebességű FFT az Arduino számára: A tipikus Arduino korlátozott RAM-mal és feldolgozási teljesítménnyel rendelkezik, az FFT pedig számításigényes folyamat. Sok valós idejű alkalmazás esetében az egyetlen követelmény a maximális amplitúdójú vagy frekvenciacsúcsok észleléséhez szükséges frekvencia megszerzése. Az egyik
Gyors laptopállvány, hely a tartozékok számára: 6 lépés
Gyors laptopállvány tartozékokkal: Egy napon azon kaptam magam, hogy két USB -eszközt, valamint az egeret és a billentyűzetet akarok csatlakoztatni a számítógépemhez, csak két USB -porttal. Akkor tudtam, hogy szükségem van USB 2.0 hubra. (Igen, a billentyűzetnek két USB -portja van, de ezek USB 1 -esek, áramtalanok és nagyon szorosak
Gyors, gyors, olcsó, jó megjelenésű LED -es szobavilágítás (bárki számára): 5 lépés (képekkel)
Gyors, gyors, olcsó, jó megjelenésű LED-es szobavilágítás (bárkinek): Üdvözlök mindenkit :-) Ez az első tanulságos, ezért a megjegyzéseket szívesen fogadom :-) Remélem, hogy megmutatom, hogyan lehet gyorsan LED-es világítást készíteni MINDEN apróság. Amire szüksége van: Kábel LED -ek Ellenállások (510 Ohm 12V -ra) Lépcsők Forrasztópáka Vágók és egyéb alapok
Gyors és egyszerű lágy kapcsolók (gyors prototípus készítéshez): 5 lépés
Gyors és egyszerű lágy kapcsolók (gyors prototípus készítéshez): A lágy kapcsolók elkészítésének sokféle módja van. Ez az utasítás egy másik lehetőséget kínál a nagyon gyors prototípushoz a lágy kapcsolóhoz, amely alumínium szalagot használ a vezető szövet helyett, és szilárd huzalokat a vezető szál helyett, ami