Isi kandungan:

QuickFFT: FFT Berkelajuan Tinggi untuk Arduino: 3 Langkah
QuickFFT: FFT Berkelajuan Tinggi untuk Arduino: 3 Langkah

Video: QuickFFT: FFT Berkelajuan Tinggi untuk Arduino: 3 Langkah

Video: QuickFFT: FFT Berkelajuan Tinggi untuk Arduino: 3 Langkah
Video: RPM measurement by analog input 2024, November
Anonim
QuickFFT: FFT Berkelajuan Tinggi untuk Arduino
QuickFFT: FFT Berkelajuan Tinggi untuk Arduino

Arduino khas mempunyai RAM dan kuasa pemprosesan yang terhad, dan FFT adalah proses intensif komputasi. Untuk banyak aplikasi masa nyata, satu-satunya syarat adalah mendapatkan frekuensi dengan amplitud maksimum atau diperlukan untuk mengesan puncak frekuensi.

Dalam salah satu arahan saya, saya menyediakan kod untuk FFT yang boleh didapati di sini: EasyFFT

Kod ini dapat melakukan FFT hingga 128 sampel di Arduino nano. Nombor sampel yang lebih tinggi daripada ini tidak mungkin berlaku kerana ingatan Arduino yang terhad. Saya telah mengubah fungsi sedikit demi sedikit untuk meningkatkan kelajuan dan mengurangkan penggunaan memori. Pengubahsuaian ini membolehkan Arduino melakukan FFT lima kali lebih pantas dan memakan hampir separuh memori. Instructable ini tidak merangkumi Kerja FFT, rujukan untuknya boleh didapati di EasyFFT.

Langkah 1: Bekerja

Bekerja
Bekerja
Bekerja
Bekerja
Bekerja
Bekerja
Bekerja
Bekerja

Fungsi khas FFT diubah untuk meningkatkan kelajuan dengan ketepatan yang lebih rendah. Seperti yang ditunjukkan dalam gambar, isyarat ujian perlu dikalikan dengan bentuk gelombang sinus atau kosinus. Nilai-nilai ini dapat antara 0 hingga 1, jadi membuat pendaraban terapung adalah suatu keharusan. di Arduino, pendaraban terapung lambat berbanding operasi integer.

Dalam fungsi ini, gelombang sinus / kosinus digantikan oleh gelombang persegi. Oleh kerana kita harus mengalikan isyarat ujian dengan gelombang persegi yang mungkin mempunyai nilai 0, 1 atau -1. Oleh kerana itu, kita dapat menggantikan pendaraban terapung menjadi penambahan atau pengurangan integer. Untuk penambahan atau pengurangan integer Arduino sekitar 5 kali lebih cepat. Ini menjadikan penyelesaian sekitar 5 kali lebih cepat.

Oleh kerana pengubahsuaian ini sekarang nilai tong frekuensi dapat disimpan sebagai bilangan bulat (yang sebelumnya mengambang) dan kami mendapat kelebihan lain dari penggunaan memori yang lebih rendah. Di Arduino Nano, int menggunakan 2 byte memori sementara float menggunakan 4 byte memori. Oleh kerana kelebihan ini dalam kod baru, kami dapat melakukan FFT untuk hampir 256 sampel (sebelumnya 128 sampel).

Dalam FFT Normal kita perlu menyimpan nilai sinus untuk membuat penyelesaian lebih cepat. Dalam fungsi baru, kerana kita tidak lagi memerlukan nilai sinus / kosinus kita dapat menghilangkannya dan menyimpan sedikit memori.

Pelaksanaan:

Melaksanakan fungsi ini adalah lurus ke hadapan. Kita hanya boleh menyalin fungsi di bahagian kod. Fungsi ini dapat dilaksanakan dengan menggunakan perintah di bawah ini:

float f = Q_FFT (data, 256, 100); Dalam fungsi Q_FFT, data: istilah ini adalah array yang mempunyai nilai isyarat, ukuran sampel yang disyorkan adalah 2, 4, 8, 32, 64, 128, 256, 512,… dan seterusnya. jika ukuran sampel tidak termasuk dalam nilai-nilai ini, ia akan dipotong ke sebelah bawah nilai yang terdekat. sebagai contoh, jika ukuran sampel adalah 75 daripada FFT akan dilakukan untuk 64 bilangan sampel. Jumlah saiz sampel maksimum dibatasi oleh RAM yang ada di Arduino.

Istilah kedua menentukan bilangan sampel dalam array dan istilah terakhir adalah frekuensi persampelan dalam Hz.

Langkah 2: Kod

Bahagian ini menerangkan pengubahsuaian yang dibuat dalam kod EasyFFT yang perlu diingat semasa melakukan pengubahsuaian dalam kod tersebut, 1. Seperti yang dijelaskan sebelumnya, di sini bilangan bulat digunakan untuk melakukan FFT. Int dalam Arduino adalah nombor 16-bit dan boleh mengandungi nilai dari -32768 hingga 32768. setiap kali nilai int ini melebihi julat ini menyebabkan masalah. untuk menghilangkan masalah ini selepas pengiraan tahap. jika mana-mana nilai melebihi 15000 tatasusunan lengkap akan dibahagi dengan 100. ini akan mengelakkan int melimpah.

2. Pengiraan amplitud: Untuk mengira amplitud, bahagian sebenar dan khayalan perlu kuasa dua dan punca kuasa dua jumlahnya diperlukan. kuasa dua dan punca kuasa dua fungsi memerlukan masa. untuk menjadikan prosesnya lebih cepat, kod ini hanya akan melakukan sebahagian besar bahagian nyata dan khayalan. Ini pasti kurang tepat dan boleh menyebabkan kesimpulan yang salah dalam beberapa kes. anda mungkin memilih untuk kembali ke kaedah Normal untuk pengiraan magnitud tetapi akan memerlukan lebih banyak masa dan anda juga perlu melakukan beberapa pengaturan untuk menyimpan nombor ini.

3. Kod ini tidak mempunyai modul untuk pengesanan pelbagai puncak. Ia hanya akan memilih nilainya dengan amplitud maksimum (tidak termasuk nombor pertama yang diimbangi DC). Sekiranya anda memerlukan banyak puncak, anda boleh merujuk kod EasyFFT dan melakukan pengubahsuaian yang diperlukan di sini. Dalam kes itu, beberapa array / pemboleh ubah juga perlu dinyatakan sebagai pemboleh ubah global.

4. Fungsi mengandungi baris berikut:

int2 yang tidak ditandatangani [13] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};

menyatakan pemboleh ubah di atas sebagai pemboleh ubah global (menempelkannya pada permulaan kod) akan menjimatkan masa 1 milisaat pada setiap pelaksanaan.

5. Tidak seperti fungsi EasyFFT, di mana 5 puncak teratas disimpan dalam susunan yang telah ditentukan. Fungsi ini akan mengembalikan nilai apungan. nilai ini mewakili frekuensi dengan amplitud maksimum dalam Hz. Jadi perwakilan kod akan kelihatan seperti ini.

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

6. Puncak Pengesanan: Setelah frekuensi dengan amplitud maksimum didapati fungsi ini menggunakan amplitud frekuensi sebelum dan sesudahnya untuk mengira hasil yang tepat. Amplitud yang digunakan dalam pengiraan ini juga merupakan jumlah modulus (bukan punca kuadrat dari jumlah kotak)

jika Fn adalah frekuensi dengan amplitud maksimum maka frekuensi dapat dikira dari formula di bawah.

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

di mana An adalah amplitud n frekuensi dan Fn-1 adalah nilai frekuensi.

Langkah 3: Hasil:

Keputusan
Keputusan
Keputusan
Keputusan

Masa penyelesaian ditunjukkan dalam perbandingan gambar di atas dengan EasyFFT. Kelajuan ditunjukkan dengan perbandingan.

Untuk data sampel yang mempunyai 3 gelombang sinusoidal dengan frekuensi yang berbeza ditunjukkan. Hasil dari QuickFFT dibandingkan dengan output Scilab. Seperti yang dapat kita lihat pada gambar, 3 puncak dengan amplitud maksimum sesuai dengan output Scilab. Walau bagaimanapun, outputnya terdiri daripada banyak bunyi, yang mungkin mengelirukan untuk beberapa aplikasi. Oleh itu, disarankan untuk memeriksa kod dengan betul sebelum melamar aplikasi anda.

Saya harap anda dapati kod ini berguna untuk projek anda. Sekiranya ada pertanyaan atau cadangan, sila komen.

Disyorkan: