Talaan ng mga Nilalaman:

EasyFFT: Mabilis na Fourier Transform (FFT) para sa Arduino: 6 Hakbang
EasyFFT: Mabilis na Fourier Transform (FFT) para sa Arduino: 6 Hakbang

Video: EasyFFT: Mabilis na Fourier Transform (FFT) para sa Arduino: 6 Hakbang

Video: EasyFFT: Mabilis na Fourier Transform (FFT) para sa Arduino: 6 Hakbang
Video: Fourier Transmission with Arduino mega describe the code. 2024, Nobyembre
Anonim
Image
Image

Ang pagsukat ng dalas mula sa nakunan ng signal ay maaaring maging isang mahirap na gawain, lalo na sa Arduino dahil mayroon itong mas mababang computational power. Mayroong mga pamamaraan na magagamit upang makuha ang zero-tawiran kung saan ang dalas ay nakuha sa pamamagitan ng pag-check kung gaano karaming beses ang signal ay tumatawid sa mga zero na linya sa loob ng naibigay na oras. Ang ganitong pamamaraan ay maaaring hindi gumana kapag ang signal ay isang kumbinasyon ng iba't ibang mga frequency.

Ito ay kahit papaano mahirap mag-code kung hindi ka mula sa ganoong background. Ngunit ang pagiging isang tinkerer ng code na ito ay maaaring maging lubhang kapaki-pakinabang para sa iba't ibang mga proyekto na nauugnay sa musika, pagsusuri ng signal. Ang motibo ng proyektong ito ay upang maghanda ng isang code na madaling ipatupad sa Arduino nang hindi nakuha ang background nito.

Ang proyektong ito ay hindi nagpapaliwanag ng Paggawa ng FFT ngunit ipinapaliwanag ang aplikasyon ng pagpapaandar na FFT. Ang parehong proseso ay ipinaliwanag din sa nakalakip na video.

Kung interesado ka lamang sa aplikasyon ng code at hindi sa isang paliwanag dito. Maaari kang direktang laktawan sa hakbang no 3.

Hakbang 1: Panimula sa Pagbabago ng Frequency

Panimula sa Frequency Transform
Panimula sa Frequency Transform
Panimula sa Frequency Transform
Panimula sa Frequency Transform

Ang anumang senyas ay maaaring binubuo ng isang kumbinasyon ng iba't ibang mga sinusoidal na alon. Kaya't ang anumang signal na nakabatay sa oras ay maipakita rin bilang isang kumbinasyon ng iba't ibang sine ng iba't ibang mga amplitude.

