Picproje Elektronik Sitesi

SERBEST BÖLGE => Programlama ve Algoritma => Konuyu başlatan: Mucit23 - 31 Ocak 2014, 00:08:32

Başlık: FFT dönüşümü hakkında
Gönderen: Mucit23 - 31 Ocak 2014, 00:08:32
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.

(http://s30.postimg.cc/bdxvtbqjx/Ekran_Al_nt_s.jpg) (http://postimg.cc/image/bdxvtbqjx/)

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.


Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: RaMu - 31 Ocak 2014, 00:36:07
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.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: kantirici - 31 Ocak 2014, 00:51:13
Ö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.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: 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.

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...
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: RaMu - 31 Ocak 2014, 03:09:52
OptimusPrime
Yanlış anlaşılmış olabilir biraz kötü yazmışım,
mesajı düzelttim.
Ama kantirici ile aynı şeyleri anlattım zaten.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: OptimusPrime - 31 Ocak 2014, 06:45:48
evet o kısmı atlarsak sende aynı şeyden bahsediyorsun. bende düzelteyim... ;D
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: mcn - 31 Ocak 2014, 07:58:54
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.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: yilmaz_kk - 31 Ocak 2014, 08:30:58
  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.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: mcn - 31 Ocak 2014, 08:47:17
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;
  }
}
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 31 Ocak 2014, 11:54:55
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.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: berat23 - 31 Ocak 2014, 16:33:57
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.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: OptimusPrime - 01 Şubat 2014, 04:12:45
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...
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 02 Şubat 2014, 23:55:01
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.

Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: berat23 - 03 Şubat 2014, 09:23:12
@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 (http://www.gweep.net/~rocko/FFT/node5.html#SECTION00050000000000000000)
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 04 Şubat 2014, 00:52:53
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.
(http://s25.postimg.cc/4pgc1v867/20140204_004042.jpg) (http://postimg.cc/)
çoklu resim upload (http://postimg.cc/index.php?lang=turkish)
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.


Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: camby - 04 Şubat 2014, 09:13:08
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 : )
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: berat23 - 04 Şubat 2014, 09:27:08
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.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 04 Şubat 2014, 09:29:43
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?
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 04 Şubat 2014, 17:18:46
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?
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: RaMu - 05 Şubat 2014, 00:06:03
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 (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.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: berat23 - 05 Şubat 2014, 09:31:59
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.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 05 Şubat 2014, 10:36:33
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 (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ış.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 07 Şubat 2014, 23:46:47
Kara düzen bir örnek yaptım. ADC'ye MP3 sinyali uyguluyorum.
(http://s25.postimg.cc/s4c90sjdr/20140207_233423.jpg) (http://postimg.cc/)
resim gönder (http://postimg.cc/index.php?lang=turkish)
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..
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: RaMu - 08 Şubat 2014, 01:31:41
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.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 08 Şubat 2014, 11:07:06
Benim öncelikle akıcı bir şekilde bargraphlar oluşturmam lazım.
Bazı örnekler,
FFT Audio Spectrum Analyser PIC32 QVGA LCD (http://www.youtube.com/watch?v=yoquqEL8OCc#ws)
Graphic audio spectrum analyzer (http://www.youtube.com/watch?v=h2-5Bvbpp8A#)

Nasıl yapıyorlar? Benim yanlış yaptığım konu nedir?
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 12 Şubat 2014, 22:04:33
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?
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: kantirici - 12 Şubat 2014, 22:58:06
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.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 12 Şubat 2014, 23:23:19
@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ı.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: mistek - 12 Şubat 2014, 23:27:19
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?
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 12 Şubat 2014, 23:44:52
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?
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: mistek - 13 Şubat 2014, 00:05:01
Stm32f1 serisi ile benzerdir belki örnek olması açısından

İlk olarak saat frekansı değiştirilecek. Siz en küçük bölme oranını kullanın. (2 oluyor sanırım)
RCC_ADCCLKConfig(RCC_PCLK2_Div4);   //ADCCLK = PCLK2/4;

Sonra şöyle bi fonksiyon varsa
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5);//Çevrime girecek kanal, sırası ve çevrim hızı

ADC_SampleTime_55Cycles5 kısmını değiştirin. Kütüphane içerisinde tanımlı olan en küçük olanı yazın.

RM0090 numaralı dokümanda 271. sayfada şu yazılmış.
Tconv = Sampling time + 12 cycles. Yani siz sample time belirledikten sonra üzerine 12clock daha koyacaksınız bu sizin çevrim sürenizi verecek. Örnekte var o sayfada.


f407 donanımını çok bilmediğim için çat pat bilgi yazabildim.

DMA ayarında bişey yok. ADC değerinin yazılacağı değişkeni 64 elemanlı dizi yapın. Hafıza adresini 1 artacak şekilde ayarlayın.

Yine f100 den örnek kod.


uint16_t ADC_dizisi[64] = {0,0};

DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; // Datanın alınacağı adres
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_dizisi; // Datanın yazılacağı adres
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // ADC kaynak. Veri yönü ADC->hafıza
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //Donanım adresi sabit kalacak
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //Hafıza adresi artacak
DMA_InitStructure.DMA_MemoryDataSize =DMA_MemoryDataSize_HalfWord;//Hafıza uzunluğu 16bit
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//Okunacak data uzunluğu 16bit
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//Çember modu
DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMA önceliği yüksek
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//Hafızadan hafızaya kayıt yok.
DMA_InitStructure.DMA_BufferSize = 64; // 64 eleman


Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: berat23 - 13 Şubat 2014, 09:15:13
bence dma kullanmayabilirsin. adc'den int. ile data alırsın(veya dma ile buffer'a doldur herneyse), bunları N uzunluklu bufferda kaydedersin. buffer dolduğunda bir sinyalle bunu belirtirsin. bu sinyali alan fft taskın bu verileri alır, hesaplama yapar. hesaplama bitince sonuçlandı diye bir sinyal daha çıkar. bu sinyali alan görüntüleme taskıda görüntüyü ekrana basar. toplamda 2 task ile bu işi halledebilirsin. bence önce tasklar nasıl konuşur ona bak.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: camby - 13 Şubat 2014, 09:35:43
Alıntı yapılan: berat23 - 13 Şubat 2014, 09:15:13
bence dma kullanmayabilirsin. adc'den int. ile data alırsın(veya dma ile buffer'a doldur herneyse)
INT ile veya benzeri yöntemle okuma zamanlama sorunlarının oluşmasına sebep olabilir.

Kesmelerin okumaların arasına başka fonksiyonlar daha yüksek öncelikli kesmeler vs girebilir.

En garanti yol ADC , DMA . DMA kesmesi geldiğinde iş bitmiş demektir.

ADC'yi full clock speed çalıştırmak istemiyorsanız , bu 2'liye Timer da ekleyebilirsiniz.

Timer'ın her dürtüsünde ADC alır , DMA yazar . N adet olunca DMA kesme verir. Bunları arka planda yapmanız önemli çünkü muhtemelen bir önceki alınan sinyalin de FFT'si alınıyor yada ekrana basılıyor olacak o sırada.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: berat23 - 13 Şubat 2014, 10:52:01
bu yorum rtos mantığına aykırı. işletim sisteminde zaten zamanlamayı sağlayacak yapılar vs. var, burada kullanılan işlemcide iç içe int. alma veya priority ayarlama gibi özellikler bunun için var. dma zamanlamayı garantiler diy birşy yok, dma int. da kaçabilir.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: camby - 13 Şubat 2014, 11:22:53
Alıntı yapılan: berat23 - 13 Şubat 2014, 10:52:01
bu yorum rtos mantığına aykırı.

Ben Rtos için yazmadım zaten, NO OS bir sistemde bu şekilde yapılabilir.

-----

ADC ölçümü yapıp sonucu yazdığında DMA bu veriyi alıp , ram'de başka bir yere yazıyor biliyorsunuz.

Yada ADC bu sonucu yazdığında INT üretiyor.

Eğer mevcut Interrupt'ı okuyamadan ( daha yüksek öncelikli işler yüzünden ) yeni interrupt gelirse aradaki veriyi kaybedersiniz ve 2 örnek orası 1us kabul ettiğimiz değer aslında 2us olur.

DMA ile yaptığımızda bu ihtimal ortadan kalkmış oluyor. Ve ADC verisi okuyup biyere yazmaya komut harcamıyoruz.

2 örnek arası nasıl olsa 1us , 1us 'de haydi haydi yetişiriz diyebilirsiniz ama bu durum program şiştikçe değişebilir. Öncelikli işleriniz daha fazla komut isteyebilir.

Yada 1MSPS örnek değilde LPC4370 ile 80MSPS ile örnek aldığımızı düşünelim. Bu durumda 2 INT arası süre 12,5ns ye kadar iner.

DMA kullanmadan bu veriyi yakalamaya çalışırsanız iş zor. Bir de işletim sistemi ile neler olur , onu hiç bilemiyorum.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 13 Şubat 2014, 11:24:53
Eğer DMA'nın bu tür yetenekleri var ise hiç timer kesmesiyle felan kendi programımı karıştırmak istemem.

Aslında anladığım kadarıyla sadece DMA+ADC ile olacak iş değil. Çünkü ADC örnekleme fekansını ayarlayamıyoruz. Bu yüzden timer kullanmak zorundayız. 
Aslında şurda güzel bir örnek buldum. Timer ile DMA tetikleniyor, DMA ise ADC den örnek alıp değişkene yazıyor.
http://www.wolinlabs.com/blog/stm32f4.adc.dsp.dac.html (http://www.wolinlabs.com/blog/stm32f4.adc.dsp.dac.html)

Şunu anlamıyorum. Diyelim timer işlemlerini felan hallettim. istediğim frekansta DMA yı tetikliyorum. Oda ADC den örnek alıyor bana

Hala şunu nasıl yapacağımı kestiremedim. 

Timerden her tetikleme geldiğinde DMA ADC yi alır benim 64 elemanlı bufferimin sıradaki elemanına yazar. Dizinin bütün elemanlarına yazıldığı zaman baştan başlıyacak. İşte ben bunu nasıl anlayacağımı bilmiyorum.

Diyelimki Ben bufferdeki elemanları alıp FFT'ye sokacağım. Fakat bir yandan timer dma adc koşuşturup benim bufferimdeki değerleri güncelliyor. Yani Bufferdeki değerler sürekli değişeceği için bufferin yarısı eski değer yarısı yeni değer olabilir.

Ben isterimki DMA bütün diziyi doldursun sonra bir flag'ı set edip beklesin. Ben FFT rutinin başında bu set edilen flag'a bakıp DMA işini bitirmişmi ona bakayım. Bitirmişse diziyi alıp flagı resetleyip Ben FFT ile uğraşırken tekrar DMA nın çalışmasına müsade edeyim. Yapmak istediğim tam olarak böyle birşey

@Klein hocamız şu konuyu biraz aydınlatsa valla çok iyi olurdu
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: camby - 13 Şubat 2014, 11:38:12
Mucit,

Basitlik açısından timer kullanma başlangıçta, sadece ADC_Prescaler_DivX değeri ile ADC nin sample sayısını datasheetteki hesaptan belirle. Ona göre FFT'ni hesapla.
Yani ADC hesaplanamıyor gibi bir durum yok, ben bu şekilde kullanıyorum , hesap tamamen Bus hızından ve datasheetteki adc ölçüm hesabından geliyor.

Diğer konu,

DMA modları var DMA_Mode_Normal veya DMA_Mode_Circular diye . DMA_Mode_Normal 'de iş bittiği zaman DMA kapanıyor. Yani şöyle diyeceksin 64 adet örnek al ve bana kesme üret. Kesme geldiğinde de artık istediğin işi yaparsın. Bülent hocanın ilk DMA örneklerinde de vardı bu.



mesaj birleştirme:: 13 Şubat 2014, 11:47:31

Bir ara konuşmuştuk  burada :

https://www.picproje.org/index.php/topic,45986.msg340626.html#msg340626 (https://www.picproje.org/index.php/topic,45986.msg340626.html#msg340626)

----

Hesap da Ref manuel 215. sayfada var :

Alıntı YapThe total conversion time is calculated as follows:
Tconv = Sampling time + 12 cycles
Example:
With ADCCLK = 38 MHz and sampling time = 3 cycles:
Tconv = 3 + 12 = 15 cycles = 0.5 μs with APB2 at 60 MHz

Yani sampling time 3 iken , 15 cycle de bir ölçüm yapılıyor.

Bus frekansı ile doğrudan çıkarabilirsin MSPS hızını.

Bus bölücü ile de hızı indirebilirsin. Yukarıdaki başlıkta konuştuğumuz ve ST'ye kızdığımız ise max hızın 60MHz 'lik bus hızında yakalanabiliyor olması. Halbuki bus 84MHz kullanılıyor.

Ama bunlar önemli ayrıntılar değil FFT geliştirmek için.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 13 Şubat 2014, 12:01:25
Anladım @camby teşekkürler, Akşam deemelere devam edeceğim.

Peki FFT için şunu sorayım. DMA, fifo modunda olsa, durum nasıl değişir.

Her ADC okunuşunda yeni bir eleman diziye eklenecek, Sondaki eleman silinecek. Yani dizideki elemanlar kayarak sürekli değişecek. Ben bu durumdaki iken herhangi bir zamanda dizinin FFT'sini alsam sonuç nasıl değişir. Gerçek bir sonuç elde edermiyim.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: camby - 13 Şubat 2014, 13:09:50
FFT nin çalışması açısından soruyorsan bilemiyorum, infinite ve finite fft versiyonları olabilir.

Ama yazılımsal yapılan bu işlem FFT'nin sonucunu etkiler.

Örneğin değeri 0 - 100 arası değişen bir sinüs örnekliyor ol. Sinüsün tepe değerinden buffer yazma sırası başa döndüğünde 100 ve 0 değeri yanyana olacak ve yüksek frekansta bir pik göreceksin FFT'den. Fakat aslında böyle bir durum yok , sadece sinüs frekansında tek bir bileşenimizin olması lazım.

Kayıt yapılan buffer da FIFO olursa böyle bir durum kalmaz aslında. Yeni gelen data baştan girer , sonunca sondan çıkar , her okuma yapıldığında en güncel N adet veri olur.

DMA_FIFOMode diye bir opsiyon da var , kullanmadım ama belki buna yarıyor olabilir.

Ama şu an için : ADC+DMA kur , her DMA kesmesinde FFT al , FFT bitince tekrar ADC+DMA kur gibi bir sıralı yapı kullanabilirsin.

STM DSP libraryleri içinde hazır yazılmış örnekler var , birkaç çeşit vardı sanırım , bu örnekler hazır sinyal dizilerinden çalışıyor , görmüşsündür sende , bu dizileri kullarak ADC+DMA karıştırmadan başlanabilir aslında.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: bocek - 13 Şubat 2014, 16:48:02
mucit şurda tam sana göre bir örnek var:

http://projectproto.blogspot.com.tr/2010/06/mini-stm32-wave-audio-player.html (http://projectproto.blogspot.com.tr/2010/06/mini-stm32-wave-audio-player.html)

CoOS kullanarak bir yandan led yakıp söndürürken bir yandan da wav dosyası çalıp spectrum grafiğini ekrana basıyor.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 13 Şubat 2014, 17:39:41
Biliyorum hocam o projeyi, Aslında bi ara dedim oradaki FFT kodlarını kullanayım dedim ama mantığını anlamadım. Tek bir fonksiyon yok. CoOS'u zaten oradan alıntıladım...
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 15 Şubat 2014, 00:27:51
FFT ve örnek alma işlemini hallettiğimi düşünüyorum. Bundan sonra biraz görselliğe ağırlık vereceğim. Tahiminimce bargraph çizimi konusunda master yapmam gerekecek.

Görüntüyü yumuşatmak için aşağıya düşüşleri yavaşlatmak gerekiyor. Yani FFT sonucunda elde edilen peak değerine kadar bargraph dolacak, Boşalırken ise belli bir hızda inmesi gerekiyor.

Benim şuan yaptığım işlem fft sonucunda elde edilen peak değerine kadar barı'doldurup, geri kalan kısımları boşaltıyorum. Dolayısıyla çok keskin oluyor.

Bu bahsettğim işlemi  nasıl yaparım? Fikri olan varmı?
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: mistek - 15 Şubat 2014, 00:51:35
Program nasıl işliyor bilmiyorum ama şöyle bişey olabilir.

En tepe değerden aşağıya doğru döngü boyunca birer birer azalarak insin eğer yeni veri gelirse yine sıfırlanıp en tepeden aşağı doğru insin. Program zaten yavaş akıyorsa kendi halinde bi süzülme gibi görünecektir diye düşünüyorum.

Mesela 100 tepe değerse sonraki FFT çevrime kadar ana döngüde
99 göster
98 göster
97 göster

Değerlere göre birer birer değilde 3-5 gibide olabilir.



Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: z - 15 Şubat 2014, 02:41:22
FFT sonucunda n tane frekansin genligini buldun diyelim.

Bu noktadan sonra elektronik dusun.

Bu gerilimlerin her birini ayri ayri diyodlarla dogrultup kapasitorlere ve paralelindeki direnclere verdigini dusun.

Bu durumda kapasitor uclarindaki gerilim, yeni fft genliklerinden daha dusukse kapasitor voltajini yeni degere set et.

Aksi durumda kapasitor voltajini direnc etkisiyle yavas yavas dusur.

Bu olayi yazilimla yapacaksin.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 15 Şubat 2014, 11:08:52
Teşekkürler, Birşeyler canlandı aklımda. Biraz çalışmam gerekiyor.

Birşey sorayım

LCD arayüzü için EMWIN tarzı bir sistem gömsem nasıl olur?
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 17 Şubat 2014, 23:30:58
Anladığım kadarıyla daha yemem gereken 2 fırın ekmek var.
Son haliyle böyle
Stm32f407 FFT Test (http://www.youtube.com/watch?v=4mzJZVBUZ2E#ws)
ADC örnekleme işin oturttum rayına. Bargraph işinide şimdilik geçtim, Ona sonra bakacam. Benim FFT rutinlerimde problem var. İlk önce bu kısmı problemsiz bir şekilde çalıştırmam gerek.

ADC örnekleme frekansım 22Khz dolayısıyla 11Khz ye kadar ölçebilmem lazım. Videoda 100Hz ile 11Khz çıkıp tekrar 100hz iniyorum. Bilgisayarın direk kulaklık jakından sinyal aldığım için hoperlorlerden ses gelmiyor.

Videoda göreceğiniz üzere sadece ilk 16 band çalışıyor. FFT rutinlerine pek karışmadım. Buradaki uygulamadaki kodları kullanıyorum.
http://www.waitingforfriday.com/index.php/Real-Time_Audio_Spectrum_Analyser (http://www.waitingforfriday.com/index.php/Real-Time_Audio_Spectrum_Analyser)

Bu konu üzerinde araştırma yapıyorum. Benim asıl problemim FFT sonucunun çok hareketli olması. Videoda çok net anlaşılıyor.
Şuanda bütün örnek alma FFT ve Bargraph rutinleri toplamda 5.5ms den az sürüyor. Yani FPS değeri 180 civarında. Çok yüksek bir değer. Bunu delay koyarak yavaşlatabilirim ama FFT sonucunun değişken olmasına çözüm olmaz. Bunu çözemiyorum bir türlü.

Fikri olan varmı Neden böyle olabilir? 
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 18 Şubat 2014, 08:42:26
Arkadaşlar 2. Problem hakkında fikri olan varmı?  Örneğin 1khz sabit frekans uygulasam ve bu frekansı temsil eden bandın değeri neden sürekli olarak değişir.

Birde FPS konusu var.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: sadogan - 18 Şubat 2014, 09:38:16
Verdiğiniz linkteki spekturm un *.hex dosyası varmı bende c18 olmadığından derleyemedim.
İsis te simüle etmek istiyorum.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 18 Şubat 2014, 09:40:59
Yok bendede yok.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: superconductor - 18 Şubat 2014, 11:27:16
Hocam bucked degerlerini direk barlara gondermek yerine birkac ornegin ortalamasini alarak gonder cozulur. Barlar duserken yavas dussun diyede birseyler yapabilirsin.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: z - 18 Şubat 2014, 12:03:12
Alıntı yapılan: Mucit23 - 18 Şubat 2014, 08:42:26
Arkadaşlar 2. Problem hakkında fikri olan varmı?  Örneğin 1khz sabit frekans uygulasam ve bu frekansı temsil eden bandın değeri neden sürekli olarak değişir.

Birde FPS konusu var.


Genel olarak aklıma gelenler:

Rutinlerde her hesaplama başlangıcında sıfırlanması vs gereken değerler sıfırlanmıyordur/ ilk değer atanmıyordur.
Fix point hesaplama yapıldıysa overflow durumları kontrol edilmemiştir. (Belki orjinal rutinler 8 bit içindir ama sen 10 bit için kullanıyorsundur.)
Sample alma süresi değişkendir.
Belki ADC rutini sorunludur.

Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 18 Şubat 2014, 12:11:41
Sample alma süresi sabit hocam. Kesinlikle eminim. Direk osiloskopla ölçüyorum çünkü.

Ben dediğim gibi FFT fonksiyonunda problem olduğunu düşünüyorum. Çünkü Orjinal devrede 10bit ADC var. Ben ise 12Bit ADC kullanıyorum, OverFlow problemleri olabilir.

İlk başta ADC bufferinden değerleri alırken sanal değerleri sıfırlıyorum.

Yazdığım kodlar bunlar.

/* Includes ------------------------------------------------------------------*/
  #include "main.h"
/** @addtogroup
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Bits definitions ----------------------------------------------------------*/
#define pi 3.1415926535
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
   static __IO uint32_t TimingDelay;
extern __IO uint16_t ADC3ConvertedValue[64];
extern __IO uint8_t ADC_Ready_Flag;
uint16_t dizi[32];
char data[20];
uint8_t value=0;
//FFT Variables
   short imaginaryNumbers[64];
   short realNumbers[64];
int i=0, k=0, z=0, place=0, root=0;

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

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

LCD_Clear(BLACK);
LCD_SetFont(&Font8x8);
LCD_SetColors(GREEN,BLACK);
//ADC_SoftwareStartConv(ADC3);
       //old bargraph function 1.840ms     

while(1)
{
if(ADC_Ready_Flag)
{
   for(i=0;i<64;i++)
   {
    realNumbers[i]=ADC3ConvertedValue[i]-2048;
    imaginaryNumbers[i]=0;
   }
ADC_Ready_Flag=0;

fix_fft(realNumbers, imaginaryNumbers, 6);

     for (k=0; k < 32; k++)
     {
        realNumbers[k] = (realNumbers[k] * realNumbers[k] +
                   imaginaryNumbers[k] * imaginaryNumbers[k]);
       
            place = 0x40000000;
      root = 0;

if (realNumbers[k] >= 0) // Ensure we don't have a negative number
{
while (place > realNumbers[k]) place = place >> 2;

while (place) 

if (realNumbers[k] >= root + place) 

realNumbers[k] -= root + place; 
root += place * 2; 

root = root >> 1; 
place = place >> 2; 
}
}
realNumbers[k] = root;
   }
}
   
    //LCD_DrawBargraph parameter (Xpos, Ypos, Widh, Height, Value)
      LCD_DrawBargraph(0,100,3,172,realNumbers[0]);
    LCD_DrawBargraph(15,100,3,172,realNumbers[1]);
    LCD_DrawBargraph(30,100,3,172,realNumbers[2]);
      LCD_DrawBargraph(45,100,3,172,realNumbers[3]);
    LCD_DrawBargraph(60,100,3,172,realNumbers[4]);
    LCD_DrawBargraph(75,100,3,172,realNumbers[5]);
      LCD_DrawBargraph(90,100,3,172,realNumbers[6]);
    LCD_DrawBargraph(105,100,3,172,realNumbers[7]);
    LCD_DrawBargraph(120,100,3,172,realNumbers[8]);
      LCD_DrawBargraph(135,100,3,172,realNumbers[10]);
    LCD_DrawBargraph(150,100,3,172,realNumbers[11]);
    LCD_DrawBargraph(165,100,3,172,realNumbers[12]);
      LCD_DrawBargraph(180,100,3,172,realNumbers[13]);
    LCD_DrawBargraph(195,100,3,172,realNumbers[14]);
    LCD_DrawBargraph(210,100,3,172,realNumbers[15]);
      LCD_DrawBargraph(225,100,3,172,realNumbers[16]);
    LCD_DrawBargraph(240,100,3,172,realNumbers[17]);
    LCD_DrawBargraph(255,100,3,172,realNumbers[18]);
      LCD_DrawBargraph(270,100,3,172,realNumbers[19]);
    LCD_DrawBargraph(285,100,3,172,realNumbers[20]);
    LCD_DrawBargraph(300,100,3,172,realNumbers[21]);
      LCD_DrawBargraph(315,100,3,172,realNumbers[22]);
    LCD_DrawBargraph(330,100,3,172,realNumbers[23]);
    LCD_DrawBargraph(345,100,3,172,realNumbers[24]);
      LCD_DrawBargraph(360,100,3,172,realNumbers[25]);
    LCD_DrawBargraph(375,100,3,172,realNumbers[26]);
    LCD_DrawBargraph(390,100,3,172,realNumbers[27]);
      LCD_DrawBargraph(405,100,3,172,realNumbers[28]);
    LCD_DrawBargraph(420,100,3,172,realNumbers[29]);
    LCD_DrawBargraph(435,100,3,172,realNumbers[30]);
      LCD_DrawBargraph(450,100,3,172,realNumbers[31]);
//Delay(10);//10ms Delay..
}
}


/**
  * @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);
}

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



Aslında ADCyi 10bit yapmayı hiç denemedim. Akşam deneyelim. Bakalım ne olacak.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: SpeedyX - 18 Şubat 2014, 13:32:56
Gözüme takıldığı için yazıyorum,

realNumbers[9] unutulmuş. 1 bar kayma var.

GLCD kısmını şöyle de yapabilirsin;
for(i = 0; i < 32; i++)
{
LCD_DrawBargraph(i*15,100,3,172,realNumbers[i]);
}
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 18 Şubat 2014, 14:11:17
İlk başlarda bargraph fonksiyonu sıkıntılıydı hocam. Ozaman böyle ard arda yazma ihityacı bulmuştum. Bir tanesini atlamışım...

Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 18 Şubat 2014, 22:35:22
ADC yi 10 bit yapıp denedim. Sonuç birazdaha iyi, En azından daha sakin bir şekilde çalışıyor. Demekki overflow durumları oluşuyor. Bu sizce nerede olabilir?
FFT Kütüphanesi budur
/************************************************************************
fft.c

    FFT Audio Analysis
    Copyright (C) 2011 Simon Inns

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

Email: simon.inns@gmail.com

************************************************************************/
#ifndef FFT_C
#define FFT_C

#include "stm32f4xx.h"
#include "fft.h"

// fix_fft.c - Fixed-point in-place Fast Fourier Transform

// All data are fixed-point short integers, in which -32768
// to +32768 represent -1.0 to +1.0 respectively. Integer
// arithmetic is used for speed, instead of the more natural
// floating-point.
//
// For the forward FFT (time -> freq), fixed scaling is
// performed to prevent arithmetic overflow, and to map a 0dB
// sine/cosine wave (i.e. amplitude = 32767) to two -6dB freq
// coefficients.
//
// Written by:  Tom Roberts  11/8/89
// Made portable:  Malcolm Slaney 12/15/94 malcolm@interval.com
// Enhanced:  Dimitrios P. Bouras  14 Jun 2006 dbouras@ieee.org
// Ported to PIC18F:  Simon Inns 20110104

/*
  fix_fft() - perform forward fast Fourier transform.
  fr[n],fi[n] are real and imaginary arrays, both INPUT AND
  RESULT (in-place FFT), with 0 <= n < 2**m
*/

// Since we only use 3/4 of N_WAVE, we define only
// this many samples, in order to conserve data space.
const short Sinewave[N_WAVE-N_WAVE/4] = {
      0,    201,    402,    603,    804,   1005,   1206,   1406,
   1607,   1808,   2009,   2209,   2410,   2610,   2811,   3011,
   3211,   3411,   3611,   3811,   4011,   4210,   4409,   4608,
   4807,   5006,   5205,   5403,   5601,   5799,   5997,   6195,
   6392,   6589,   6786,   6982,   7179,   7375,   7571,   7766,
   7961,   8156,   8351,   8545,   8739,   8932,   9126,   9319,
   9511,   9703,   9895,  10087,  10278,  10469,  10659,  10849,
  11038,  11227,  11416,  11604,  11792,  11980,  12166,  12353,
  12539,  12724,  12909,  13094,  13278,  13462,  13645,  13827,
  14009,  14191,  14372,  14552,  14732,  14911,  15090,  15268,
  15446,  15623,  15799,  15975,  16150,  16325,  16499,  16672,
  16845,  17017,  17189,  17360,  17530,  17699,  17868,  18036,
  18204,  18371,  18537,  18702,  18867,  19031,  19194,  19357,
  19519,  19680,  19840,  20000,  20159,  20317,  20474,  20631,
  20787,  20942,  21096,  21249,  21402,  21554,  21705,  21855,
  22004,  22153,  22301,  22448,  22594,  22739,  22883,  23027,
  23169,  23311,  23452,  23592,  23731,  23869,  24006,  24143,
  24278,  24413,  24546,  24679,  24811,  24942,  25072,  25201,
  25329,  25456,  25582,  25707,  25831,  25954,  26077,  26198,
  26318,  26437,  26556,  26673,  26789,  26905,  27019,  27132,
  27244,  27355,  27466,  27575,  27683,  27790,  27896,  28001,
  28105,  28208,  28309,  28410,  28510,  28608,  28706,  28802,
  28897,  28992,  29085,  29177,  29268,  29358,  29446,  29534,
  29621,  29706,  29790,  29873,  29955,  30036,  30116,  30195,
  30272,  30349,  30424,  30498,  30571,  30643,  30713,  30783,
  30851,  30918,  30984,  31049,  31113,  31175,  31236,  31297,
  31356,  31413,  31470,  31525,  31580,  31633,  31684,  31735,
  31785,  31833,  31880,  31926,  31970,  32014,  32056,  32097,
  32137,  32176,  32213,  32249,  32284,  32318,  32350,  32382,
  32412,  32441,  32468,  32495,  32520,  32544,  32567,  32588,
  32609,  32628,  32646,  32662,  32678,  32692,  32705,  32717,
  32727,  32736,  32744,  32751,  32757,  32761,  32764,  32766,
  32767,  32766,  32764,  32761,  32757,  32751,  32744,  32736,
  32727,  32717,  32705,  32692,  32678,  32662,  32646,  32628,
  32609,  32588,  32567,  32544,  32520,  32495,  32468,  32441,
  32412,  32382,  32350,  32318,  32284,  32249,  32213,  32176,
  32137,  32097,  32056,  32014,  31970,  31926,  31880,  31833,
  31785,  31735,  31684,  31633,  31580,  31525,  31470,  31413,
  31356,  31297,  31236,  31175,  31113,  31049,  30984,  30918,
  30851,  30783,  30713,  30643,  30571,  30498,  30424,  30349,
  30272,  30195,  30116,  30036,  29955,  29873,  29790,  29706,
  29621,  29534,  29446,  29358,  29268,  29177,  29085,  28992,
  28897,  28802,  28706,  28608,  28510,  28410,  28309,  28208,
  28105,  28001,  27896,  27790,  27683,  27575,  27466,  27355,
  27244,  27132,  27019,  26905,  26789,  26673,  26556,  26437,
  26318,  26198,  26077,  25954,  25831,  25707,  25582,  25456,
  25329,  25201,  25072,  24942,  24811,  24679,  24546,  24413,
  24278,  24143,  24006,  23869,  23731,  23592,  23452,  23311,
  23169,  23027,  22883,  22739,  22594,  22448,  22301,  22153,
  22004,  21855,  21705,  21554,  21402,  21249,  21096,  20942,
  20787,  20631,  20474,  20317,  20159,  20000,  19840,  19680,
  19519,  19357,  19194,  19031,  18867,  18702,  18537,  18371,
  18204,  18036,  17868,  17699,  17530,  17360,  17189,  17017,
  16845,  16672,  16499,  16325,  16150,  15975,  15799,  15623,
  15446,  15268,  15090,  14911,  14732,  14552,  14372,  14191,
  14009,  13827,  13645,  13462,  13278,  13094,  12909,  12724,
  12539,  12353,  12166,  11980,  11792,  11604,  11416,  11227,
  11038,  10849,  10659,  10469,  10278,  10087,   9895,   9703,
   9511,   9319,   9126,   8932,   8739,   8545,   8351,   8156,
   7961,   7766,   7571,   7375,   7179,   6982,   6786,   6589,
   6392,   6195,   5997,   5799,   5601,   5403,   5205,   5006,
   4807,   4608,   4409,   4210,   4011,   3811,   3611,   3411,
   3211,   3011,   2811,   2610,   2410,   2209,   2009,   1808,
   1607,   1406,   1206,   1005,    804,    603,    402,    201,
      0,   -201,   -402,   -603,   -804,  -1005,  -1206,  -1406,
  -1607,  -1808,  -2009,  -2209,  -2410,  -2610,  -2811,  -3011,
  -3211,  -3411,  -3611,  -3811,  -4011,  -4210,  -4409,  -4608,
  -4807,  -5006,  -5205,  -5403,  -5601,  -5799,  -5997,  -6195,
  -6392,  -6589,  -6786,  -6982,  -7179,  -7375,  -7571,  -7766,
  -7961,  -8156,  -8351,  -8545,  -8739,  -8932,  -9126,  -9319,
  -9511,  -9703,  -9895, -10087, -10278, -10469, -10659, -10849,
-11038, -11227, -11416, -11604, -11792, -11980, -12166, -12353,
-12539, -12724, -12909, -13094, -13278, -13462, -13645, -13827,
-14009, -14191, -14372, -14552, -14732, -14911, -15090, -15268,
-15446, -15623, -15799, -15975, -16150, -16325, -16499, -16672,
-16845, -17017, -17189, -17360, -17530, -17699, -17868, -18036,
-18204, -18371, -18537, -18702, -18867, -19031, -19194, -19357,
-19519, -19680, -19840, -20000, -20159, -20317, -20474, -20631,
-20787, -20942, -21096, -21249, -21402, -21554, -21705, -21855,
-22004, -22153, -22301, -22448, -22594, -22739, -22883, -23027,
-23169, -23311, -23452, -23592, -23731, -23869, -24006, -24143,
-24278, -24413, -24546, -24679, -24811, -24942, -25072, -25201,
-25329, -25456, -25582, -25707, -25831, -25954, -26077, -26198,
-26318, -26437, -26556, -26673, -26789, -26905, -27019, -27132,
-27244, -27355, -27466, -27575, -27683, -27790, -27896, -28001,
-28105, -28208, -28309, -28410, -28510, -28608, -28706, -28802,
-28897, -28992, -29085, -29177, -29268, -29358, -29446, -29534,
-29621, -29706, -29790, -29873, -29955, -30036, -30116, -30195,
-30272, -30349, -30424, -30498, -30571, -30643, -30713, -30783,
-30851, -30918, -30984, -31049, -31113, -31175, -31236, -31297,
-31356, -31413, -31470, -31525, -31580, -31633, -31684, -31735,
-31785, -31833, -31880, -31926, -31970, -32014, -32056, -32097,
-32137, -32176, -32213, -32249, -32284, -32318, -32350, -32382,
-32412, -32441, -32468, -32495, -32520, -32544, -32567, -32588,
-32609, -32628, -32646, -32662, -32678, -32692, -32705, -32717,
-32727, -32736, -32744, -32751, -32757, -32761, -32764, -32766,
};

void fix_fft(short fr[], short fi[], short m)
{
int mr = 0, nn, i, j, l, k, istep, n;
short qr, qi, tr, ti, wr, wi;

n = 1 << m;
nn = n - 1;

/* max FFT size = N_WAVE */
//if (n > N_WAVE) return -1;

/* decimation in time - re-order data */
for (m=1; m<=nn; ++m)
{
l = n;
do
{
l >>= 1;
} while (mr+l > nn);

mr = (mr & (l-1)) + l;
if (mr <= m) continue;

tr = fr[m];
fr[m] = fr[mr];
fr[mr] = tr;
ti = fi[m];
fi[m] = fi[mr];
fi[mr] = ti;
}

l = 1;
k = LOG2_N_WAVE-1;

while (l < n)
{
/*
  fixed scaling, for proper normalization --
  there will be log2(n) passes, so this results
  in an overall factor of 1/n, distributed to
  maximize arithmetic accuracy.

  It may not be obvious, but the shift will be
  performed on each data point exactly once,
  during this pass.
*/

// Variables for multiplication code
long int c;
short b;

istep = l << 1;
for (m=0; m<l; ++m)
{
j = m << k;
/* 0 <= j < N_WAVE/2 */
wr =  Sinewave[j+N_WAVE/4];
wi = -Sinewave[j];

wr >>= 1;
wi >>= 1;

for (i=m; i<n; i+=istep)
{
j = i + l;

// Here I unrolled the multiplications to prevent overhead
// for procedural calls (we don't need to be clever about
// the actual multiplications since the pic has an onboard
// 8x8 multiplier in the ALU):

// tr = FIX_MPY(wr,fr[j]) - FIX_MPY(wi,fi[j]);
c = ((long int)wr * (long int)fr[j]);
c = c >> 14;
b = c & 0x01;
tr = (c >> 1) + b;

c = ((long int)wi * (long int)fi[j]);
c = c >> 14;
b = c & 0x01;
tr = tr - ((c >> 1) + b);

// ti = FIX_MPY(wr,fi[j]) + FIX_MPY(wi,fr[j]);
c = ((long int)wr * (long int)fi[j]);
c = c >> 14;
b = c & 0x01;
ti = (c >> 1) + b;

c = ((long int)wi * (long int)fr[j]);
c = c >> 14;
b = c & 0x01;
ti = ti + ((c >> 1) + b);

qr = fr[i];
qi = fi[i];
qr >>= 1;
qi >>= 1;

fr[j] = qr - tr;
fi[j] = qi - ti;
fr[i] = qr + tr;
fi[i] = qi + ti;
}
}

--k;
l = istep;
}
}

#endif


FFT fonksiyonunda M parametresi var. Fonksiyon kullanılırken sabit 6 değeri gönderiliyor. Bu nedir sizce
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: z - 18 Şubat 2014, 22:44:07
realNumbers=ADC3ConvertedValue-2048;

bu gibi ifadeleri 10 bit icin duzelt. Ama bu zaten 12 bit icin yazilmis gorunuyor.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 18 Şubat 2014, 23:01:59
Hocam yok 10Bit Testlerinde onları zaten düzeltmiştim. O işlemi 12 bit ADC için yapıyorum.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: superconductor - 19 Şubat 2014, 00:11:28
O parametre fft fonksiyonuna gonderecegin dizi eleman sayisinin 2 tabanindaki logaritmasi hocam.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 19 Şubat 2014, 00:19:43
Yarım yamalakta olsa kütüphane bir şekilde çalışıyor, fakat ben hiç memnun değilim.
http://www.waitingforfriday.com/index.php/Real-Time_Audio_Spectrum_Analyser (http://www.waitingforfriday.com/index.php/Real-Time_Audio_Spectrum_Analyser)
Hocam bu uygulamayı yapan adama mail attım 12Bit ADC için durumu anlattım.  Adam bana bu kodlar 10 bit ADC  sinyalini işlemek için tasarlanmış diyor. Bana Fast Hardley Transformu öneriyor. Biraz daha farklı bir konu.

@superconductor, Hocam siz kendi çalışmalarınızdan FFT ile ilgili rutinlerinizi paylaşmanız mümkünmü?

Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: superconductor - 19 Şubat 2014, 01:21:38
Pc ye gecince paylasayim hocam. Ben bahsettigin ayni frekans ve genlikte sinyal uygulandiginda olusan dalgalanmayi, bar degerlerini low-pass filtreye sokarak kismen cozdum. Anladigim kadari ile bu algoritmayi yazan arkadas pic4550 de rahat calissin diye baya optimize etmis. Dikkat ettiysen kendi uygulamasida aslinda cok iyi calismiyor. Ozellikle iki kesim frekansi arasinda kalan bir sinyal uygulaninca cevredeki barlarda dalgalanma yapiyor. Iki uc harmonikle denedigimde bu olay daha cok belli oldu. Ben dma ile adc degerlerini diziye atiyorum 64 eleman dolunca o diziyi fft islemine sokuyorum. Bu sirada dma bir sonraki fft islemi icin diziye adc degerlerini kopyaliyor. Simdi aklima geldi bir hatami buldum. Fft islemi daha bitemeden dma dizinin ilk elemanlarini degistiriyor olabilir bakmak lazim. Bunun onune iki tane buffer kullanilarak gecilebilir. Dsp library kullanmayi bir turlu cozemedim  onun uzerine gitmek lazim diye dusunuyorum bol ornek var fft icin.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 19 Şubat 2014, 01:31:49
Hocam ben o dediginiz problemi yaşamamak icin iki adet buffer kullandım.  Dma işini bitirince FFT islemine başlamam için start sinyali geliyor. Bende hemen bufferdeki degerleri ikinci buffere taşıyıp fft işlemine giriyorum.

Dediginiz gibi kodlar cok fazla optimize edilmiş.  Bahsettiğiniz problem şuanda bende de var.Bu yuzden dsp library kullanmam gerekiyor. En sağlamı böyle.

Bir iki makale buldum. Bakalım yarın bu konularda biraz çalışmayı düşünüyorum.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: OptimusPrime - 19 Şubat 2014, 01:36:08
Mucit23

son eklediğin video da en soldaki değer dc bileşen mi???
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 19 Şubat 2014, 10:27:27
Evet hocam, 0. değer DC bileşen olması lazım.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: OptimusPrime - 19 Şubat 2014, 23:13:03
kulaklık çıkışında dc bileşen yoktur dolayısı ile ya örnekleri pencerelemeden fft alıyorsun yada fft yi yanlış olıyorsun yada ikisinde de sorun var...
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 19 Şubat 2014, 23:15:47
Hocam, ADC değerini olduğu gibi FFT rutinine yolluyorum. Pencereleme dediğiniz olay nedir?
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: OptimusPrime - 19 Şubat 2014, 23:44:44
http://en.wikipedia.org/wiki/Window_function (http://en.wikipedia.org/wiki/Window_function)

hanning veya hamming yapabilirsin...
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 19 Şubat 2014, 23:47:31
Desene işimiz var...  :o :o
Başa gelen çekilir... Devam  :-X

mesaj birleştirme:: 20 Şubat 2014, 00:13:06

Proje Dosyamda CMSIS içerisinde DSP_Lib bulunmakta.
DSP Lib içerisinde birçok kütüphane var. Ben Target Optinous, C++ Sekmesinde derlenmesi için DSP_Lib klasörünü keile tanıttım.

Bundan sonra istediğim fonksiyonları kullanabilmem için ne yapmam gerekir. Burada tıkanıyorum.
Mesela burada bir kod parçacığı buldum
https://github.com/nabilt/STM32F4-Discovery-Firmware/blob/master/Libraries/CMSIS/DSP_Lib/Examples/arm_fft_bin_example/arm_fft_bin_example_f32.c

Kulanılan fonksiyonlar sırasıyla arm_cfft_radix4_init_f32(), arm_cfft_radix4_f32(), arm_cmplx_mag_f32(), arm_max_f32()

Bu kodları bende denemek istiyorum. Kendi projemde kullanabilmem için ne yapmam gerekiyor? Özellikle proje ağacına nasıl bir ekleme yapmam gerekiyor bunu merak ediyorum.
Yardım ederseniz sevinirim..
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: berat23 - 20 Şubat 2014, 09:00:50
real time fft o kadar basit birşey değil, gördüğüm kadarıyla temeliniz de yok. bence önce biraz işin teorisini çalışın, window function vs., kodlama kolay işler.

window function olarakta normal bufferlasanız veriyi rectangle window olur, frekans tepkisi sizin için önemli olmadığından rectangle durumu kurtarır, hatta bu aslında stft olur ye neyse, dediğim gibi biraz teorisine bakın(hatta baya bakın).
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 20 Şubat 2014, 09:56:53
Doğrudur Hocam Temelim zayıf, Ama ilk çalışmalarımı matlabda yaptım. Burada FFT fonksiyonu nedir, Nasıl çalışır gibi soruların cevabını buldum. Yani temel seviyede bilgim var.
Matlabdaki kodları olduğu gibi STM32'ye taşıyınca çok ağır çalıştığını gördüm.  Sqrt, Sin, Cos ve Log gibi fonksiyonlardan dolayı. Bu yüzden Hazır kütüphane kovalamaya başladım.

Aslında şuan kullandığım kodlar 10bit ADC de çok iyi çalışıyor. 12 bit ADC'de ise giriş hassasiyetleştiği için okunana değerler çok oynak oluyor. Ben okunun değerleri direk FFT'ye tabi tuttuğum için sonuçta epeyce hareketli oluyor. Bence Overflow durumları olmuyor. FFT fonksiyonun içindeki bütün değişkenler 16 bit işaretli tam sayı.

Bu sorun @OptimusPrime'nın söylediği pencereleme meselesi olabilir.

ADC çözünürlüğünü 10Bit yaptığımda DC bileşende görünmüyor. Sanırım hassasiyet düşüyor ondan.

Ben dediğiniz gibi Şu Window_Function konularını araştırayım şimdilik ama bu sırada keil'deki DSP_Lib problemimi çözmem gerekiyor. DSP_Lib'de istediğim fonksiyonları mainde kulanabilmem için ne yapmam gerekir. Birisi kısaca anlatsa çok güzel olur.
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 20 Şubat 2014, 21:13:38
Kimsenin fikri yikmu?
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: Mucit23 - 21 Şubat 2014, 23:35:58
İki gündür şu DSP'library konusunda araştırma yapıyorum. Birşey öğrendim deneme yapmam lazım ama Keil yine önüme taş koydu.

aşağıdaki hatayı alıyorum.

.\Output\Discovery.axf: Error: L6218E: Undefined symbol arm_cfft_radix4_init_q31 (referred from main.o).

Kütüphaneleri kullanmak için main programıma #include "arm_math.h" tanımalamasını yaptım. Derlemede problem yok. Fakat arm_cfft_radix4_init_q31 Fonksiyonunu kullandığımda yukarıdaki gibi bir hata alıyorum.

Bu hata ile daha önce karşılaşmıştım. Yanlışım yoksa eğer "Kullanılacak olan kütüphane dosyalarının Proje ağacına eklenmemesinden kaynaklanıyor" diye biliyorum. Sorunum burada bunu çözersem yani kodu derleyebilirsem gerisini hallederim.

DSP_Lib'de kulandığım proje dosyalarını, Proje ağacına nasıl eklemem gerekiyor? Proje ağacında Yeni bir grup ekleyip içerisine DSP_library'de kullandığım proje dosyalarını eklersem eğer çok fazla hata alıyorum..

Bu problemi nasıl çözerim? 
Başlık: Ynt: FFT dönüşümü hakkında
Gönderen: jabbathehutt - 17 Ocak 2016, 17:28:49
FFT'yi incelerken aklıma bir soru takıldı. Twiddle faktöründe euler katsayısını kullanırken ortaya reel ve imajiner kısımlar çıkıyor. Biz bu imajiner kısımları nasıl hesaplayacağız?
Mesela  "cos (x)+i sin(x)" değerinin aldığımız örneklerle çarpılması gerektiğinde bu işlemi nasıl gerçekleştireceğiz? Radix diyagramının sonunda ortaya çıkacak olan imajiner kısım bir değişken içerisine nasıl aktarlıacak?
İmajiner kısımları dikkate almasak ne olur?

Diğer sorumda Twiddle faktörünün dışarıda hesaplanımasıyla ilgili. Twiddle değerlerini kod içerisinde hesaplatmaktansa dışarıda nasıl hesaplatabiliriz? Bazı kodlamalarda bu değeri doğrudan reel sayısal bir değer olarak hesaplamışlar ama nasıl hesapladıklarını anlayamadım.