Talaan ng mga Nilalaman:

QuickFFT: High Speed FFT para sa Arduino: 3 Hakbang
QuickFFT: High Speed FFT para sa Arduino: 3 Hakbang

Video: QuickFFT: High Speed FFT para sa Arduino: 3 Hakbang

Video: QuickFFT: High Speed FFT para sa Arduino: 3 Hakbang
Video: QuickFFT: High Speed FFT for Arduino 2024, Nobyembre
Anonim
QuickFFT: High Speed FFT para sa Arduino
QuickFFT: High Speed FFT para sa Arduino

Ang tipikal na Arduino ay may limitadong RAM at pagproseso ng kuryente, at ang FFT ay isang proseso ng computationally-intensive. Para sa maraming mga application na real-time, ang tanging kinakailangan ay upang makakuha ng dalas na may maximum na amplitude o kinakailangan upang makita ang mga tuktok ng dalas.

Sa isa sa aking itinuturo, naghanda ako ng isang code para sa FFT na mahahanap dito: EasyFFT

Ang code na ito ay nakagawa ng FFT ng hanggang sa 128 mga sample sa Arduino nano. Ang isang mas mataas na bilang ng sample kaysa sa ito ay hindi posible dahil sa limitadong memorya ng Arduino. Medyo binago ko ang pagpapaandar upang mapabuti ang bilis at mabawasan ang pagkonsumo ng memorya. Pinapayagan ng modipikasyong ito ang Arduino na gumanap ng FFT nang limang beses nang mas mabilis at kumonsumo ng halos kalahating memorya. Ang Instructable na ito ay hindi saklaw ang Paggawa ng FFT, ang mga sanggunian para dito ay matatagpuan sa EasyFFT.

Hakbang 1: Nagtatrabaho

Nagtatrabaho
Nagtatrabaho
Nagtatrabaho
Nagtatrabaho
Nagtatrabaho
Nagtatrabaho
Nagtatrabaho
Nagtatrabaho

Ang tipikal na pagpapaandar ng FFT ay binago upang mapabuti ang bilis na may mas mababang kawastuhan. Tulad ng ipinakita sa imahe ang isang senyas ng pagsubok ay kailangang paramihin ng mga sine o cosine waveform. Ang mga halagang ito ay maaaring nasa pagitan ng 0 hanggang 1, kaya't kinakailangan ang paggawa ng lumulutang na pagpaparami. sa Arduino, ang Floating multiplication ay mabagal kumpara sa mga integer na operasyon.

Sa pagpapaandar na ito, ang alon ng sine / cosine ay pinalitan ng isang parisukat na alon. Tulad ng pag-multiply namin ng isang test signal na may square square na maaaring may halagang 0, 1 o -1. Dahil dito, mapapalitan natin ang lumulutang na pagpaparami sa simpleng pagdaragdag o pagbabawas ng integer. Para sa Arduino integer na karagdagan o pagbabawas ay halos 5 beses na mas mabilis. Ginagawa nitong mas mabilis ang paglutas sa paligid ng 5 beses.

Dahil sa pagbabago na ito, ang mga halaga ng dalas ng dalas ay maaaring itago bilang isang integer (na dating nakalutang) at nakakakuha kami ng isa pang kalamangan ng mas mababang pagkonsumo ng memorya. Sa Arduino Nano, ang ubusin ng 2 bytes ng memorya habang ang float ay kumokonsumo ng 4 bytes ng memorya. Dahil sa kalamangan na ito sa bagong code, nagagawa namin ang FFT para sa halos 256 na mga sample (dating 128 na mga sample).

Sa Normal FFT kailangan namin upang maiimbak ang halaga ng sine upang gumawa ng isang solusyon nang mas mabilis. Sa bagong pag-andar, dahil hindi na namin kinakailangan ang mga halaga ng sine / cosine maaari nating alisin ito at makatipid ng ilang memorya.

Pagpapatupad:

Ang pagpapatupad ng pagpapaandar na ito ay tuwid na pasulong. Maaari lamang naming kopyahin ang pagpapaandar sa ens ng code. Ang pagpapaandar na ito ay maaaring maipatupad gamit ang sumusunod na utos:

float f = Q_FFT (data, 256, 100); Sa pagpapaandar Q_FFT,

data: ang term na ito ay isang array na mayroong mga halaga ng signal, ang inirekumendang laki ng sample ay 2, 4, 8, 32, 64, 128, 256, 512,… pasulong. kung ang laki ng sample ay hindi kabilang sa mga halagang ito ay mai-clip sa pinakamalapit na ibabang bahagi ng mga halaga. halimbawa, kung ang laki ng sample ay 75 kaysa sa FFT ay isasagawa para sa 64 na bilang ng mga sample. Ang maximum na bilang ng laki ng sample ay limitado ng magagamit na RAM sa Arduino.

Tinutukoy ng pangalawang term ang bilang ng mga sample sa isang array at ang huling term ay ang dalas ng sampling sa Hz.

Hakbang 2: Code

Ipinapaliwanag ng seksyong ito ang pagbabago na ginawa sa EasyFFT code na kailangang tandaan habang gumagawa ng pagbabago sa code, 1. Tulad ng ipinaliwanag dati, dito ang mga integer ay ginagamit upang gumawa ng FFT. Ang Int sa Arduino ay isang 16-bit na numero at maaaring maglaman ng mga halaga mula -32768 hanggang 32768. tuwing ang halaga ng int na ito ay lumampas sa saklaw na ito sanhi ng problema. upang maalis ang problemang ito pagkatapos ng pagkalkula sa antas. kung ang alinman sa halagang lumagpas sa 15000 kumpletong mga array ay hahatiin ng 100. pipigilan nito ang int na mag-overflow.

2. Pagkalkula ng amplitude: Upang makalkula ang amplitude, ang tunay at haka-haka na bahagi ay kailangang mai-square at kinakailangan ang square root ng kabuuan. ang pag-squaring at ang square root ng pagpapaandar ay tumatagal ng oras. upang gawing mas mabilis ang proseso, gagawin lamang ng code na ito ang ilan sa mga kalakihan ng mga tunay at haka-haka na bahagi. Ito ay tiyak na hindi gaanong tumpak at maaaring humantong sa maling konklusyon sa ilang mga kaso. maaari kang pumili upang bumalik sa Karaniwang pamamaraan para sa pagkalkula ng lakas ngunit tatagal ito ng mas maraming oras at kailangan mo ring gumawa ng ilang pag-aayos upang maiimbak ang mga numerong ito.

3. Ang code na ito ay walang isang module para sa maraming tuktok ng pagtuklas. Pipili lamang nito ang halaga na may max amplitude (hindi kasama ang unang numero na DC offset). Kung kailangan mo ng maraming mga taluktok maaari kang mag-refer sa EasyFFT code at gawin ang kinakailangang pagbabago dito. Sa kasong iyon, ang ilang mga array / variable ay kailangan ding ideklara bilang isang pandaigdigang variable.

4. Naglalaman ang pagpapaandar ng sumusunod na linya:

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

ang pagdedeklara ng mga variable sa itaas bilang isang pandaigdigang variable (i-paste ito sa simula ng code) ay makatipid sa isang lugar ng 1 milliseconds na oras sa bawat pagpapatupad.

5. Hindi tulad ng pag-andar ng EasyFFT, kung saan ang nangungunang 5 mga tuktok ay naimbak sa paunang natukoy na array. Ang pagpapaandar na ito ay magbabalik ng isang halaga ng float. ang halagang ito ay kumakatawan sa dalas na may maximum na amplitude sa Hz. Kaya't ang representasyon ng code ay magmukhang ganito.

float f = Q_FFT (data, 256, 100);

6. Pagtuklas ng Pataas: Kapag nahanap ang dalas na may max amplitude ang pagpapaandar na ito ay gumagamit ng isang amplitude ng dalas bago at pagkatapos nito upang makalkula ang tumpak na mga resulta. Ang amplitude na ginamit sa pagkalkula na ito ay ang kabuuan din ng modulus (hindi ang square root ng kabuuan ng mga parisukat)

kung ang Fn ay ang dalas na may max amplitude pagkatapos ang dalas ay maaaring makalkula mula sa ibaba formula.

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

kung saan ang An ay malawak ng n ang dalas at Fn-1 ay ang halaga ng dalas.

Hakbang 3: Mga Resulta:

Mga Resulta
Mga Resulta
Mga Resulta
Mga Resulta

Ang oras ng paglutas ay ipinapakita sa itaas na paghahambing ng imahe sa EasyFFT. Ang bilis ng ipinakitang ito sa paghahambing.

Para sa sample na data na mayroong 3 sinusoidal waves na may iba't ibang mga frequency ay ipinapakita. Ang resulta mula sa QuickFFT ay inihambing sa output ng Scilab. Tulad ng nakikita natin sa imahe na 3 mga tuktok na may max amplitude ay tumutugma sa output ng Scilab. Gayunpaman, ang output ay binubuo ng maraming ingay, na maaaring nakaliligaw para sa ilang mga application. Kaya pinayuhan na suriin nang maayos ang code bago mag-apply sa iyong aplikasyon.

Inaasahan kong nahanap mo ang code na ito na kapaki-pakinabang para sa iyong proyekto. Sa kaso ng anumang query o mungkahi mangyaring magbigay ng puna.

Inirerekumendang: