FFT dönüşümü hakkında

Başlatan Mucit23, 31 Ocak 2014, 00:08:32

camby

#15
mucit , kare dalga ver , başka bir pinden de olur.

Kare dalganın fft'si güzel ve bilinen bir fft.

Test ederken F4'e ait outputların init sırasında belirlediğimiz frekans ayarını değiştirdiğimizde yüksek frekanslı bileşenlerin de değişmesi lazım. Bunu FFT de gözlemleyebilirsin. Hem de neden ihtiyacımız yok iken pinleri 100MHz de kullanmamalıyız görmüş oluruz uygulamalı.


Basit bir grafik en azından yanyana bar graph lar da çok yararlı olur. Matrix gibi uğraşmazsın : )

berat23

bilgisayarın sesçıkışını kullanabilirsin ama zaten dc verdiğinde gerilim yükseldikçe 1. katsayı artıyorsa doğru gibi gözüküyor zira 0.terim sinyalin dc bileşenidir.

Mucit23

Teşekkürler @camby dün aklıma geldi ama geç oldu diye uğraşmadım. Olmazsa bu akşam denerim.

@berat23, girişteki gelirimi arttırınca 1. değer 10-11 lere fırlıyor. Diğer bütün değerlerde 7-8'lere çıkıyor.

Bu sistemde FFT'yi anladıktan sonra hazır kütüphaneye geçmem gerekecek. Çünkü bu kodlar çok yavaş çalışıyor. Hiç arada delay koymasam bile tahmimince saniyede 4-5 defa bütün işlemler tekrarlanabiliyor. Bir sürü float işlem yapıldığından kaynaklansa gerek. Hazır kodları inceliyorum float değişken bile yok. Hep int türünden değişkenler kullanılıyor.

ST'nin DSP library'sini kullanan oldumu?

Mucit23

Ben yinede bu kadar yavaş çalışmasına anlam veremedim. Adamlar 16F de ASM ile kodlayarak 65fps'de fft alıp spectrum gösteriyorlar. Tamam yapılan işlemler çok fazla ve ağır ama bukadar düşmesine pek anlam veremedim.
Acaba system core clock gerçekten 168Mhz mi. Nasıl ölçebilirim?

RaMu

Hocam ekrana yazdırma işi uzun sürüyor olabilir mi,
sanki tft ekran kullanıyordunuz gibi hatırlıyorum,
hiç ekrana yazdırmadan işlemi 3-5 defa tekrarlatıp ne kadar sürdüğünü kontrol etmeyi deneyebilirsiniz.

Ayrıca henüz bakmadıysanız şu konudada biraz ft vs. konuşmuştuk
https://www.picproje.org/index.php/topic,48884.30.html
her ne kadar picprojenin kanayan yarası, tamamlanmamış projelerden biri olarak kalan birdiğer fft konusu olsada.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

berat23

o kodu çok detaylı incelemedim ama içinde sin, cos, log var. zaten bu haliyle hızlı çalışmasını beklemek doğru değil.  ayrıca ben olsam sonuçları debug ile görmeye çalışırdım, tft bence gereksiz.

Mucit23

#21
Benim yazdığım kodlarda çalışıyor. Dün akşam bilgisayarımdan ses sinyali uyguladım. Farklı frekanslarda farklı bandların değiştiğini gördüm.

Şimdilik o kodları kenara bırakıp biraz daha işin temeline inmem gerek.

Güzel bir kaynak buldum. Biraz burdan devam edeceğim.
http://www.waitingforfriday.com/index.php/Fast_Hartley_Transformation_Library_for_AVR_microcontrollers

Bu arada FFT nin yanında birde FHT(Fast Hartley Transform) varmış.

Mucit23

#22
Kara düzen bir örnek yaptım. ADC'ye MP3 sinyali uyguluyorum.

resim gönder
Ama sonuç hiç aklıma yatmadı. Örnekleme frekansını felan ayarlayamadım sanırım 1Khz nin altında bir değer göremiyorum. Sanırım çok yüksek frekansta örnek alıyorum.

Barlar hiç akıcı değil çok titreme oluyor. Sebebini çözemedim ama sanırsam arada saçma sonuçlar geliyor bundan kaynaklanıyor. Ayrıca bar çizme fonksiyonunu kendim yazdım ama pek iyi olmadı galiba.
void LCD_DrawBargraph(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height, uint8_t BarVal)
{
  uint16_t x=Xpos, y=LCD_PIXEL_HEIGHT-Ypos-1;
  uint16_t a=0, b=0, color=0;
  uint16_t val=((uint16_t)(BarVal*(y+Height))/100);
	for (a=0;a<Height;a++) //Dikey Tarama Yapiliyor.
	{
		 if (val>=a)
	   {
           color=TextColor;
     }
		 else
		 {
           color=BackColor;

     }
     for(b=0;b<Width;b++)// Yatay Tarama yapiliyor.
		 {
        LCD_DrawPoint(x+b, LCD_PIXEL_HEIGHT-y-a-1, color);
     }
  }
}

Özelikle Barın kalınlığı ve yüksekliği artınca çok yavaşlıyor.(tabiri caizse hayvan gibi işlemciyi öldürüyorum burada) Bar çizmede daha iyi olduğunu düşündüğünüz bir algoritma varmı?

İşleri hızlandırma adına kesinlikle ST'nin DSP library'sini kullanmam gerek. Bu şekilde FFT alma rutinleri yaklaşık 15,16ms sürüyor. Ekrana basma rutinleri kaç ms sürüyor ölçmedim daha. Bence çok fazla bir değer.

Ayrıca ADC örnekleme işini çözmem gerek. Sabit bir frekansta örnek almalıyım. Bunu nasıl yapacam henüz bilmiyorum. delaylarla felan kara düzen gitmiyor. Gui tarzı birşey olsa çok güzel olacak..

RaMu

Ekrana yazdırma uzun sürüyor olabilir daha önce demiştim,
bu nedenlede sıkıntılar olabilir yukarıdakilerle ilgili.

Adc örneklemesini timer kesmesiyle almakta fayda var,
hatta waiting for friday deki 18f li örnekte
eleman adc örneklemesini aldığı zamanlamanın eşitliğini
herbir adc örnekelemesinde bir pini toggle ederek
ve toggle ettiği pini osiloskopla gözleyerek
ayrıca kontrol ediyordu, yanlış hatırlamıyorsam.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Mucit23

Benim öncelikle akıcı bir şekilde bargraphlar oluşturmam lazım.
Bazı örnekler,
FFT Audio Spectrum Analyser PIC32 QVGA LCD
Graphic audio spectrum analyzer

Nasıl yapıyorlar? Benim yanlış yaptığım konu nedir?

Mucit23

Merhaba Arkadaşlar şöyle bir problemim var.

FFT alma işini çözdüm sayılır. İşlem sırasında bir sıkıntım var. Şuanda yaptığım işlem sırası şöyle.

İlk önce ard arda 64 adet örnek alıyorum
Ardından aldığım örneklerin FFT'sini alıyorum
Son olarakda FFT sonucunda elde ettiğim değerleri ekrana basıyorum.

Şöyle bir problem var. 22KHz de 64 örnek alsam her bir döngüde yaklaşık 45uS beklemem gerekirki buda 45x64'den yaklaşık olarak 2280uS bir süre tutar. Ben her FFT almadan önce bu süreyi beklemek istemiyorum. Zaten FFT ve diğer grafik işlemlerim yeterince zamanımı alıyor.

Ben bu işlemi timer ile flaglar yardımıyla yapabilirim fakat ben Rtos ile yapmak istiyorum.

Kendi projeme CoOS'u dahil ettim, şuanda 2 adet task oluşturdum blink vs yapabiliyorum. Örneğin CoOS 'da TaskA'nın FFT işlerimi hallettiğimiz varsayalım. TaskB ise bize ADC den 22KHz de örnek alsın. Ben TaskA içerisinden TaskB'ye nasıl start verebilirim. Yani TaskA nın başındayken TaskB'ye örnek almaya başla diyeceğim. 64 adet örnek alıp duracak ve TaskA dan tekrardan start gelmesini bekleyecek. Bunu flaglar ilemi yapmam gerekiyor? Eğer bunu yapabilirsem aynı işlemi Bargraph Basma içinde yapacağım.

Diğer bir sorum ise CoOS'a Task Switch ile ilgili

void led_blink(void *pdata)
{
  for(;;)
	{
                 CoTickDelay(50);
		 STM_EVAL_LEDOn(LED3);
		 CoTickDelay(50);
		 STM_EVAL_LEDOff(LED3);
        }
}


Örneğin bu task'da 500'ms aralıklarla led yakıp söndrüyorum. CoTickDelay parametresinde her bir tick, 10ms gecikmeye denk geliyor. Yani  CoTickDelay(50); dediğim zaman 500ms bekliyor. Benim mesela 22Khz'de örnek alabilmem için 45uS gecikme yaratabilmem lazım. Şuanda CoOS'un Kullanım kılavuzuna bakınıyorum ama elde tutulur birşey elde edemedim. Bu konuda yönlendirmeye ihtiyacım var.

Aslında tam emin değilim benim kurduğum mantıktada problem olabilir, Acaba doğru yoldamıyım?

kantirici

Bekleme olacaksa rotos gereksiz olabilir. Bence adc işini dma ya bırak. istenilen frekansata sürekli örnek alıp bir alana yazsın. Sen main içerisinde sürekli 64 değerin fft sini al ekrana bas. Hatta bu iş içinde bir timer kurulup ekran sürekli güncellenebilir. Yani ekran güncelleme işlemi tek seferde değilde parça parça yapılsın. Burada da ekran için ram de bir alan olsun. Kesme fonksiyonu bu alanı parça parça sürekli ekrana bassın.

Mucit23

@kantirici,

Dma ile bu dediklerin yapılırmı emin değilim.
Benim 64 elemanlı dizim olacak. Dma sıra ile adc den gelen değerleri bu diziye yerleştirecek. Bütün dizi dolduğunda tekrar baştan başlıyacak.
Ben zaten şuanda DMA ile ADC den örnek alıyorum. ADC otomatik çevrim modunda, DMA ise sürekli ADC_DR registerindeki değeri alıp benim tanımladığım değişkenin adresine yazıyor. 

DMA ayarlarında  DMA_MemoryInc ve DMA_BufferSize gibi parametreler var. Biraz araştırayım bu konuyu.

Benim asıl yapamadığım sampling rate konusu.

Ben ADC'yi istediğim frekansta örnek alacak şekilde ayarlayamıyorum. ADC ayarlarını karıştırıyorum birtek  ADC_TwoSamplingDelay_5Cycles diye bir parametre var. Hızı belirleyecek birde ADC_Prescaler var. Sadece bu iki parametre ile oynayarak 22KHz ADC örnekleme frekansı elde edebilirmiyim? Özellikle bu sorunun cevabını çok merak ediyorum.

Aslında Rotos olmadan bu sistemi güzel bir şekilde rayına oturtabilirim ama tek bir döngü içerisine tıkılıp kalmak can sıkıcı.

mistek

#28
Yüksek sayıda örnek işini DMA halleder. Dikkat etmen gereken nokta her kanal için aynı örnek sayısında elemanın olacak. Yani bildiğim kadarıyla 3 ADC pini DMA ya bağlıysa her kanal için eşit sayıda örnek alabilirsiniz, birinden 64 adet alıp diğerinden 5 adet alayım şeklinde Buffer ayarlanmıyor.

Hangi işlemciyi kullanıyorsunuz?
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

Mucit23

Hocam STM32F407 ile Tek kanal ADC'den ölçüm alıyorum. DMA ile ilgili ayarlara biraz bakınayım ben.

Peki, Sampling Rate işini nasıl ayarlayacağım?