Përmbajtje:

EasyFFT: Shndërrim i shpejtë i Furierit (FFT) për Arduino: 6 hapa
EasyFFT: Shndërrim i shpejtë i Furierit (FFT) për Arduino: 6 hapa

Video: EasyFFT: Shndërrim i shpejtë i Furierit (FFT) për Arduino: 6 hapa

Video: EasyFFT: Shndërrim i shpejtë i Furierit (FFT) për Arduino: 6 hapa
Video: QuickFFT: High Speed FFT for Arduino 2024, Shtator
Anonim
Image
Image

Matja e frekuencës nga sinjali i kapur mund të jetë një detyrë e vështirë, veçanërisht në Arduino pasi ka fuqi më të ulët llogaritëse. Ka metoda të disponueshme për të kapur kalimin zero ku frekuenca kapet duke u kontrolluar se sa herë sinjali kalon zero linja brenda kohës së caktuar. Një metodë e tillë mund të mos funksionojë kur sinjali është një kombinim i frekuencave të ndryshme.

Kjo është disi e vështirë të kodohet nëse nuk jeni nga një sfond i tillë. Por duke qenë një kallajxhi ky kod mund të jetë shumë i dobishëm për projekte të ndryshme që lidhen me muzikën, analizën e sinjalit. Motivi i këtij projekti ishte të përgatiste një kod që është i lehtë për t’u zbatuar në Arduino pa hyrë në sfondin e tij.

Ky projekt nuk shpjegon Puna e FFT por shpjegon aplikimin e funksionit FFT. I njëjti proces shpjegohet gjithashtu në videon e bashkangjitur.

Nëse jeni të interesuar vetëm për aplikimin e kodit dhe jo për një shpjegim të tij. Ju mund të kaloni drejtpërdrejt në hapin nr 3.

Hapi 1: Hyrje në transformimin e frekuencës

Hyrje në transformimin e frekuencës
Hyrje në transformimin e frekuencës
Hyrje në transformimin e frekuencës
Hyrje në transformimin e frekuencës

Çdo sinjal mund të përbëhet nga një kombinim i valëve të ndryshme sinusoidale. Pra, çdo sinjal i bazuar në kohë mund të tregohet gjithashtu si një kombinim i sinusit të ndryshëm të amplituda të ndryshme.

Unë u përpoqa të shpjegoj funksionimin e DFT (transformimi diskret Furier) në një nga udhëzimet e mëparshme udhëzuese (https://www.instructables.com/id/Arduino-Frequency…). Këto metoda janë jashtëzakonisht të ngadalta për çdo aplikim në kohë reale. gjë që e bën atë pothuajse të padobishme.

Në imazh, tregohet një sinjal i cili është një kombinim i dy frekuencave f2 dhe f5. Ky sinjal shumëzohet me valët sinus të provës të vlerave f1 deri f5.

Mund të tregohet matematikisht se -përmbledhja e shumëzimit të dy të dhënave harmonike me frekuencë të ndryshme tenton në zero (një numër më i madh i të dhënave mund të çojë në rezultatin e grumbullimit). Në rastin tonë, Nëse këto dy frekuenca të shumëzimit kanë të njëjtën frekuencë (ose shumë të afërt), shuma e shumëzimit është numri jozero.

Pra, nëse sinjali ynë shumëzohet me f1, përmbledhja e shumëzimit do të jetë zero (afër zeros për aplikim real). e ngjashme është rasti për f3, f4. Megjithatë për vlerën, prodhimi f2 dhe f5 nuk do të jetë zero, por dukshëm më i lartë se pjesa tjetër e vlerave.

Këtu një sinjal testohet me 5 frekuenca, kështu që sinjali duhet të shumëzohet me pesë frekuenca. Një llogaritje e tillë intensive kërkon një kohë më të lartë. Matematikisht tregohet se për N numrin e mostrave nevojitet shumëzimi kompleks N*N.

Hapi 2: Transformimi i shpejtë i Furierit

Për të bërë llogaritjen e DFT më të shpejtë algoritmi FFT u zhvillua nga James Cooley dhe John Tukey. Ky algoritëm konsiderohet gjithashtu si një nga algoritmet më të rëndësishëm të shekullit të 20 -të. Ai ndan një sinjal në një pjesë të çuditshme dhe madje të sekuencuar, gjë që i bën një numër llogaritjesh të kërkuara më të ulëta. Duke e përdorur atë, shumëzimi kompleks i kërkuar kompleks mund të reduktohet në NlogN. që është një përmirësim domethënës.

Ju mund t'i referoheni referencave më poshtë të cilave iu referova ndërsa shkruaja kodin për një kuptim të hollësishëm të matematikës pas FFT:

1.

2.

3.

4.

Hapi 3: Shpjegimi i Kodit

1. Sinus i shpejtë dhe kosinus:

Llogaritja FFT merr vlerën e sinusit dhe kosinusit të ndryshëm shumë herë. Funksioni i integruar i Arduino nuk është mjaft i shpejtë dhe kërkon shumë kohë për të siguruar vlerën e kërkuar. Kjo e bën kodin dukshëm më të ngadaltë (dyfishon kohën për 64 mostra). Për të kundërshtuar këtë çështje vlera e sinusit për 0 deri në 90 gradë ruhet si shumëfish i 255. Duke vepruar kështu do të eliminoni nevojën e përdorimit të ruajtjes së numrave si notues dhe ne mund ta ruajmë atë si bajt që merr 1/4 e hapësirës në Arduino. Të dhënat sine duhet të ngjiten në krye të kodit për ta deklaruar atë si një ndryshore globale.

Përveç të dhënave sine, një grup i quajtur f_peaks i deklaruar si një ndryshore globale. Pas çdo ekzekutimi të funksionit FFT, kjo grup azhurnohet. Aty ku f_peaks [0] është frekuenca më dominuese dhe vlerat e mëtejshme në rend zbritës.

byte 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}; noton f_peaks [5];

Meqenëse kemi ruajtur vlerën e sinusit nga 0 në 90 gradë, çdo vlerë e sinusit ose kosinusit mund të llogaritet. Më poshtë funksiononi raundin e parë të numrit në zero dhjetore dhe kthejeni vlerën nga të dhënat e ruajtura. kjo metodë ka nevojë për vetëm një ndarje lundruese. Kjo mund të zvogëlohet më tej duke ruajtur drejtpërdrejt vlerat e sinusit (jo 255 të shumëfishta). por që ha kujtesë të lartë në Arduino.

Përdorimi i procedurës së mësipërme zvogëlon saktësinë, por përmirëson shpejtësinë. Për 64 pikë, jep përparësinë prej 8ms dhe për 128 pikë jep një avantazh prej 20ms.

Hapi 4: Shpjegimi i Kodit: Funksioni FFT

FFT mund të kryhet vetëm për madhësinë e mostrës 2, 4, 8, 16, 32, 64 etj. nëse vlera nuk është 2^n, atëherë do të marrë anën e poshtme të vlerës. Për shembull, nëse zgjedhim madhësinë e mostrës prej 70 atëherë ai do të marrë parasysh vetëm 64 mostrat e para dhe do të lërë pjesën tjetër.

Rekomandohet gjithmonë që të keni një madhësi mostre prej 2^n. e cila mund të jetë:

2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, …

Dy nota jashtë_r dhe jashtë_im do të marrin një sasi të madhe të kujtesës. për Arduino nano nuk do të funksionojë për mostrat më të larta se 128 (dhe në disa raste 128) për shkak të mungesës së kujtesës në dispozicion.

të dhëna int të panënshkruara [13] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};

int a, c1, f, o, x; a = N; për (int i = 0; i <12; i ++) // llogaritjen e niveleve {if (të dhënat <= a) {o = i;}} int in_ps [të dhënat [o] = {}; // hyrja për sekuencimin e notimit out_r [të dhënat [o] = {}; // pjesa reale e transformimit noton out_im [të dhënat [o] = {}; // pjesa imagjinare e transformimit

Rrjedha e mëtejshme është si më poshtë:

1. Kodi gjeneron një rend pak të përmbysur për madhësinë e dhënë të mostrës (detaje mbi përmbysjen e bit në referencat: hapi 2)

2. Të dhënat e dhëna të renditura sipas porosisë së gjeneruar, 3. FFT e kryer

4. Amplituda e numrit kompleks të llogaritur, 5. Majat zbulohen dhe renditen në rend zbritës

6. Rezultatet mund të arrihen nga f_peaks.

[për të hyrë në të dhëna të tjera (përveç frekuencës maksimale) kodi duhet të modifikohet, në mënyrë që variabla lokale të mund të kopjohet në ndonjë ndryshore globale të paracaktuar]

Hapi 5: Testimi i Kodit

Testimi i Kodit
Testimi i Kodit
Testimi i Kodit
Testimi i Kodit

Një valë mostër e trekëndëshit jepet si hyrje. për këtë valë frekuenca e marrjes së mostrave është 10 Hz dhe frekuenca e valës në vetvete është 1.25 Hz.

Siç mund të tregohet nga prodhimi i papërpunuar, vlera përputhet me FFT të llogaritur nga Scilab. megjithatë, këto vlera nuk janë saktësisht të njëjta me saktësinë e ulët, por valën e sinusit më të shpejtë.

Në frekuencën e daljes, frekuenca e grupit është 1.25 dhe 3.75. nuk është e nevojshme të merret vlera e saktë çdo herë. në mënyrë tipike këta numra quhen kazanët e frekuencës. kështu që vlera e prodhimit mund të jetë kudo brenda koshave të specifikuar.

Shpejtësia:

për Arduino nano duhet:

16 Pikë: 4ms32 Pikë: 10ms 64 Pikë: 26ms 128 Pikë: 53ms

Hapi 6: Përfundimi

Ky kod FFT mund të përdoret në aplikime në kohë reale. Pasi duhen rreth 30 ms për të përfunduar llogaritjen. Sidoqoftë, zgjidhja e tij është e kufizuar nga një numër mostrash. Numri i mostrës është i kufizuar nga memoria Arduino. Duke përdorur Arduino Mega ose saktësi tjetër të bordit me performancë më të lartë, mund të përmirësohet.

nëse keni ndonjë pyetje, sugjerim ose korrigjim mos ngurroni të komentoni.

Përditësim (2/5/21)

Përditësimet: // ----------------------------- Funksioni FFT --------------- ------------------------------- // float FFT (int në , int N, frekuenca e notimit)

Lloji i të dhënave të N ndryshoi në Integer (Byte ekzistues) për të mbështetur> 255 madhësinë e mostrës. Nëse madhësia e mostrës është <= 128, duhet të përdoret lloji i të dhënave të bajtit.

Recommended: