Daftar Isi:

EasyFFT: Transformasi Fourier Cepat (FFT) untuk Arduino: 6 Langkah
EasyFFT: Transformasi Fourier Cepat (FFT) untuk Arduino: 6 Langkah

Video: EasyFFT: Transformasi Fourier Cepat (FFT) untuk Arduino: 6 Langkah

Video: EasyFFT: Transformasi Fourier Cepat (FFT) untuk Arduino: 6 Langkah
Video: Digital Signal Processing (3MB) Alarm Kerusakan Mesin Cuci dengan Algoritma FFT Berbasis Arduino UNO 2024, September
Anonim
Image
Image

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 bekerja ketika sinyal 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.

Langkah 1: Pengantar Transformasi Frekuensi

Pengantar Transformasi Frekuensi
Pengantar Transformasi Frekuensi
Pengantar Transformasi Frekuensi
Pengantar Transformasi Frekuensi

Setiap sinyal dapat terdiri dari kombinasi berbagai gelombang sinusoidal. Jadi setiap sinyal berbasis waktu dapat juga ditampilkan sebagai kombinasi dari berbagai sinus dengan amplitudo yang berbeda.

Saya mencoba menjelaskan cara kerja DFT (transformasi Fourier diskrit) di salah satu instruksi sebelumnya (https://www.instructables.com/id/Arduino-Frequency…). Metode ini sangat lambat untuk aplikasi waktu nyata apa pun. yang membuatnya hampir tidak berguna.

Pada gambar, ditunjukkan sinyal yang merupakan kombinasi dari dua frekuensi f2 dan f5. Sinyal ini dikalikan dengan uji gelombang sinus dari nilai f1 hingga f5.

Secara matematis dapat ditunjukkan bahwa -penjumlahan perkalian dua himpunan data harmonik yang frekuensinya berbeda cenderung nol (jumlah data yang lebih banyak dapat menghasilkan hasil adonan). Dalam kasus kami, Jika dua frekuensi perkalian ini memiliki frekuensi yang sama (atau sangat dekat) jumlah perkaliannya adalah bilangan bukan nol.

Jadi jika sinyal kita dikalikan dengan f1 penjumlahan perkalian akan menjadi nol (mendekati nol untuk aplikasi nyata). serupa adalah kasus untuk f3, f4. Namun untuk nilainya, output f2 dan f5 tidak akan menjadi nol, tetapi secara signifikan lebih tinggi dari nilai-nilai lainnya.

Di sini sinyal diuji dengan 5 frekuensi, jadi sinyal perlu dikalikan dengan lima frekuensi. Perhitungan yang intens seperti itu membutuhkan waktu yang lebih lama. Secara matematis ditunjukkan bahwa untuk N jumlah sampel dibutuhkan N*N perkalian kompleks.

Langkah 2: 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.

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

1.

2.

3.

4.

Langkah 3: 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 diperlukan. 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. Dimana 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 menjadi nol titik 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 8ms dan untuk 128 poin memberikan keuntungan 20ms.

Langkah 4: 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 berupa:

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.

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<=a){o=i;} } int in_ps[data[o]={}; //input untuk mengurutkan float out_r[data[o]={}; //bagian nyata dari transformasi float out_im[data[o]={}; //bagian imajiner dari transformasi

Aliran selanjutnya adalah sebagai berikut:

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

2. Input data yang dipesan sesuai pesanan yang dihasilkan, 3. FFT dilakukan

4. Amplitudo bilangan kompleks dihitung, 5. Puncak terdeteksi dan dipesan 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]

Langkah 5: Menguji Kode

Menguji Kode
Menguji Kode
Menguji Kode
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-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: 4ms32 Poin: 10ms 64 Poin: 26ms 128 Poin: 53ms

Langkah 6: 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.

Perbarui (2/5/21)

Pembaruan: //-----------------------------Fungsi FFT--------------- -------------------------------//float FFT(int in, int N, float Frekuensi)

Tipe data N diubah menjadi Integer (Byte yang ada) untuk mendukung ukuran sampel >255. Jika ukuran sampel <=128, tipe data byte harus digunakan.

Direkomendasikan: