İçindekiler:

QuickFFT: Arduino için Yüksek Hızlı FFT: 3 Adım
QuickFFT: Arduino için Yüksek Hızlı FFT: 3 Adım

Video: QuickFFT: Arduino için Yüksek Hızlı FFT: 3 Adım

Video: QuickFFT: Arduino için Yüksek Hızlı FFT: 3 Adım
Video: 16 - Düşük Geçiren Filtreler (Low-Pass Filters) Python Pratik - 1 2024, Kasım
Anonim
QuickFFT: Arduino için Yüksek Hızlı FFT
QuickFFT: Arduino için Yüksek Hızlı FFT

Tipik Arduino, sınırlı RAM ve işlem gücüne sahiptir ve FFT, hesaplama açısından yoğun bir işlemdir. Birçok gerçek zamanlı uygulama için tek gereklilik, maksimum genlikli frekansı elde etmek veya frekans tepe noktalarını tespit etmek için gereklidir.

Talimatlarımdan birinde, burada bulunabilecek FFT için bir kod hazırladım: EasyFFT

Bu kod, Arduino nano'da 128 adede kadar örneğin FFT'sini gerçekleştirebildi. Arduino'nun sınırlı hafızası nedeniyle bundan daha yüksek bir örnek numarası mümkün değildir. Hızı artırmak ve bellek tüketimini azaltmak için işlevi biraz değiştirdim. Bu değişiklik, Arduino'nun FFT'yi beş kat daha hızlı gerçekleştirmesini sağlar ve neredeyse yarı bellek tüketir. Bu Talimat, FFT'nin Çalışmasını kapsamaz, bunun için referanslar EasyFFT'de bulunabilir.

Adım 1: Çalışma

Çalışma
Çalışma
Çalışma
Çalışma
Çalışma
Çalışma
Çalışma
Çalışma

Tipik FFT işlevi, hızı daha az doğrulukla artırmak için değiştirilir. Resimde gösterildiği gibi, bir test sinyalinin sinüs veya kosinüs dalga formları ile çarpılması gerekir. Bu değerler 0 ile 1 arasında olabilir, bu nedenle kayan çarpma yapmak şarttır. Arduino'da Kayan çarpma, tamsayı işlemlerine kıyasla yavaştır.

Bu fonksiyonda sinüs/kosinüs dalgası kare dalga ile değiştirilir. Bir test sinyalini 0, 1 veya -1 değerine sahip olabilecek bir kare dalga ile çarpmamız gerektiğinden. Bu nedenle, kayan çarpmayı basitçe tamsayı toplama veya çıkarma ile değiştirebiliriz. Arduino için tamsayı toplama veya çıkarma işlemi yaklaşık 5 kat daha hızlıdır. Bu, çözmeyi yaklaşık 5 kat daha hızlı hale getirir.

Bu değişiklik sayesinde artık frekans kutusu değerleri bir tamsayı olarak saklanabilir (önceden değişkendi) ve daha düşük bellek tüketiminin başka bir avantajını elde ederiz. Arduino Nano'da int 2 bayt bellek tüketirken, float 4 bayt bellek tüketir. Yeni koddaki bu avantaj sayesinde, yaklaşık 256 örnek (önceden 128 örnek) için FFT gerçekleştirebiliyoruz.

Normal FFT'de daha hızlı bir çözüm yapmak için sinüs değerini saklamamız gerekiyordu. Yeni fonksiyonda, artık sinüs/kosinüs değerlerine ihtiyaç duymadığımız için onu ortadan kaldırabilir ve bir miktar bellek kaydedebiliriz.

Uygulama:

Bu işlevin uygulanması basittir. Fonksiyonu basitçe kodun sonuna kopyalayabiliriz. Bu işlev aşağıdaki komut kullanılarak yürütülebilir:

float f= Q_FFT(veri, 256, 100);Q_FFT işlevinde,

data: Bu terim sinyal değerlerine sahip bir dizidir, önerilen örneklem büyüklüğü 2, 4, 8, 32, 64, 128, 256, 512, … sonrasıdır. örnek boyutu bu değerlere ait değilse, değerlerin en yakın alt kenarına kırpılacaktır. örneğin, örneklem büyüklüğü 75 ise, 64 adet örnek için FFT yapılacaktır. Maksimum örnek boyutu sayısı Arduino'daki mevcut RAM ile sınırlıdır.

İkinci terim bir dizideki örnek sayısını belirtir ve son terim Hz cinsinden örnekleme frekansıdır.

2. Adım: Kodlayın

Bu bölümde, EasyFFT kodunda yapılan değişiklik, kodda değişiklik yapılırken akılda tutulması gereken, 1. Daha önce açıklandığı gibi, burada FFT yapmak için tam sayılar kullanılır. Arduino'da Int 16 bitlik bir sayıdır ve -32768 ile 32768 arası değerler içerebilir. Bu int değeri bu aralığı aştığında soruna neden olur. Seviye hesaplamasından sonra bu sorunu ortadan kaldırmak için. değerlerden herhangi biri 15000'i aşarsa, tam diziler 100'e bölünecektir. bu, int'nin taşmasını önleyecektir.

2. Genlik hesabı: Genliği hesaplamak için reel ve sanal kısımların karesinin alınması ve toplamın karekökü alınması gerekir. kare alma ve fonksiyonun karekökü zaman alıyor. süreci daha hızlı hale getirmek için, bu kod basitçe gerçek ve hayali parçaların bazı büyüklüklerini yapacaktır. Bu kesinlikle daha az doğrudur ve bazı durumlarda yanlış sonuca yol açabilir. Büyüklük hesaplaması için Normal yönteme dönmeyi seçebilirsiniz ancak bu daha fazla zaman alacaktır ve ayrıca bu sayıları saklamak için bazı düzenlemeler yapmanız gerekecektir.

3. Bu kod, çoklu tepe tespiti için bir modüle sahip değildir. Sadece maksimum genliğe sahip değeri seçecektir (DC ofset olan ilk sayı hariç). Birden fazla tepe noktasına ihtiyacınız varsa, EasyFFT koduna başvurabilir ve burada gerekli değişiklikleri yapabilirsiniz. Bu durumda, bazı dizi/değişkenlerin de global değişken olarak bildirilmesi gerekir.

4. İşlev aşağıdaki satırı içerir:

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

yukarıdaki değişkenleri global bir değişken olarak bildirmek (kodun başına yapıştırmak), her yürütmede 1 milisaniyelik bir yerden tasarruf sağlayacaktır.

5. İlk 5 tepenin önceden tanımlanmış dizide depolandığı EasyFFT işlevinin aksine. Bu işlev bir kayan nokta değeri döndürür. bu değer, Hz cinsinden maksimum genlikli frekansı temsil eder. Yani kodun temsili şöyle görünecek.

kayan nokta f= Q_FFT(veri, 256, 100);

6. Tepe Tespiti: Maksimum genliğe sahip frekans bulunduğunda, bu fonksiyon doğru sonuçları hesaplamak için hemen öncesinde ve sonrasında bir frekans genliği kullanır. Bu hesaplamada kullanılan genlik de modülün toplamıdır (kareler toplamının karekökü değil)

Fn, maksimum genliğe sahip frekans ise, frekans aşağıdaki formülden hesaplanabilir.

Gerçek F= (A n-1 *Fn-1 + An-1 *Fn-1 + An-1 *Fn-1) / (An-1+An+An+1)

burada An, frekansın genliği ve Fn-1, frekans değeridir.

3. Adım: Sonuçlar:

Sonuçlar
Sonuçlar
Sonuçlar
Sonuçlar

Çözme süresi, EasyFFT ile yukarıdaki resim karşılaştırmasında gösterilmektedir. Karşılaştırma ile gösterilen hızı.

Farklı frekanslarda 3 sinüzoidal dalgaya sahip örnek veriler için gösterilmiştir. QuickFFT'den elde edilen sonuç, Scilab çıktısı ile karşılaştırılır. Resimde gördüğümüz gibi maksimum genliğe sahip 3 tepe Scilab çıktısı ile eşleşiyor. Ancak çıktı, bazı uygulamalar için yanıltıcı olabilecek çok sayıda gürültüden oluşur. Bu nedenle, başvurunuza başvurmadan önce kodu doğru bir şekilde kontrol etmeniz önerilir.

Umarım bu kodu projeniz için faydalı bulmuşsunuzdur. Herhangi bir sorunuz veya öneriniz olması durumunda lütfen yorum yapın.

Önerilen: