İçindekiler:
- Adım 1: Frekans Dönüşümüne Giriş
- Adım 2: Hızlı Fourier Dönüşümü
- Adım 3: Kodun Açıklaması
- Adım 4: Kodun Açıklaması: FFT Fonksiyonu
- Adım 5: Kodu Test Etme
- 6. Adım: Sonuç
Video: EasyFFT: Arduino için Hızlı Fourier Dönüşümü (FFT): 6 Adım
2024 Yazar: John Day | [email protected]. Son düzenleme: 2024-01-30 13:17
Yakalanan sinyalden frekansın ölçülmesi, özellikle Arduino'da daha düşük hesaplama gücüne sahip olduğu için zor bir görev olabilir. Sinyalin verilen süre içinde sıfır çizgilerini kaç kez geçtiğini kontrol ederek frekansın yakalandığı sıfır geçişi yakalamak için mevcut yöntemler vardır. Böyle bir yöntem, sinyal çeşitli frekansların bir kombinasyonu olduğunda çalışmayabilir.
Böyle bir geçmişe sahip değilseniz, bunu kodlamak bir şekilde zordur. Ancak bir tamirci olarak bu kod, müzik, sinyal analizi ile ilgili çeşitli projeler için oldukça faydalı olabilir. Bu projenin amacı, arka planına girmeden Arduino üzerinde uygulanması kolay bir kod hazırlamaktı.
Bu proje, FFT'nin Çalışmasını açıklamaz, ancak FFT işlevinin uygulamasını açıklar. Aynı işlem ekteki videoda da anlatılmıştır.
Yalnızca kodun uygulanmasıyla ilgileniyorsanız ve bunun bir açıklamasıyla ilgilenmiyorsanız. Doğrudan 3 numaralı adıma geçebilirsiniz.
Adım 1: Frekans Dönüşümüne Giriş
Herhangi bir sinyal, çeşitli sinüzoidal dalgaların bir kombinasyonundan oluşabilir. Dolayısıyla herhangi bir zamana dayalı sinyal, farklı genliklerin çeşitli sinüslerinin bir kombinasyonu olarak da gösterilebilir.
DFT'nin (ayrık Fourier dönüşümü) çalışmasını önceki öğretilebilirlerden birinde açıklamaya çalıştım (https://www.instructables.com/id/Arduino-Frequency…). Bu yöntemler, herhangi bir gerçek zamanlı uygulama için son derece yavaştır. bu da onu neredeyse işe yaramaz hale getiriyor.
Resimde, f2 ve f5 frekanslarının bir kombinasyonu olan bir sinyal gösterilmektedir. Bu sinyal, f1 ila f5 değerlerinin test sinüs dalgaları ile çarpılır.
Farklı frekansa sahip iki harmonik veri kümesinin çarpımının toplamının sıfıra meylettiği matematiksel olarak gösterilebilir (daha fazla veri, meyilli sonuca yol açabilir). Bizim durumumuzda, bu iki çarpma frekansı aynı (veya çok yakın) frekansa sahipse, çarpma toplamı sıfır olmayan sayıdır.
Yani sinyalimiz f1 ile çarpılırsa çarpmanın toplamı sıfır olacaktır (gerçek uygulama için sıfıra yakın). f3, f4 için de durum aynıdır. Ancak değer için f2 ve f5 çıktısı sıfır olmayacak, ancak diğer değerlerden önemli ölçüde yüksek olacaktır.
Burada bir sinyal 5 frekansla test edilir, bu nedenle sinyalin beş frekansla çarpılması gerekir. Böyle yoğun bir hesaplama daha fazla zaman alır. Matematiksel olarak, N sayıda örnek için N*N karmaşık çarpım aldığı gösterilmiştir.
Adım 2: Hızlı Fourier Dönüşümü
DFT'nin daha hızlı hesaplanmasını sağlamak için FFT algoritması James Cooley ve John Tukey tarafından geliştirilmiştir. Bu algoritma aynı zamanda 20. yüzyılın en önemli algoritmalarından biri olarak kabul edilmektedir. Bir sinyali, bir dizi gerekli hesaplamayı daha düşük yapan tek ve çift sıralı bir parçaya böler. Bunu kullanarak, toplam gerekli karmaşık çarpma NlogN'ye indirgenebilir. bu önemli bir gelişme.
FFT'nin arkasındaki matematiğin ayrıntılı bir şekilde anlaşılması için kodu yazarken atıfta bulunduğum aşağıdaki referanslara başvurabilirsiniz:
1.
2.
3.
4.
Adım 3: Kodun Açıklaması
1. Hızlı sinüs ve Kosinüs:
Hesaplama FFT, çeşitli sinüs ve kosinüs değerlerini birden çok kez alır. Arduino'nun dahili işlevi yeterince hızlı değil ve gerekli değeri sağlamak için çok zaman alıyor. Bu, kodu önemli ölçüde yavaşlatır (64 örnek için süreyi iki katına çıkarır). Bu sorunu gidermek için 0 ila 90 derece için sinüs değeri 255'in katları olarak saklanır. Bunu yapmak, sayıları yüzer olarak saklama ihtiyacını ortadan kaldıracak ve Arduino'da 1/4 alanı kaplayan bayt olarak saklayabiliriz. sine_data öğesinin, onu global bir değişken olarak bildirmek için kodun üstüne yapıştırması gerekir.
sine_data dışında, f_peaks adlı bir dizi global değişken olarak bildirildi. FFT işlevinin her çalışmasından sonra bu dizi güncellenir. Burada f_peaks[0] en baskın frekans ve azalan sırada diğer değerlerdir.
bayt sinüs_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];
0 ile 90 derece arasında sinüs değerini sakladığımız için herhangi bir sinüs veya kosinüs değeri hesaplanabilir. Aşağıda, sayının ilk turunu sıfır ondalık basamağa ve depolanan verilerden değer döndürmeye çalışın. bu yöntem yalnızca bir kayan bölüme ihtiyaç duyar. Bu, sinüs değerlerinin (255 çoklu değil) doğrudan saklanmasıyla daha da azaltılabilir. ama bu Arduino'da yüksek hafızayı yiyor.
Yukarıdaki prosedürün kullanılması doğruluğu azaltır ancak hızı artırır. 64 puan için 8ms, 128 puan için 20ms avantaj sağlar.
Adım 4: Kodun Açıklaması: FFT Fonksiyonu
FFT sadece 2, 4, 8, 16, 32, 64 ve benzeri örneklem büyüklüğü için gerçekleştirilebilir. değer 2^n değilse, değerin alt tarafını alacaktır. Örneğin, örnek boyutunu 70 olarak seçersek, yalnızca ilk 64 örneği dikkate alacak ve dinlenmeyi atlayacaktır.
Örnek boyutunun her zaman 2^n olması önerilir. hangisi olabilir:
2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, …
İki float out_r ve out_im, yüksek miktarda bellek alacaktır. Arduino nano için, kullanılabilir bellek eksikliği nedeniyle 128'den (ve bazı durumlarda 128'den) daha yüksek örnekler için çalışmaz.
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++) //düzeylerin hesaplanması { if(data<=a){o=i;} } int in_ps[data[o]={}; //dizileme için giriş float out_r[data[o]={}; // dönüşümün gerçek kısmı float out_im[data[o]={}; // dönüşümün hayali kısmı
Daha fazla akış aşağıdaki gibidir:
1. Kod, verilen örnek boyutu için sırayı biraz tersine çevirir (referanslarda bitin tersine çevrilmesiyle ilgili ayrıntılar: 2. adım)
2. Oluşturulan siparişe göre sıralanan giriş verileri, 3. FFT gerçekleştirildi
4. Hesaplanan karmaşık sayının genliği, 5. Pikler algılanır ve azalan sırada sıralanır
6. sonuçlara f_peaks adresinden erişilebilir.
[diğer verilere erişmek için (tepe frekansı dışında) kod değiştirilmelidir, böylece yerel değişken önceden tanımlanmış bazı global değişkenlere kopyalanabilir]
Adım 5: Kodu Test Etme
Giriş olarak örnek bir üçgen dalga verilir. bu dalga için örnekleme frekansı 10 Hz'dir ve dalganın kendisinin frekansı 1,25 Hz'dir.
Ham çıktıdan da anlaşılacağı gibi, değer Scilab tarafından hesaplanan FFT ile eşleşiyor. ancak, bu değerler bizim düşük doğrulukla tam olarak aynı değil, daha hızlı sinüs dalgası.
Çıkış frekansında dizi frekansı 1.25 ve 3.75'tir. her seferinde tam değeri almak gerekli değildir. tipik olarak bu sayılara frekans kutuları denir. bu nedenle çıktı değeri belirtilen kutular içinde herhangi bir yerde olabilir.
Hız:
Arduino nano için şunları alır:
16 Puan: 4ms32 Puan: 10ms 64 Puan: 26ms 128 Puan: 53ms
6. Adım: Sonuç
Bu FFT kodu gerçek zamanlı uygulamalarda kullanılabilir. Hesaplamayı tamamlamak yaklaşık 30 ms sürdüğü için. Ancak çözünürlüğü birkaç örnekle sınırlıdır. Örnek sayısı Arduino hafızası ile sınırlıdır. Arduino Mega veya diğer yüksek performanslı kartlar kullanılarak doğruluk artırılabilir.
Herhangi bir sorunuz, öneriniz veya düzeltmeniz varsa, yorum yapmaktan çekinmeyin.
Güncelleme (2/5/21)
Güncellemeler://-----------------------------FFT İşlevi--------------- ----------------------------------//float FFT(int in, int N, float Frekans)
N veri türü, >255 örnek boyutunu desteklemek için Tamsayı (mevcut Bayt) olarak değiştirildi. Örnek boyutu <=128 ise byte veri tipi kullanılmalıdır.
Önerilen:
50 $ Altında Hızlı Shifter! Kazeshifter Arduino Ayarlanabilir Hızlı Shifter: 7 Adım
50 $ Altında Hızlı Shifter! Kazeshifter Arduino Ayarlanabilir Hızlı Shifter: Merhaba Superbike veya motosiklet severler!Bu talimatta, ucuza kendi Quick Shifter'ınızı nasıl yapacağınızı paylaşacağım!Bu talimatı okumak için tembel olanlar için videomu izleyin!Not: Bazı bisikletler için Halihazırda Yakıt Enjeksiyon Sistemini kullanıyor, bazen
Hızlı Hartley Dönüşümü Spektral Stetoskop: 22 Adım
Hızlı Hartley Dönüşümü Spektral Stetoskop: Bu talimatta, hızlı hartley dönüşümünü kullanarak spektral stetoskop yapmayı öğreneceksiniz. Bu, kalp ve akciğer seslerini görselleştirmek için kullanılabilir
QuickFFT: Arduino için Yüksek Hızlı FFT: 3 Adım
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
Hızlı, Hızlı, Ucuz, İyi Görünümlü LED Oda Aydınlatması (Herkes İçin): 5 Adım (Resimli)
Hızlı, Hızlı, Ucuz, İyi Görünümlü LED Oda Aydınlatması (Herkes için): Herkese hoş geldiniz :-) Bu benim ilk talimatım, bu yüzden yorumları bekliyoruz :-) Size göstermeyi umduğum şey, KÜÇÜK bütçe.Neye ihtiyacınız var:KabloLED'lerDirençler (12V için 510Ohm)ZımbalarLehimleme demirKesiciler ve diğer temel
Hızlı ve Basit Yumuşak Anahtarlar (Hızlı Prototipleme için): 5 Adım
Hızlı ve Basit Yumuşak Anahtarlar (Hızlı Prototipleme için): Bir yazılım anahtarı yapmanın birçok farklı yolu vardır. Bu talimat, yumuşak anahtar için çok hızlı bir prototipin başka bir seçeneğini gösterir; iletken kumaş yerine alüminyum bant ve iletken iplik yerine katı teller kullanarak bot