如何逆FFT中的Arduino [英] How to Inverse FFT in Arduino

查看:1925
本文介绍了如何逆FFT中的Arduino的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想筛选基于使用 Arduino的FFT库进行FFT(快速傅立叶变换)

I am trying to filter some data based on the the following code using Arduino FFT library for FFT (fast Fourier transform)

/*
fft_adc_serial.pde
guest openmusiclabs.com 7.7.14
example sketch for testing the fft library.
it takes in data on ADC0 (Analog0) and processes them
with the fft. the data is sent out over the serial
port at 115.2kb.
*/

#define LOG_OUT 1 // use the log output function
#define FFT_N 256 // set to 256 point fft

#include <FFT.h> // include the library

void setup() {
  Serial.begin(115200); // use the serial port
  TIMSK0 = 0; // turn off timer0 for lower jitter
  ADCSRA = 0xe5; // set the adc to free running mode
  ADMUX = 0x40; // use adc0
  DIDR0 = 0x01; // turn off the digital input for adc0
}

void loop() {
  while(1) { // reduces jitter
    cli();  // UDRE interrupt slows this way down on arduino1.0
    for (int i = 0 ; i < 512 ; i += 2) { // save 256 samples
      while(!(ADCSRA & 0x10)); // wait for adc to be ready
      ADCSRA = 0xf5; // restart adc
      byte m = ADCL; // fetch adc data
      byte j = ADCH;
      int k = (j << 8) | m; // form into an int

      k -= 0x0200; // form into a signed int
      k <<= 6; // form into a 16b signed int
      fft_input[i] = k; // put real data into even bins
     // Serial.print(millis());
     // Serial.print("input ");
     // Serial.print(i);
    //  Serial.print(" = ");
      Serial.println(k);
      fft_input[i+1] = 0; // set odd bins to 0
      delay(0.1);
    }
    fft_window(); // window the data for better frequency response
    fft_reorder(); // reorder the data before doing the fft
    fft_run(); // process the data in the fft
    fft_mag_log(); // take the output of the fft
    sei();
    Serial.println("start");

   for (byte i = 0; i < FFT_N/2; i++) {
     if(i<10 || i>20)
     {
       fft_log_out[i] = 0;
     }

     Serial.println(fft_log_out[i]);
   }    
  }
}

应用过滤器这样的后:

After applying the filter like this:

if(i<10 || i>20)
     {
       fft_log_out[i] = 0;
     }

然后我需要逆FFT数据 fft_log_out []

我找了一个反向FFT功能(特别是在 http://wiki.openmusiclabs.com/wiki / FFTFunctions 的),但不能在任何地方找到它。

I looked for an Inverse FFT function (in particular in http://wiki.openmusiclabs.com/wiki/FFTFunctions) but can't find it anywhere.

所以,我怎么能得到逆FFT在Arduino的?

So how can I get the Inverse FFT in Arduino?

推荐答案

的逆FFT​​可以通过利用获得的正向变换

The inverse FFT can be obtained by making use of the forward transform:

for (int i = 0 ; i < 512 ; i += 2) {
  fft_input[i] =  (fft_input[i] >> 8);
  fft_input[i+1] = -(fft_input[i+1] >> 8);
}
fft_reorder();
fft_run();
// For complex data, you would then need to negate the imaginary part
// but we can skip this step since you have real data.

不过请注意,您的过滤code有几个问题。

Note however that your filtering code has a few issues.

首先,将正向FFT的结果是复数携带幅度和相位信息。使用 fft_mag_log 只需幅度,仅此一项不足以原始信号的恢复。因此,您应该用留在完整的FFT输出fft_input 数组作为输入到你的过滤code。

First, the results of the forward FFT are complex numbers which carry both magnitude and phase information. Using fft_mag_log only takes the magnitude, which alone is not sufficient for recovery of the original signal. You should thus use the complete FFT output left in fft_input array as input to your filtering code.

二,与厄密对称频谱实值数据的结果FFT。为了得到一个实值滤波输出,您必须preserve对称性。
所以,不应该完全在频谱的上半部零出的值:

Second, the FFT of real valued data results in a spectrum with Hermitian symmetry. To get a real valued filtered output, you must preserve that symmetry. So, you should not completely zero out the values in the upper half of the spectrum:

for (byte i = 0; i < FFT_N; i+=2) {
  if (! ((i>=20 && i<=40) || (i>=FFT_N-40 && i<=FFT_N-20)))
  {
    fft_input[i] = 0;
    fft_input[i+1] = 0;
  }
}

三,过滤将适用于彼此独立的每个数据块中,总是假定previous输入是零。这通常导致在块边界的不连续性。为了避免这种情况,你应该考虑使用重叠相加的方法

这篇关于如何逆FFT中的Arduino的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