Hello,
I am looking for an FFT library I can use on the Mega2560. Basically, I want to take 256 samples at 391uS intervals. I will end up with a 128 bin spectra from 0-1280 hz I can then discard the last 28 bins and calculate overall vibration acceleration and velocity levels in the 10-1000hz range.
I have an ADC shield I designed with an MCP3208 12 bit ADC. The sensor is an ADXL335 accelerometer giving 300mV/g I am only using the Y axis in the vertical orientation so with no vibration at all, it puts out roughly 1.95V
What I have done so far is to take my samples, find the average, which as I mentioned is about 1.95V which I subtract ie remove the dc bias, convert them to g’s, pass them through a hanning window then do an fft with some old code I adapted from an old Turbo C++ program I developed years ago.
Now, as the project is developing and I’m adding in more bits, I find that the old fft routine is causing problems.
OK, the openmusiclabs fft code takes its data from the internal ADC and looks like this
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
fft_input[i+1] = 0; // set odd bins to 0
and my code, using the MCP3208 library, looks like this
void sample(int chan)
{
unsigned long start_time;
unsigned long next_time;
int a;
start_time = micros();
if(start_time>0xFFF0BDBF) // micros is close to rollover, wait until it has.
delay(1010); // 1.01 second delay to take micros past rollover
next_time = micros()+391;
for(a=0; a<=numsamples; a++)
{
twf[a] = adc.analogRead(chan)*res; // res=3.3/4096 ie 12 bit resolution with 3.3V ref
avg+=twf[a];
for(;;)
if((long)micros()>next_time)
break;
next_time+=391;
}
avg/=numsamples;
}
So, I’m guessing that ADCL and ADCH are the low and high bytes as the internal ADC is 10 bits and they are shifted into int k and fft_input is made up of alternative real and imaginary values but I’d like to be corrected if I’m wrong. Also, this code does not remove any dc bias prior to doing the fft which I have seen on other examples.
Not being a brilliant mathematician (or a brilliant anything for that matter) I would really appreciate some advice here. Is it necessary to convert the voltages to their relative values prior to doing the fft? should the dc offset be removed? or can I just fetch the data from the MCP3208 and put it into the even bins, fill the odd bins with zeros, do the fft and worry about conversion later?
I know there’s some knowledgeable people on here who seem to understand fft’s very well as I’ve been reading your posts all afternoon and I’d be very grateful for your advice.