Fourier, AFD (DFT), HFD (FFT)

Başlatan mihri, 21 Eylül 2009, 00:34:44

mihri

Arkadaşlar sık sık FFT ile ilgili kod isteği geliyor bu yüzden hem FFT hemde DFT için yazdığım kodları paylaşıyorum. Aşağıdaki linklerden indirilebilir. Ayrıca  mod arkadaşlar kodyarı silinmeyecek biryere upload ederlerse sevinirim.

http://www.dosya.tc/server7/0qHcWq/FFT.rar.html

http://www.dosya.tc/server7/S3nGlF/DFT.rar.html

Unutmadan şunuda ekleyeyim  bu kodları yazalı 2 seneden fazla olmuş. Forumun zehir gibi üyeleri kodlardan hemen mantığı kapacaklardır.  :)
"Eppur si muove!"

SiVRiSiNEK

DTMF ton frekans tablosu


"1" tuşunun grafiği 1209Hz ve 697Hz karışımı


picin analog girişine DTMF sinyalini girdik diyelim bu fourier dönüşümleri ile içiçe geçmiş 2 dalganın frekansını çözümleyip hangi tuşa basıldığını nasıl anlarız

picusta

@SiVRiSiNEK
|FFT| yaptiktan sonra DTMF çözmek için asagidaki gibi bir kod yazmistim. Bir gönüllü Mihrinin verdigi FFT'yi bu fonksyonla birlestirse bir de proteus'ta simülasyon yapsa tadindan yenmez.
#define MX_FFT_SAMPLE         256         // FFT tablosunun uzunlugu
#define MX_FFT_FRENQUENCY      40000      // FFT tablosundaki maksimum frekans


/*
  * ENU_DTMF_FREQ
  *  DTMF frekanslarinin sayilmasi
  */
typedef enum ENU_DTMF_FREQ
{
ENU_DTMF_FREQ_SATIR1,   // 697
ENU_DTMF_FREQ_SATIR2,   // 770
ENU_DTMF_FREQ_SATIR3,   // 852
ENU_DTMF_FREQ_SATIR4,   // 941
MX_DTMF_FREQ_SATIR,
ENU_DTMF_FREQ_SUTUN1  = MX_DTMF_FREQ_SATIR,   // 1209
ENU_DTMF_FREQ_SUTUN2,   // 1336
ENU_DTMF_FREQ_SUTUN3,   // 1477
ENU_DTMF_FREQ_SUTUN4,   // 1633
MX_DTMF_FREQ_SUTUN = (ENU_DTMF_FREQ_SUTUN4 - ENU_DTMF_FREQ_SUTUN1 +1),
};

// DTMF frekans listesi
unsigned char LstDTMFFreq[]=
{
697,  //ENU_DTMF_FREQ_SATIR1,
770,  //ENU_DTMF_FREQ_SATIR2,
852,  //ENU_DTMF_FREQ_SATIR3,
941,  //ENU_DTMF_FREQ_SATIR4,
1209, //ENU_DTMF_FREQ_SUTUN1,
1336, //ENU_DTMF_FREQ_SUTUN2,
1477, //ENU_DTMF_FREQ_SUTUN3,
1633  //ENU_DTMF_FREQ_SUTUN4,
};

// DTMF kod çozme tablosu
unsigned char DTMFTablo[MX_DTMF_FREQ_SATIR][MX_DTMF_FREQ_SUTUN] =
   {
      {'1','2','3','A'},
      {'4','5','6','B'},
      {'7','8','9','C'},
      {'*','0','#','D'}
   };

/*
 * DecodeDTMF
 * FFT Tablosundan DTMF kodu bulma fonksyonu
 * Girdi :
 *     -> FFTTab : sinyalin FFT mutlak deger tablosu
 *   -> Treshold : Deteksyon genligi
 *   <- Kod : dekode edilen DTMF kodu
 *  çikti :
 *   DTMF sinyali bulduysa true, bulamadiysa false
 *
 */
 
bool DecodeDTMF (unsigned char *FFTTab, unsigned char Treshold, char *Kod )
{
bool Retour;      // çikti degeri
int MaxFreqSatir,      // Birinci maximum frekans
   MaxFreqSutun;      // Ikinci maximum frekans
   
int FreqAdim,      // Frekans adimi
   IdxFreq;      // FFT tablosu endeksi

int ii;         // Döngü sayaci

Retour = false;
MaxFreqSatir = -1;
MaxFreqSutun = -1;
FreqAdim = MX_FFT_FRENQUENCY / MX_FFT_SAMPLE;

// Ilgilenilen frekanslarin sinyal genligini esik degerle karsilastir
for (ii = 0; ii < MX_DTMF_FREQ_SATIR + MX_DTMF_FREQ_SUTUN && !Retour; ii++ )
{
IdxFreq = LstDTMFFreq[ii] / FreqAdim;
if (FFTTab[IdxFreq] > Treshold)
   {
   if (MaxFreqSatir == -1)
      {
      if (ii < MX_DTMF_FREQ_SATIR)
         MaxFreqSatir = ii;
      }
   else
      {
      if (ii > MX_DTMF_FREQ_SATIR -1)
         {
         MaxFreqSutun = ii;
         Retour = true;
         }
      }
   }
}

// Dekod ve çikis
if (Retour)
   {
   *Kod = DTMFTablo[MaxFreqSatir][MaxFreqSutun];
   }
else
   {
   *Kod = '\0';
   }

return Retour;
}


Bu link'te de FFT hesaplaniyor ve DTMF kod çözümü yapiliyor:


DTMF Remote control – A software DTMF decoder for PIC 16F87X

SiVRiSiNEK

şimdi şu Detect=..... diye başlayan formülü türkçe nasıl izah edebiliriz? ondan sonrasını mikroişlemci koduna dökeriz bir şekilde

okul yılları eskide kaldı yaş malum bu formülü anlayabilecek matematik pek kalmadı bende :)

picusta

Alıntı yapılan: "SiVRiSiNEK"şimdi şu Detect=..... diye başlayan formülü türkçe nasıl izah edebiliriz? ondan sonrasını mikroişlemci koduna dökeriz bir şekilde

okul yılları eskide kaldı yaş malum bu formülü anlayabilecek matematik pek kalmadı bende :)

Konunun basinda Mihrinin emek verip hazirladigi ve sundugu dokümani bu formülün izahi değil de ne peki ?
Biraz zahmed edip indirip bir de okuma zahmetine girseydin ... .

Alıntı YapAmacım bütün dokümanları okuyan kişilerin istedikleri programlama dili ve mikrodenetleyici ile HFD (FFT) yapabilecek bilgi düzeyine sahip olmalarını sağlamaktır.

SiVRiSiNEK

okuma zahmetine girdim ama sanırım bir sonraki yazıda daha ayrıntılı bilgi vereceğini yazmış arkadaşımız, bu arada eline koluna sağlık @mihri



yalnız herkesin algılama kapasitesi bir değil malumunuz mesela ben yukarıdaki formule bakınca ne demek istediğini tam olarak anlayamıyorum

254 kere örnek alıp sinüs kosinüs birşeyler oluyor ama kendime tam izah edemiyorum sadece bunun açıklamasını basit yalın dille anlatabilirmisiniz diye sormuştum, ondan sonra bir şekilde C veya basice geçirilir genelde nette örnekler asm çıktı karşıma

gevv

 

hasangurlek

Çok güzel karikatür :) aman konu dağılmasın.

Sabırsızlıkla 2.3. 10. kısımları bekliyoruz.
http://www.cyber-warrior.org, Although they like whiteness, sometimes twilight is required...  Hala evlilermi bilinmez ama kesinlikle artık uygun değiller !!!

picusta

Alıntı yapılan: "SiVRiSiNEK"okuma zahmetine girdim ama sanırım bir sonraki yazıda daha ayrıntılı bilgi vereceğini yazmış arkadaşımız, bu arada eline koluna sağlık @mihri

(Resim gizlendi görmek için tıklayın.)

yalnız herkesin algılama kapasitesi bir değil malumunuz mesela ben yukarıdaki formule bakınca ne demek istediğini tam olarak anlayamıyorum

254 kere örnek alıp sinüs kosinüs birşeyler oluyor ama kendime tam izah edemiyorum sadece bunun açıklamasını basit yalın dille anlatabilirmisiniz diye sormuştum, ondan sonra bir şekilde C veya basice geçirilir genelde nette örnekler asm çıktı karşıma

Formülü anlamak için lise düzeyinde matematik biliyor olmak gerekir.
Kisaca söyle izah edeyim :
1) ABS( xxx ) demek xxx'nin mutlak degerini al demek.
2) O gördügün isarete (E gibi olan) sigma deniyor ve birçok terimin toplanmasi demek.
Sigmadan sonraki ifade 255 kere toplaniyor, terimler arasinda degisen tek sey N degiskeni (0'dan 254'e kadar). N degiskeni sinus fonksyonunda varbir de In(N) kisminda. Burada In giris sinyalinin tablosu oldugu için In(x)  x. giris sinyalinin örnegine tekabül ediyor.

SiVRiSiNEK

şimdi ozaman

sin(2*PI*Fd*(1/Fsample*N))*In(N)

kısmını N değerini 0..254 arası vererek 255 kere yapıp toplayacağız öylemi?

peki

Fd
Fsample

bunlar nedir değeri nasıldır?

birde In() tablosundan N inci değeri alacağızda bu tablodaki değerler nasıl belirleniyor?

Cos kısmında In(t) var t nedir?

ftsahin

Alıntı yapılan: "picusta"
Bu link'te de FFT hesaplaniyor ve DTMF kod çözümü yapiliyor:
(Resim gizlendi görmek için tıklayın.)

DTMF Remote control – A software DTMF decoder for PIC 16F87X


Formüldeki ln(N) şeklindeki ifade Ln(N) olabilir.  Matematik formüllerinde In() diye bir ifade yok bildiğim kadarıyla.
2*pi*fd kısmı da pek yabancı gelmedi. Sanırım bu da Omega'nın açılımı :  W=2.pi.f.
Eğer böyleyse f'i bizim vermemiz gerekebilir. Bu da frekens bileşenlerini bilmemiz gerektiğini gösterir.    
Eğer frekansı da biliyorsak geriye Fsample kalıyor. O da ADC kanalından alınan örnek olarak kabul edersek basit bir kod yazılabilir.



..........


for n=0 to  254
  fsample = adcin 0
  sin_toplam =sin_toplam+ (sin(2*pi*fd*(1/fsample*n)*ln(n))
next n

for n=0 to  254
  fsample = adcin 0
  cos_toplam =cos_toplam+ (cos(2*pi*fd*(1/fsample*n)*ln(t))
next n

detect = abs(sin_toplam + co_toplam)

.....

remzi

ln(t) şeklinde bir değer olmaz olurmu. Alın hesap makinasını elinize ln(3) yazın ln(5) yazın bakın bakalım değer gösteriyormu göstermiyormu?

ftsahin

Alıntı yapılan: "remzi"ln(t) şeklinde bir değer olmaz olurmu. Alın hesap makinasını elinize ln(3) yazın ln(5) yazın bakın bakalım değer gösteriyormu göstermiyormu?


Yazdıklarımı tam anlamamışsınız ben de aynı şeyi söylüyorum. LN diye bir fonksiyon var. e tabanına göre logaritma demek. IN yok yukarıda anlatmak istediğim bu (küçük harfle (in).  
Bu arada t ifadesi de 1/f olabilir.  Aslında konuyu tam anlamak için iyice araştırmak lazım. Örnek kod bile bulunabilir.

mihri

Arkadaşlar şimdilik amacımız DTMF çözmek değil DFT nedir onu öğrenmek sabırlı olmakta fayda var. DFT nedir öğrendikten sonra ne isterseniz onu yapın. 2. kısım bitmek üzere örnek DFT programıda vereceğim konunun daha iyi anlaşılması için. Fakat birtakım matematiksel ifadelerle ilgili probleminiz olmamalı. Mesela toplam sembolu yada Ln()... gibi bunları kendiniz halletmelisiniz. Yoksa araba kullanmasını bilmeyen adamın altına ferrari çeksen neye yarar.
"Eppur si muove!"

Ankaralı

Alıntı yapılan: "mihri"(Resim gizlendi görmek için tıklayın.)

Hocam teşekkürler bunlar işimize derste yarıyacak ancak;
Geçenlerde pic'e 2 float sayıyı hesaplatayım dedim bayıldı kaldı.Sonuc'u %0.5 - %0.6 hata ile hesaplıyor.Çözüm yollarına baktım gene sonuç aynı.Kaldıki sizin yukarıdaki formülü hayatta tam sonuçla hesaplayamaz.Bu sorunu nasıl hallederiz ?
@ NEXYS2