Sinubukan kong ipaliwanag ang pagtatrabaho ng DFT (discrete Fourier transform) sa isa sa naunang itinuturo (https://www.instructables.com/id/Arduino-Frequency…). Ang mga pamamaraang ito ay lubos na mabagal para sa anumang real-time na application. na ginagawang halos walang silbi.

Sa imahe, ipinakita ang isang senyas na kung saan ay kombinasyon ng dalawang dalas ng frequency f2 at f5. Ang senyas na ito ay pinarami ng mga pagsubok na sinus alon ng mga halagang f1 hanggang f5.

Maaari itong maipakita sa matematika na -kumpleto ng pagpaparami ng dalawang magkatugma na data-set na mayroong magkakaibang dalas ay may gawi sa zero (mas mataas na bilang ng data ay maaaring humantong sa resulta ng humampas). Sa aming kaso, Kung ang dalas ng pagdaragdag na ito ay may pareho (o napakalapit) na dalas na ang kabuuan ng pagpaparami ay ang nonzero na numero.

Kaya't kung ang aming signal ay pinarami ng f1 buod ng pagpaparami ay magiging zero (malapit sa zero para sa totoong aplikasyon). katulad nito ang kaso para sa f3, f4. Gayunpaman para sa halaga, ang f2 at f5 na output ay hindi magiging zero, ngunit makabuluhang mas mataas kaysa sa natitirang mga halaga.

Dito nasubukan ang isang senyas na may 5 mga frequency, kaya't kailangang palakihin ng signal ang limang mga frequency. Ang nasabing matinding pagkalkula ay tumatagal ng isang mas mataas na oras. Sa matematika ipinapakita na para sa N bilang ng mga sample tumatagal ito ng N * N kumplikadong pagdami.

Hakbang 2: Mabilis na Fourier Transform

Upang makalkula ang DFT na mas mabilis na FFT algorithm ay binuo nina James Cooley at John Tukey. Ang algorithm na ito ay isinasaalang-alang din bilang isa sa pinakamahalagang mga algorithm ng ika-20 siglo. Hinahati nito ang isang senyas sa isang kakaiba at kahit na sunud-sunod na bahagi na ginagawang mas mababa ang isang bilang ng mga kinakailangang kalkulasyon. Sa pamamagitan ng paggamit nito kabuuang kinakailangang kumplikadong pagpaparami ay maaaring mabawasan sa NlogN. na kung saan ay isang makabuluhang pagpapabuti.

Maaari kang mag-refer sa ibaba ng mga sanggunian na tinukoy ko habang sinusulat ang code para sa isang detalyadong pag-unawa sa matematika sa likod ng FFT:

1.

2.

3.

4.

Hakbang 3: Paliwanag ng Code

1. Mabilis na sine at Cosine:

Kinukuha ng pagkalkula FFT ang halaga ng iba't ibang mga sinus at cosine ng maraming beses. Ang nakapaloob na pagpapaandar ng Arduino ay hindi sapat na mabilis at tumatagal ng isang mahusay na halaga ng oras upang maibigay ang kinakailangang halaga. Na ginagawang mas mabagal ang code (pagdodoble ng oras para sa 64 na mga sample). Upang kontrahin ang isyu na ito ng halaga ng sine para sa 0 hanggang 90 degree ay nakaimbak ng maraming 255. Ang paggawa nito ay aalisin ang pangangailangan ng paggamit ng mga bilang ng pag-iimbak bilang float at maiimbak natin ito bilang byte na tumatagal ng 1 / 4th space sa Arduino. Ang sine_data ay kailangang i-paste sa tuktok ng code upang ideklara ito bilang isang pandaigdigang variable.

Bukod sa sine_data, isang array na tinatawag na f_peaks ay idineklara bilang isang global variable. Matapos ang bawat pagpapatakbo ng FFT function na ito ang mga update sa array. Kung saan ang f_peaks [0] ay ang pinaka-nangingibabaw na dalas at karagdagang mga halaga sa pababang pagkakasunud-sunod.

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

Tulad ng naimbak naming halaga ng sine para sa 0 hanggang 90 degree ang anumang halaga ng sine o cosine ay maaaring kalkulahin. Sa ibaba ay gumana ang unang pag-ikot ng numero sa zero decimal point at ibalik ang halaga mula sa nakaimbak na data. ang pamamaraang ito ay nangangailangan lamang ng isang lumulutang na dibisyon. Maaari itong bawasan pa sa pamamagitan ng direktang pag-iimbak ng mga halaga ng sine (hindi 255 na maramihang). ngunit kumakain ng mataas na memorya kay Arduino.

Ang paggamit ng pamamaraang nasa itaas ay binabawasan ang katumpakan ngunit nagpapabuti ng bilis. Para sa 64 na puntos, binibigyan nito ang bentahe ng 8ms at para sa 128 na puntos ay nagbibigay ito ng kalamangan na 20ms.

Hakbang 4: Paliwanag ng Code: FFT Function

Maaari lamang isagawa ang FFT para sa laki ng sample ng 2, 4, 8, 16, 32, 64 at iba pa. kung ang halaga ay hindi 2 ^ n, kaysa sa kukuha ng mas mababang bahagi ng halaga. Halimbawa, kung pipiliin namin ang laki ng sample ng 70 pagkatapos ay isasaalang-alang lamang nito ang unang 64 na sample at alisin ang pahinga.

Palaging inirerekumenda na magkaroon ng isang sample na laki ng 2 ^ n. na maaaring maging:

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

Dalawang float out_r at out_im ay kukuha ng isang mataas na halaga ng memorya. para sa Arduino nano ay hindi gagana para sa mga sample na mas mataas sa 128 (at sa ilang mga kaso 128) dahil sa kakulangan ng magagamit na memorya.

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

int a, c1, f, o, x; a = N; para sa (int i = 0; i <12; i ++) // kinakalkula ang mga antas {kung (data <= a) {o = i;}} int in_ps [data [o] = {}; // input for sequencing float out_r [data [o] = {}; // totoong bahagi ng transform float out_im [data [o] = {}; // imahinasyong bahagi ng pagbabago

Ang karagdagang daloy ay ang sumusunod:

1. Bumubuo ang code ng kaunting baligtad sa pagkakasunud-sunod para sa ibinigay na laki ng sample (mga detalye sa pag-reverse ng bit sa mga sanggunian: hakbang 2)

2. Input ang data ng inorder ayon sa bawat nabuong order, 3. Ganap na FFT

4. Ang amplitude ng kumplikadong bilang na kinakalkula, 5. Ang mga tuktok ay napansin at iniutos sa pababang pagkakasunud-sunod

6. maa-access ang mga resulta mula sa f_peaks.

[upang ma-access ang iba pang data (bukod sa dalas ng rurok) na code ay dapat mabago, upang ang lokal na variable ay maaaring makopya sa ilang paunang natukoy na pandaigdigang variable]

Hakbang 5: Pagsubok sa Code

Pagsubok sa Code
Pagsubok sa Code
Pagsubok sa Code
Pagsubok sa Code

Ang isang sample na alon ng tatsulok ay ibinibigay bilang input. para sa dalas ng sampling ng alon na ito ay 10 Hz at ang dalas ng alon mismo ay 1.25 Hz.

Tulad ng maaaring ipakita mula sa hilaw na output, ang halaga ay tumutugma sa FFT na kinakalkula ng Scilab. gayunpaman, ang mga halagang ito ay hindi eksaktong kapareho namin ng mababang katumpakan ngunit mas mabilis na alon ng sine.

Sa dalas ng output frequency array ay 1.25 at 3.75. hindi kinakailangan upang makuha ang eksaktong halaga sa bawat oras. karaniwang ang mga bilang na ito ay tinatawag na frequency bins. kaya ang halaga ng output ay maaaring kahit saan sa loob ng mga tinukoy na bins.

Bilis:

para sa Arduino nano kinakailangan:

16 Points: 4ms32 Points: 10ms 64 Points: 26ms 128 Points: 53ms

Hakbang 6: Konklusyon

Ang FFT code na ito ay maaaring magamit sa mga real-time na application. Dahil tumatagal ng humigit-kumulang 30 ms upang makumpleto ang pagkalkula. Gayunpaman, ang resolusyon nito ay limitado ng isang bilang ng mga sample. Ang bilang ng sample ay limitado ng memorya ng Arduino. Sa pamamagitan ng paggamit ng Arduino Mega o iba pang mas mataas na kawastuhan ng board ng pagganap ay maaaring mapabuti.

kung mayroon kang anumang mga query, mungkahi, o pagwawasto huwag mag-atubiling magbigay ng puna.

Update (2/5/21)

Mga Update: // ----------------------------- FFT Function ------------- ------------------------------ // float FFT (int in , int N, float Frequency)

Ang uri ng data ng N ay binago sa Integer (umiiral na Byte) upang suportahan ang> 255 laki ng sample. Kung ang sukat ng sample ay <= 128, dapat gamitin ang uri ng data ng byte.

Inirerekumendang: