Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Manufacturing Technology >> Proses manufaktur

EasyFFT:Fast Fourier Transform (FFT) untuk Arduino

Komponen dan persediaan

Arduino Nano R3
× 1

Aplikasi dan layanan online

Arduino IDE

Tentang proyek ini

Pengukuran frekuensi dari sinyal yang ditangkap bisa menjadi tugas yang sulit, terutama pada Arduino karena memiliki daya komputasi yang lebih rendah. Ada metode yang tersedia untuk menangkap zero-crossing di mana frekuensi ditangkap dengan memeriksa berapa kali sinyal melintasi garis nol dalam waktu tertentu. Metode seperti itu mungkin tidak berfungsi jika sinyalnya merupakan kombinasi dari berbagai frekuensi.

Ini entah bagaimana sulit untuk dikodekan jika Anda bukan dari latar belakang seperti itu. Tapi menjadi seorang pengotak kode ini mungkin sangat berguna untuk berbagai proyek yang berhubungan dengan musik, analisis sinyal. Motif dari proyek ini adalah untuk menyiapkan kode yang mudah diimplementasikan di Arduino tanpa harus mengetahui latar belakangnya.

Proyek ini tidak menjelaskan cara kerja FFT tetapi menjelaskan penerapan fungsi FFT. Proses yang sama juga dijelaskan dalam video terlampir.

Jika Anda hanya tertarik pada penerapan kode dan tidak pada penjelasannya. Anda dapat langsung melompat ke langkah no 3.

Jika Anda perlu melakukan FFT dengan kecepatan tinggi (3x) dengan sedikit kompromi dalam akurasi (sekitar 5%) lihat artikel saya yang lain di ApproxFFT.

https://create.arduino.cc/projecthub/abhilashpatel121/approxfft-fastest-fft-function-for-arduino-fd4917?ref=user&ref_id=1593632&offset=0

Langkah 1:Transformasi Fourier Cepat

Untuk mempercepat komputasi DFT, algoritma FFT dikembangkan oleh James Cooley dan John Tukey. Algoritma ini juga dianggap sebagai salah satu algoritma terpenting abad ke-20. Ini membagi sinyal menjadi bagian ganjil dan genap yang membuat sejumlah perhitungan yang diperlukan lebih rendah. Dengan menggunakannya total perkalian kompleks yang dibutuhkan dapat direduksi menjadi NlogN. yang merupakan peningkatan yang signifikan. DFT tipikal membutuhkan N*N perkalian kompleks untuk hasil, sedangkan FFT hanya membutuhkan N*logN. ini adalah keuntungan yang signifikan jika jumlah sampelnya tinggi.

Anda dapat merujuk referensi di bawah yang saya rujuk saat menulis kode untuk pemahaman terperinci tentang matematika di balik FFT:

1. https://flylib.com/books/en/2.729.1/derivation_of_...

2. https://jakevdp.github.io/blog/2013/08/28/understa...

3. https://cnx.org/contents/[email protected]:zmcmahhR@7/D...

4. https://en.wikipedia.org/wiki/Fast_Fourier_transfo...

Langkah 2:Penjelasan Kode

1. Sinus cepat dan Cosinus:

Perhitungan FFT mengambil nilai berbagai sinus dan cosinus beberapa kali. Fungsi inbuilt Arduino tidak cukup cepat dan membutuhkan banyak waktu untuk memberikan nilai yang dibutuhkan. Yang membuat kode secara signifikan lebih lambat (menggandakan waktu untuk 64 sampel). Untuk mengatasi masalah ini, nilai sinus untuk 0 hingga 90 derajat disimpan sebagai kelipatan 255. Melakukan hal itu akan menghilangkan kebutuhan menggunakan nomor penyimpanan sebagai float dan kita dapat menyimpannya sebagai byte yang mengambil ruang 1/4 di Arduino. Sine_data[ ] perlu ditempelkan di atas kode untuk mendeklarasikannya sebagai variabel global.

Selain sine_data, sebuah array bernama f_peaks[] dideklarasikan sebagai variabel global . Setelah setiap menjalankan fungsi FFT, array ini diperbarui. Di mana f_peaks[0] adalah frekuensi paling dominan dan nilai selanjutnya dalam urutan menurun.

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 ]; 

Karena kami telah menyimpan nilai sinus untuk 0 hingga 90 derajat, nilai sinus atau kosinus apa pun dapat dihitung. Di bawah ini berfungsi putaran pertama angka ke titik nol desimal dan mengembalikan nilai dari data yang disimpan. metode ini hanya membutuhkan satu divisi mengambang. Ini dapat dikurangi lebih lanjut dengan menyimpan nilai sinus secara langsung (bukan 255 kelipatan). tapi itu memakan memori tinggi di Arduino.

Menggunakan prosedur di atas mengurangi akurasi tetapi meningkatkan kecepatan. Untuk 64 poin memberikan keuntungan 8 md dan untuk 128 poin memberikan keuntungan 20 md.

Langkah 3:Penjelasan Kode:Fungsi FFT

FFT hanya dapat dilakukan untuk ukuran sampel 2, 4, 8, 16, 32, 64 dan seterusnya. jika nilainya bukan 2^n, maka akan mengambil sisi nilai yang lebih rendah. Misalnya, jika kita memilih ukuran sampel 70 maka hanya akan mempertimbangkan 64 sampel pertama dan menghilangkan sisanya.

Selalu disarankan untuk memiliki ukuran sampel 2^n. yang dapat:

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

Dua float out_r dan out_im akan memakan banyak memori. untuk Arduino nano tidak akan berfungsi untuk sampel yang lebih tinggi dari 128 (dan dalam beberapa kasus 128) karena kurangnya memori yang tersedia.

data int yang tidak ditandatangani[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++) //menghitung level { if(data[i]<=a){o=i;} } int in_ps[data[o]]={}; //input untuk sequencingfloat out_r[data[o]]={}; //bagian nyata dari transformfloat out_im[data[o]]={}; //bagian imajiner dari transformasi 

Alur selanjutnya adalah sebagai berikut:

1. Kode menghasilkan sedikit membalik urutan untuk ukuran sampel yang diberikan (detail tentang pembalikan bit pada referensi:langkah 2)

2. Masukkan data yang dipesan sesuai pesanan yang dihasilkan,

3. FFT dilakukan

4. Amplitudo bilangan kompleks dihitung,

5. Puncak terdeteksi dan diurutkan dalam urutan menurun

6. hasil dapat diakses dari f_peaks[].

[untuk mengakses data lain (selain frekuensi puncak) kode harus diubah, sehingga variabel lokal dapat disalin ke beberapa variabel global yang telah ditentukan sebelumnya]

Langkah 4:Menguji Kode

Sebuah sampel gelombang segitiga diberikan sebagai masukan. untuk frekuensi sampling gelombang ini adalah 10 Hz dan frekuensi gelombang itu sendiri adalah 1,25 Hz.

Seperti yang dapat ditunjukkan dari output mentah, nilai cocok dengan FFT yang dihitung oleh Scilab. namun, nilai ini tidak persis sama dengan akurasi rendah tetapi gelombang sinus lebih cepat.

Pada frekuensi keluaran frekuensi larik adalah 1,25 dan 3,75. tidak perlu untuk mendapatkan nilai yang tepat setiap saat. biasanya angka-angka ini disebut frekuensi bin. jadi nilai output mungkin ada di mana saja dalam bin yang ditentukan.

Kecepatan:

untuk Arduino nano dibutuhkan:

  • 16 Poin :4ms
  • 32 Poin :10 md
  • 64 Poin :26ms
  • 128 Poin :53 md

Langkah 5:Kesimpulan

Kode FFT ini dapat digunakan dalam aplikasi waktu nyata. Karena dibutuhkan sekitar 30 ms untuk menyelesaikan perhitungan. Namun, resolusinya dibatasi oleh sejumlah sampel. Jumlah sampel dibatasi oleh memori Arduino. Dengan menggunakan Arduino Mega atau akurasi papan kinerja yang lebih tinggi lainnya dapat ditingkatkan.

Jika Anda memiliki pertanyaan, saran, atau koreksi, jangan ragu untuk berkomentar.

Kode

  • EasyFFT
EasyFFTArduino
Kode ini menjalankan FFT dan memperbarui larik F_peasks dengan 5 frekuensi paling dominan teratas.
/*//Contoh data:int data[64]={14, 30, 35, 34, 34, 40, 46, 45, 30 , 4, -26, -48, -55, -49, -37,-28, -24, -22, -13, 6, 32, 55, 65, 57, 38, 17, 1, -6, - 11, -19, -34, -51, -61, -56, -35, -7, 18, 32, 35, 34, 35, 41, 46, 43, 26, -2, -31, -50, -55, -47, -35, -27, -24, -21, -10, 11, 37, 58, 64, 55, 34, 13, -1, -7};*///---- -------------------------------------------------- ---------------------//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, //Tempel ini di atas program198, 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]; // puncak 5 frekuensi teratas dalam urutan menurun//-------------------------------------------------- ------------------------------------//void setup() { Serial.begin(250000); } void loop() {/*//exampleFFT(data,64.100); //untuk mendapatkan lima nilai teratas dari frekuensi X yang memiliki 64 sampel pada 100Hz samplingSerial.println(f_peaks[0]);Serial.println(f_peaks[1]);delay(99999);*//* setelah ruing di atas FFT( ), frekuensi tersedia di f_peaks[0],f_peaks[1],f_peaks[2],f_peaks[3],f_peaks[4],*/ }//--------------- -------------- Fungsi FFT ---------------------------------- ------------//float FFT(int in[],int N,float Frequency){/*Kode untuk melakukan FFT pada arduino,setup:paste sine_data [91] di atas program [ variabel global], rekatkan fungsi FFT di akhir programTerm:1. in[] :Array data, 2. N :Jumlah sampel (ukuran sampel yang direkomendasikan 2,4,8,16,32,64,128...)3. Frekuensi:frekuensi pengambilan sampel diperlukan sebagai input (Hz)Jika ukuran sampel tidak dalam pangkat 2, maka akan dipotong ke sisi bawah angka. yaitu, untuk 150 jumlah sampel, kode akan mempertimbangkan 128 sampel pertama, sampel yang tersisa akan dihilangkan.Untuk Arduino nano, FFT lebih dari 128 sampel tidak dimungkinkan karena keterbatasan mamory (64 direkomendasikan)Untuk jumlah sampel yang lebih tinggi mungkin timbul terkait Mamory masalah,Kode oleh ABHILASHContact:[email protected] Dokumentasi:https://www.instructables.com/member/abhilash_patel/instructables/2/3/2021:ubah tipe data N dari float ke int untuk>=256 sampel* /unsigned int data[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++) //menghitung level { if(data[i]<=a){o=i;} } int in_ps[data[o]]={}; //input untuk sequencingfloat out_r[data[o]]={}; //bagian nyata dari transformfloat out_im[data[o]]={}; //bagian imajiner dari transformasi x=0; for(int b=0;ba) {out_r[i]=in[in_ps[i]-a];} }int i10,i11,n1;float e,c,s,tr,ti; untuk(int i=0;i di sini seterusnya out_r berisi amplitudo dan our_in berisi frekuensi (Hz) for(int i=0;iout_r[i-1] &&out_r[i]>out_r[i+1] ) {in_ps[x]=i; //in_ps array digunakan untuk menyimpan bilangan puncak x=x+1;} }s=0;c=0; for(int i=0;i360){j=j-360;} if(j>-1 &&j<91){out=sine_data[j];} else if (j>90 &&j<181){out=sine_data[180-j];} else if(j>180 &&j<271){out=-sine_data[j-180];} else if(j>270 &&j<361){out=-sine_data[360-j];} return (out/255);}float cosinus(int i){ int j=i; mengapung keluar; while(j<0){j=j+360;} while(j>360){j=j-360;} if(j>-1 &&j<91){out=sine_data[90-j];} else if(j>90 &&j<181){out=-sine_data[j-90];} else if(j>180 &&j<271){out=-sine_data[270-j];} else if(j>270 &&j<361){out=sine_data[j-270];} kembali (keluar/255);}//---------------------- -------------------------------------------------- ------------//

Skema


Proses manufaktur

  1. Apakah Transformasi Fourier itu?
  2. Decoder DTMF Hanya Menggunakan Arduino
  3. Sistem Alarm Arduino:SERENA
  4. Python3 dan Komunikasi Arduino
  5. Pemantauan Suhu CERDAS untuk Sekolah
  6. Perpustakaan Port IO 8-Bit untuk Arduino
  7. Matriks Keyboard Prototipe 64-Key untuk Arduino
  8. Input Analog Terisolasi untuk Arduino
  9. Robot untuk navigasi dalam ruangan yang sangat keren
  10. Apa Kode HS untuk pompa hidrolik?