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

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

Mucit23

Merhaba,

STM32F407 discovery kitinde karta ses sinyali girip FFT'sini alıp spectrum bastırmak istiyorum. Bir arkadaşımdan FFT konusunda temel bilgileri aldım. İşin mantığını birazcık kavradım. Beraber matlab da bir uygulama yazıp çalıştırdık. Fakat yazdığımız FFT rutininde giriş değeri olarak 1 ile 100 arasında ramdom sayı verdik. 

İşin içine ses sinyali girince biraz tıkandım açıkçası.

Bazı sormak istediklerim var.

Örneğin ben şimdilik 10 band üzerinde çalışmak istiyorum. Belirlemek istediğim frekanslar 100Hz, 180Hz, 310Hz, 550Hz, 1Khz, 1.8Khz, 3.1Khz, 5.5Khz, 10Khz ve 16Khz olsun.

Anlamadığım nokta şu. Bizim yaptığımız matlab uygulamasında N değeri sabitti. Gerçek uygulamada her bir band için ayrı ayrı FFT mi uygulamak mı gerekiyor bunu anlayamadım. Çünkü matlabda yaptığımız uygulamada N kadar örnek alıp FFT uyguladıktan sonra ekrana bastığımızda Aşağıdaki gibi bir sonuç alıyoruz.



Anlayamadığım veya yanlış anladığım çok önemli noktalar olduğunu düşünüyorum. Özellikle her bir band için nasıl FFT alacağımı öğrenmek istiyorum.



RaMu

#1
N değeri dopru anladıysam
DFT deki örnekleme sayısı,
DFT discrete fourier transform ayrık fourier dönüşümü
dft digital ortamda daha hızlı analiz yapmamıza olanak sağlıyor
düzeltme; FFT dft den daha hızlı işlem yapmamızı sağlıyor
radix2 vs. gibi düzeltme fourier transform hesaplama metodları var,
neyse bunu gerekirse tekrar tartışırız,
matlabda bildiğim kadarıyla dft radix2 radix4, goertzel vs.
algoritmalarını hepten işletip ortak bir sonuç alıp onu veriyor,
eğerki kendimiz bir fft algoritması yazıp işletmiyorsak.

Şimdi hocam sizin söylediğiniz frekanslardan en yükseği 16kHz
nyquist kriteri diyorkigörmek istiyorsan en az iki katı ile örnekleyeceksin,
yani siz içerisinde hangi bileşenler var diye görmek istediğiniz sinyali
en az 32 kHz ile örneklemek zorundasınızki
içinde 16 kHz varsa görebilesiniz.
Bunun yanında 16 Khz den küçük hangi sinyallerde varsa onlarda görülüyor zaten.

Kısaca FFT (veya DFT) düzeltme; veya derken fourier transformu fft ilede dft ilede hesaplanabilir
hangi yöntemi kullandıysak artık. Hatta burada hepten fourier transformu bize....diyebiliriz

bize incelediğimiz sinyalin hangi sinus sinyallerinin birleşiminden oluştuğunu söylüyor,
sinyali incelerken örnekleme frekansımızda en az aradığımız sinyalin iki katı frekans olmak zorunda.


Ek;
N değeride çözünürlüğü sağlıyor,
misal 32kHz de 16 tane örnek aldık,
sonuçta çizeceğimiz grafiğin frekans ekseninde
1 2 3 4 ... 15
skalası olur,
eğer 32 örnek alsaydık çözünürlük artacaktı,
ara değerlerdeki frekanslarıda görebilecektik.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

kantirici

Öncelikle frekans max frekansı belirliyoruz.Mesela 12 Khz. Bu durumda örnekleme frekansı min. 24 Khz olmalı (pratikte bir miktar daha fazlası 26-27). Sonra adc den alınacak örnek sayısını belirliyoruz. 64 örnek alırsak 12Khz/64=187.5 Hz ve katları şeklinde analiz yapabiliriz demek. Yani n=1 187.5, n=64 12 Khz bileşenlerini verecektir.

Uygulamada ise seçilen örnekleme frekansına göre adc'den örnek alınacak, örnek alımı bittikten sonra alınan örnekler fft 'ye tabi tutulacak. FFT sonucunda elde edilen n  değerleri için hesaplanan genlik değeri ekranda gösterilecek ve yeniden örnek alınarak bu işlem devam edecek.

Bende fft uygulması yapmak istiyorum ama henüz uğraşamadım. Benim bildiklerimde fft için böyle.

OptimusPrime

#3
RaMu
fft ile dft aynı şey değiller. aynı şekilde dft ile dtft de aynı değiller.
matlab ın fft komutu fft işlemi yapmaz, dft işlemi yapar. help inden de görebilirsin.

Mucit23
olay kantirici ve RaMu nun anlattığı gibi. ama önce matlab ile olayı iyice anladıktan ve geliştireceğin fft algoritmasını matlab in sonuçlarıyla karşılaştırdıktan sonra stm üzerinde dene derim. ayırıca olay sadece fft alma ile bitmiyor. giriş işaretini pencerelemende gerekiyor. ham veriyi fft ye girersen her telden bir işaret görürsün.

mesela matlab da fft olayını iyice öğrendikten sonra 0-2pi aralığındaki saf sinüs girişinin fft sini al sonrada bunu pi/2 kadar kaydırıp yeniden fft sine bak ve birde pencereleyip bak. farkları göreceksin...
https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||

RaMu

OptimusPrime
Yanlış anlaşılmış olabilir biraz kötü yazmışım,
mesajı düzelttim.
Ama kantirici ile aynı şeyleri anlattım zaten.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

OptimusPrime

evet o kısmı atlarsak sende aynı şeyden bahsediyorsun. bende düzelteyim... ;D
https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||

mcn

Olayın tersinden gidersek. Yani mantığını anlayıp FFT yi kurmak değil de,

MikroC ile STM32F4 ARM programlama kitabında görmüştüm mikroC nin FFT kütüphanesi olduğunu yazıyordu.

Bunu inceleyen bakan deneyen var mı, direk bunu kullanarak birşeyler elde edebilir miyiz? Ben de henüz bakmadım şimdi bi bulup incelemeye çalışayım.

Zamanında pic işlemcilerle FFT alıp basit bir spektrum analyzer yapmaya çalışmıştım ama yememişti.
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

yilmaz_kk

  Daha önce arkadaşlarında belirttiği gibi Fs örnekleme frekansın en yüksek değerlikli işaretinin en az iki katı olmalı. Biraz daha yüksek yapman senin için daha yararlı olabilir.
  N sayısına gelince, Fs frekansın en olursa olsun senin verilerini kaç noktada çizeceğin anlamına gelir. Şöyleki 1024 noktalı FFT aldığını düşünürsen 10k' lık bir Fs li sinyal çizdirirsen her bir nokta yaklaşık 10 Hz' lik alanı gösterir.
FFT ' yi aldıktan sonra istediğin band aralığını sonuç üzerinden çizdirebilirsin.

100 Hz, 1000 Hz için ayrı ayrı FFT alamazsın. Sonuç üzerinden ilgili kısımları tarayabilirsin. Çözünürlüğünün yüksek olmasını istiyorsan 2048, 4096 veya 2' nin katları cinsinden daha yüksek N değerlikli fft almanı tavsiye ederim. Bunların dışında kullanacağın değerler için MATLAB zero padding yapacaktır.
Özetlemek gerekirse yüksek Fs kullan, yüksek N seç (Sisteminin buna uygun olduğunu varsayıyorum.). Sonuçları bir değişkene atıp ilgili bandları çizdirebilirsin.

mcn

Mikro C nin FFT örneği;

/*
 * Project name:
     FFT_Convolution (FFT library test example)
 * Description:
      The convolution theorem states that convolution in the time domain corresponds to multiplication in
      the frequency domain. Therefore, the Fourier transform of the convoution of two signals is equal to
      the product of their individual Fourier transforms. The Fourier transform of a signal can be evaluated
      efficiently using the Fast Fourier Transform (FFT).

      Two input signals, a[n] and b[n], with lengths n1 and n2 respectively, are zero padded so that their
      lengths become N, which is greater than or equal to (n1+n2-1) and is a power of 4 as FFT implementation
      is radix-4.

      The convolution of a[n] and b[n] is obtained by taking the FFT of the input signals, multiplying the
      FFT of the two signals, and taking the inverse FFT of the multiplied result.

      This is denoted by the following equations:
      A[k] = FFT(a[n],N)
      B[k] = FFT(b[n],N)
      conv(a[n], b[n]) = IFFT(A[k] * B[k], N)
      where A[k] and B[k] are the N-point FFTs of the signals a[n] and b[n] respectively.
      The length of the convolved signal is (n1+n2-1).
      
 * Test configuration:
     MCU:             STM32F107VC
                      http://www.st.com/st-web-ui/static/active/en/resource/technical/document/reference_manual/CD00171190.pdf
     dev.board:       EasyMx v7 for STM32 ® ARM ®
                      http://www.mikroe.com/easymx-pro/stm32/
     Oscillator:      HSE-PLL, 72.000MHz
     Ext. Modules:    None.
     SW:              mikroC PRO for ARM
                      http://www.mikroe.com/mikroc/arm/
 * NOTES:
     - None.
*/

#include "stdint.h"
#include "__Dsp.h"

#define FFT_BLOCKSIZE 128
#define SNR_THRESHOLD 30
 
// Declare I/O buffers
// -------------------------------------------------------------------
q15_t     testInputA_q15[FFT_BLOCKSIZE/2];
q15_t     testInputB_q15[FFT_BLOCKSIZE/2];
q15_t     Ak[FFT_BLOCKSIZE];             // q15 input A
q15_t     Bk[FFT_BLOCKSIZE];             // q15 input B
q15_t     AxB_q15[FFT_BLOCKSIZE];        // q15 output
float32_t AxB_f32[FFT_BLOCKSIZE];        // f32 output
int cnt;
 
// Test input data for Floating point Convolution example 
// for 32-blockSize generated by the MATLAB randn() function
// -------------------------------------------------------------------
const float32_t testInputA_f32[64] = {
-0.808920,  1.357369,  1.180861, -0.504544,  1.762637, -0.703285,
 1.696966,  0.620571, -0.151093, -0.100235, -0.872382, -0.403579,
-0.860749, -0.382648, -1.052338,  0.128113, -0.646269,  1.093377,
-2.209198,  0.471706,  0.408901,  1.266242,  0.598252,  1.176827,
-0.203421,  0.213596, -0.851964, -0.466958,  0.021841, -0.698938,
-0.604107,  0.461778, -0.318219,  0.942520,  0.577585,  0.417619,
 0.614665,  0.563679, -1.295073, -0.764437,  0.952194, -0.859222,
-0.618554, -2.268542, -1.210592,  1.655853, -2.627219, -0.994249,
-1.374704,  0.343799,  0.025619,  1.227481, -0.708031,  0.069355,
-1.845228, -1.570886,  1.010668, -1.802084,  1.630088,  1.286090,
-0.161050, -0.940794,  0.367961,  0.291907
};
  
const float32_t testInputB_f32[64] = {
 0.933724,  0.046881,  1.316470,  0.438345,  0.332682,  2.094885,
 0.512081,  0.035546,  0.050894, -2.320371,  0.168711, -1.830493,
-0.444834, -1.003242, -0.531494, -1.365600, -0.155420, -0.757692,
-0.431880, -0.380021,  0.096243, -0.695835,  0.558850, -1.648962,
 0.020369, -0.363630,  0.887146,  0.845503, -0.252864, -0.330397,
 1.269131, -1.109295, -1.027876,  0.135940,  0.116721, -0.293399,
-1.349799,  0.166078, -0.802201,  0.369367, -0.964568, -2.266011,
 0.465178,  0.651222, -0.325426,  0.320245, -0.784178, -0.579456,
 0.093374,  0.604778, -0.048225,  0.376297, -0.394412,  0.578182,
-1.218141, -1.387326,  0.692462, -0.631297,  0.153137, -0.638952,
 0.635474, -0.970468,  1.334057, -0.111370
};  
  
const float testRefOutput_f32[126] = {
 -0.818943,  1.229484,  -0.533664,   1.016604,  0.341875, -1.963656,
  5.171476,  3.478033,   7.616361,   6.648384,  0.479069,  1.792012,
 -1.295591, -7.447818,   0.315830, -10.657445, -2.483469, -6.524236,
 -7.380591, -3.739005,  -8.388957,   0.184147, -1.554888,  3.786508,
 -1.684421,  5.400610,  -1.578126,   7.403361,  8.315999,  2.080267,
 11.077776,  2.749673,   7.138962,   2.748762,  0.660363,  0.981552,
  1.442275,  0.552721,  -2.576892,   4.703989,  0.989156,  8.759344,
 -0.564825, -3.994680,   0.954710,  -5.014144,  6.592329,  1.599488,
-13.979146, -0.391891,  -4.453369,  -2.311242, -2.948764,  1.761415,
-0.138322,  10.433007,  -2.309103,   4.297153,  8.535523,  3.209462,
 8.695819,   5.569919,   2.514304,   5.582029,  2.060199,  0.642280,
 7.024616,   1.686615,  -6.481756,   1.343084, -3.526451,  1.099073,
-2.965764,  -0.173723,  -4.111484,   6.528384, -6.965658,  1.726291,
 1.535172,  11.023435,   2.338401,  -4.690188,  1.298210,  3.943885,
 8.407885,   5.168365,   0.684131,   1.559181,  1.859998,  2.852417,
 8.574070,  -6.369078,   6.023458,  11.837963, -6.027632,  4.469678,
-6.799093,  -2.674048,   6.250367,  -6.809971, -3.459360,  9.112410,
-2.711621,  -1.336678,   1.564249,  -1.564297, -1.296760,  8.904013,
-3.230109,   6.878013,  -7.819823,   3.369909, -1.657410, -2.007358,
-4.112825,   1.370685,  -3.420525,  -6.276605,  3.244873, -3.352638,
 1.545372,   0.902211,   0.197489,  -1.408732,  0.523390,  0.348440
}; 
 
uint32_t srcALen = 64;         // Length of Input A
uint32_t srcBLen = 64;         // Length of Input B
uint32_t outLen;               // Length of convolution output
float32_t snr;                 // output SNR

const char TEST_FAILURE = 1;
const char TEST_SUCCESS = 0;

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

#define FACTOR 7
void ComplexMult_Q15(q15_t *pSrcA, q15_t *pSrcB, q15_t *pDst, uint32_t numSamples) {
  q15_t a, b, c, d;
  uint32_t blkCnt;

  blkCnt = numSamples;

  while(blkCnt > 0) {

    // C[2 * i] = A[2 * i] * B[2 * i] - A[2 * i + 1] * B[2 * i + 1]
    // C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i]
    a = *pSrcA++;
    b = *pSrcA++;
    c = *pSrcB++;
    d = *pSrcB++;

    // Store results in the destination buffer
    *pDst++ = (q15_t) ((((q31_t) a * c) - ((q31_t) b * d)) >> FACTOR);
    *pDst++ = (q15_t) ((((q31_t) a * d) + ((q31_t) b * c)) >> FACTOR);

    blkCnt--;
  }
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

// --------------------------------------------------------------------
// Calculation of SNR.
// Parameters:
//  *pRef         pointer to the reference buffer
//  *pTest        pointer to the test buffer
//   buffSize     total number of samples
// Returns:       SNR
// --------------------------------------------------------------------

float SNRCalc(float *pRef, float *pTest, uint32_t buffSize) {
  float EnergySignal = 0, EnergyError = 0;
  uint32_t i;
  float SNR;
  int temp;
  int *test;

  for (i = 0; i < buffSize; i++) {
    // Checking for a NAN value in pRef array
    test = (int *)(&pRef[i]);
    temp = *test;
    if(temp == 0x7FC00000) {
      return(0);
    }

    // Checking for a NAN value in pTest array
    test = (int *)(&pTest[i]);
    temp =  *test;
    if(temp == 0x7FC00000) {
      return(0);
    }
    EnergySignal += pRef[i] * pRef[i];
    EnergyError += (pRef[i] - pTest[i]) * (pRef[i] - pTest[i]);
  }

  // Checking for a NAN value in EnergyError
  test = (int *)(&EnergyError);
  temp = *test;
  if(temp == 0x7FC00000) {
    return(0);
  }
  SNR = 10 * log10 (EnergySignal / EnergyError);
  return (SNR);
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

void main() {
  char status;
  TFFT_Radix4_Instance cfft_instance;
  TFFT_Radix4_Instance *cfft_instance_ptr = (TFFT_Radix4_Instance*) &cfft_instance;
 
  // Set LED indicators
  GPIO_Digital_Output(&GPIOA_BASE, _GPIO_PINMASK_0 | _GPIO_PINMASK_4); // Set PORTA.0 and PORTA.4  as digital output
  GPIOA_ODR.B0 = 0;
  GPIOA_ODR.B4 = 0;

  // Output length of convolution
  outLen = srcALen + srcBLen - 1;

  // Convert input data from float to q15
  for(cnt = 0; cnt < 64; cnt++) {
    testInputA_q15[cnt] = Q15_Ftoi(testInputA_f32[cnt]/4);
    testInputB_q15[cnt] = Q15_Ftoi(testInputB_f32[cnt]/4);
  }

  // Initialize the FFT input buffers with all zeros
  Vector_Set16(Ak, FFT_BLOCKSIZE, 0);
  Vector_Set16(Bk, FFT_BLOCKSIZE, 0);

  // Copy the input values to the FFT input buffers */
  memcpy(Ak, testInputA_q15, FFT_BLOCKSIZE);
  memcpy(Bk, testInputB_q15, FFT_BLOCKSIZE);
  
  // Initialize the CFFT function to compute 64 point FFT
  status = FFT_Radix4_Init(cfft_instance_ptr, 64, 0, 1);
 
  // Transform input a[n] from time domain to frequency domain A[k]
  FFT_Radix4(cfft_instance_ptr, Ak);
  
  // Transform input b[n] from time domain to frequency domain B[k]
  FFT_Radix4(cfft_instance_ptr, Bk);

  // Complex Multiplication of the two input buffers in frequency domain
  ComplexMult_Q15(Ak, Bk, AxB_q15, FFT_BLOCKSIZE/2);
  
  // Initialize the CIFFT function to compute 64 point IFFT
  status = FFT_Radix4_Init(cfft_instance_ptr, 64, 1, 1);
 
  // Transform the multiplication output from frequency domain to time domain, that gives the convolved output
  FFT_Radix4(cfft_instance_ptr, AxB_q15);
  
  // Convert q15 result back to float
  for(cnt = 0; cnt < FFT_BLOCKSIZE; cnt++) {
    AxB_f32[cnt] = Q15_Itof(AxB_q15[cnt])*256;
  }

  // Classical CMSIS SNR test
  snr = SNRCalc((float32_t *)testRefOutput_f32, AxB_f32, srcALen + srcBLen - 1);
  if (snr < SNR_THRESHOLD) {
    status = TEST_FAILURE;
  }
  else {
    status = TEST_SUCCESS;
  }

  if( status != TEST_SUCCESS) {
    // Loop here if the signal does not match the reference output.
    GPIOA_ODR.B0 = 0;
    GPIOA_ODR.B4 = 1;
  }
  else {
    // Success
    GPIOA_ODR.B0 = 1;
    GPIOA_ODR.B4 = 1;
  }
}
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

Mucit23

Arkadaşlar hepnize teşekkür ederim.

@Ramu ve @Kantricinin verdiğin bilgiler sayesinde soru işaretleri kayboldu. Şimdi biraz matlab'da çalışmam lazım.

berat23

Alıntı yapılan: OptimusPrime - 31 Ocak 2014, 01:55:54
RaMu
fft ile dft aynı şey değiller. aynı şekilde dft ile dtft de aynı değiller.
matlab ın fft komutu fft işlemi yapmaz, dft işlemi yapar. help inden de görebilirsin.

fft, dft'yi hızlandıran bir algortima . sonuç olarak aynı şey, metod farklı ki burada arkadaşın istediği frekans spektrumu görmek ise dft de fft de aynı kapıya çıkar.dft ile dtft arasındaki fark fft ile dft arasındaki fark gibi değil, biri sonlu diğeri sonsuz. matlabın fft fonksiyonu ise gayet fft algoritmasıyla dft yapar , pekala fft'dir.

OptimusPrime

anlam karmaşasına doğru sürüklüyorusun olayı.

fft ve dft sonuç olarak aynı şey deyip aynı kefeye koyuyorsun daha sonra arasında bir fark olduğunu ortaya koyup dft ile dtft arasındaki gibi değil ama diyorsun. ne demek istediğini anlamadım.

neyse

fft bir algoritma değildir. dft nin bellirli özeliklerini kullarak (simetri gibi) hesaplamayı kolaylaştıran 1800 lü yıllarda bulunmuş bir yöntemdir. senin fft algoritması olarak bildiğin yöntem 2n noktalı dizinin dft sini alabilir ama 2n+1 i alamaz fakat srfft olarak bilinen başka bir yöntem ile alınabilir. bu hızlı hesaplama yöntemlerinin hepsine fft denir. dft nin belirli özelliklerini hesaplama işlemini kolaylaştırmak için kullanan algoritmalara da fft algoritması denir.

matlab de helpinde fft komutunu açıklarken, fft algoritmalarıyla dft işlemi yaparım der. fft işlemi yaparım demez çünki öyle bir işlem yoktur fft algoritmaları vardır. kullanıcının girdisi neye uygunsa çözüm için o algoritmayı kullanır.

yani RaMu nun yazdığı ve seninde tasdiklediğin gibi
FFT (veya DFT)
veya senin ifadenle
sonuç olarak aynı şey
değil.

sadece sonucu aynı. 4/2 ve 1x2 gibi...
https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||

Mucit23

Arkadaşlar Merhaba

FFT konusunda gerçekte bir iki deneme yapmam lazım. Band Sayısını 32'ye çıkardığımızı varsayalım.Bu durumda N değerimiz 32 olacak.
Max. Örnekleme frekansımız yine 16Khz olsun. Bu durumda FS değeri Yani örnekleme frekansımız X2 olacağı için min 32Khz olmakla birlikte ben 32.768Khz Yapmayı düşünüyorum.  Band sayısını 32'ye çıkardığım için min. 500Hz olmak üzere 500'er Hz aralıklarla fft alabilirim demektir. Buraya kadar sıkıntı yok.

Datasheet'te STM32F4 adc'si için 2.4MSPS yazıyor. Yani saniyede en fazla 2.4 milyon örnek alınabilir diyor. Ben bir şekilde Örnekleme Frekansını 32768Hz yapmak zorundayım. Bunun çalışmasını yapmadım henüz.

Sesin FFT'sini alırken yapmam gereken işlem sırası anladığım kadarıyla aşağıdaki gibi olacak.

1-) 32768Hz'de N kadar örnek al.
2-) Aldığın örnekleri FFT işlemine tut.
3-) Sonucu Ekrana bas.

Anlamadığım nokta şu. Bu yukarıdaki işlemler sürekli yapılacak. Peki Saniyede kaç defa bu işlemi yapmam gerekir? Bunun alt limiti nedir? Fazla olması veya az olması neyi değiştir?

Diğer bir yandan ST'nin kendi DSP library'si var. Bunlarda FFT Radix 2, FFT Radix 4 ve FFT Radix 8 gibi fonksiyonlar var. Bunlar arasındaki farklar nelerdir.

Ben Özellikle ST'nin Kendi DSP library'sini kullanmak istiyorum.


berat23

@OptimusPrime

anlam karmaşasını kullanan sizsiniz. farklı fft algortimalarının olması fft'nin olmadığı anlamına gelmez. fft ile dft'nin sonuçları aynıdır, dtft farklı birşey. siz analoji kurmuşsunuz, ben öyle birşey yok dedim, bu mu anlam karmaşası. neyse.

@Mucit23

fazla olması diye birşey yok. diyelim saniyede 8000 örnek alıyorsunuz, 8 uzunlulu fft için 8000/8 = 1000 hesaplama lazım, yani 1k ile fft yapmanız lazım. radix2,4 arasındaki fark algoritma. kıyaslaması için ufak bir google araması kafi;
http://www.gweep.net/~rocko/FFT/node5.html#SECTION00050000000000000000

Mucit23

#14
Merhaba

Matlabda çalıştıdığım kodları stm32f407'de denedim.

Yazdığım kodlar şöyle,
/**
  ******************************************************************************
  * @file    STM32F407 Test Yazilimi/main.c 
  * @author  Mucit23
  * @version V1.0.0
  * @date    03-Subat-2014
  * @brief   Main program body
  ******************************************************************************
  * @attention
  ******************************************************************************
  */
/* Includes ------------------------------------------------------------------*/
  #include "main.h"
	#include <stdio.h>
	#include "math.h"
/** @addtogroup 
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Bits definitions ----------------------------------------------------------*/
#define pi 3.1415926535 
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
   static __IO uint32_t TimingDelay;
	 uint16_t adc_val=0;
	 extern __IO uint16_t ADC3ConvertedValue;
	 char data[20];
	 //FFT Variables
	 
	 int N=32;
	 int input[32];
	 float Rk[32], Ik[32], output[32];
	 float deger=0, sonuc=0;
	 float cosdeger=0, sindeger=0;
	 float toplamIk=0;
	 float toplamRk=0;
	 int i=0, z=0, k=0;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

void delay_us(uint32_t delay_val);
int main()
{
	if (SysTick_Config(SystemCoreClock / 3119))//1ms 
  { 
    /* Capture error */ 
    while (1);
  }
	STM_EVAL_LEDInit(LED3);
  /* LCD Configuration */
  SSD1963_Init(); 
  /* ADC Configuration */ 	
  ADC3_CH12_DMA_Config();

	LCD_Clear(BLACK);
	LCD_SetFont(&Font8x8);
	LCD_SetColors(BLUE,BLACK);
	
	ADC_SoftwareStartConv(ADC3);
	while(1)
	{ 
    for(i=0;i<N;i++)
		{
      toplamRk = 0;
 			toplamIk = 0;
			for(z=0;z<N;z++)
			{
        deger=(2* pi *z*i)/N;
				input[z]=ADC3ConvertedValue;
				
				cosdeger=cos(deger);
				toplamRk=toplamRk + input[z] * cosdeger;
				Rk[i]=input[1] + toplamRk;
				
				sindeger=sin(deger);
				toplamIk = toplamIk - input[z] * sindeger;
				Ik[i] = toplamIk;
				delay_us(190);
      }
			sonuc = Rk[i] * Rk[i] + Ik[i] * Ik[i];
			sonuc = sqrt(sonuc);
      output[i] = log(sonuc);	
    }
    for(k=0;k<N;k++)
		{
       sprintf(data,"%02u.Deger=%f  ",k+1,output[k]);		
		   LCD_DisplayStringLine(0,k*8,data);
    }

 	}
}

/**
  * @brief  Inserts a delay time.
  * @param  nTime: specifies the delay time length, in milliseconds.
  * @retval None
  */
void Delay(__IO uint32_t nTime)
{ 
  TimingDelay = nTime;

  while(TimingDelay != 0);
}


void delay_us(uint32_t delay_val){
  uint32_t counter=0;
	for (counter=0;counter<delay_val;counter++)
	{

  }
}

/**
  * @brief  Decrements the TimingDelay variable.
  * @param  None
  * @retval None
  */
void TimingDelay_Decrement(void)
{
  if (TimingDelay != 0x00)
  { 
    TimingDelay--;
  }
}


#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif


ADC girişine şimdilik pot bağladım. Potu ise minimunda yani adc değeri 0 civarı birşey olmalı. Potun değerini arttırdığım zaman özellikle 1. değer çok artıyor.

Aldığım sonuç ise böyle oldu.

çoklu resim upload
Aslında tam olarak nasıl test edeceğimi bilmiyorum. Frekans jeneratörüm yok.

Ancak bilgisayarımın kulaklık çıkışından ses sinyali alıp stm32f407'nin ADC'sine bağlarsam eğer bilgisayarımdan istediğim frekansda sinyal yollayabilirim.

Bunu yapabilmem için Bilgisayar ile arasında nasıl bir bağlantı kurmam gerekir? Direk bağlanmaz herhalde.