We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi,
Hope someone can provide some assistance on this issue.
1 - Using an STM32F407 processor, clock at 168Mhz
2 - Using ADC to sample low frequency signals (< 50Hz) from sensors
3 - Have timer interrupt set such that setting timer period to frequency will interrupt at that rate and add a sample from ADC to buffer. Using timestamps, I have confirmed that the interrupt is operating correctly
4 - I have used ScopeFIR to create 3 sets of filter coefficients to test: one at Fs = 512Hz, one at 1024Hz, and one at 2048Hz. The reason I'm using power of 2 values for sampling is so that when I divide the sampling rate into the FFT size, I should get 0.5Hz resolution. (according to resolution = Fs / Fn)
In the header, I have three #defines that control the interrupt operation:
#define SAMPLE_FREQ
#define BUFFER_SIZE
#define FFT_SIZE
In the interrupt handler:
if(sampleCount == BUFFER_SIZE)
{
cfftBuffer[0] = 0;
//do stuff here...look for bins of interest....
} //end: if (samplecount...
So this is where my questions are:
With the defines set to these values:
#define SAMPLE_FREQ 512
#define BUFFER_SIZE 2048
#define FFT_SIZE 1024
And using the Dolph-Cheby filter coefficients for Fs = 512, with a 22Hz sensor signal into the ADC, here are the bin values from 1 to 25:
Power at 1 = 201.5
Power at 2 = 203.8
Power at 3 = 183.8
Power at 4 = 215.4
Power at 5 = 137.4
Power at 6 = 107.9
Power at 7 = 112.4
Power at 8 = 125.5
Power at 9 = 81.0
Power at 10 = 128.6
Power at 11 = 190.1
Power at 12 = 60.5
Power at 13 = 53.6
Power at 14 = 103.9
Power at 15 = 76.4
Power at 16 = 84.4
Power at 17 = 29.6
Power at 18 = 61.4
Power at 19 = 48.9
Power at 20 = 18.0
Power at 21 = 40.9
Power at 22 = 47.6
Power at 23 = 524.6
Power at 24 = 123.5
Power at 25 = 55.9
Power at 58 = 43.9
Power at 59 = 96.4
The sensor is signalling at precisely 22Hz, clearly the highest bin level is at 23, one higher than it should be.
Now, if I set the defines to these values:
#define SAMPLE_FREQ 1024
And use the Dolph-Cheby filter coefficients for Fs = 1024, here are the new bin values (shown from 20 to 50):
Power at 21 = 197.2
Power at 22 = 64.0
Power at 23 = 81.5
Power at 24 = 70.8
Power at 25 = 72.8
Power at 26 = 49.3
Power at 27 = 31.5
Power at 28 = 37.9
Power at 29 = 7.5
Power at 30 = 18.7
Power at 31 = 20.3
Power at 32 = 30.4
Power at 33 = 17.6
Power at 34 = 27.1
Power at 35 = 67.4
Power at 36 = 28.9
Power at 37 = 12.6
Power at 38 = 29.6
Power at 39 = 14.5
Power at 40 = 52.4
Power at 41 = 46.9
Power at 42 = 44.1
Power at 43 = 21.2
Power at 44 = 28.1
Power at 45 = 89.8
Power at 46 = 311.5
Power at 47 = 236.7
Power at 48 = 83.2
Power at 49 = 54.1
Power at 50 = 35.7
The high bin has now moved to 46. Dividing by 2 and subtracting 1 it is 22, which again is correct.
Can someone explain what is happening with this? I'll soon need a hair transplant if I don't figure it out. Any comments or suggestions would be appreciated.
Thanks,
Gary
Clearly, no support from ARM or anyone writing CMSIS can be expected here. Not a difficult question, but perhaps I need to offer my credit card number first?? 8---) ??
Think I'll move over to Siglib and perhaps even go with the XMOS multi-core processors where I know I can get support.
Hi Grog,
I replied to this a minute ago before I noticed you had actually responded to me on the other thread, so please disregard that message which I have now deleted.
I'll make a quick program to attempt to test something like this, but it would really be a lot easier to find the source of this problem if you would send me a complete, compilable, working program that showcases the reported issue. The best I can think of on my end is to run a 22Hz sine wave through cfft + cfft mag and make sure it pops up at the right spot with the fft sizes you mentioned.
As I mentioned before, you can email me at dwhite@dspconcepts.com .
Cheers,
Dan
Below is a sample program I created without all the FIR and interrupt stuff. It just generates a real 22Hz sine wave and puts it in cfft then cfft mag. I ran it through the simulator for FFT_SIZE 512 and FFT_SIZE 1024.
FFT_SIZE 512 - bin 22 (indexing starts at 0 not 1 just to be clear)
FFT_SIZE 1024 - bin 44
These are the expected values. So I may need more information about these FIRs and your actual input data to offer a more informative response.
#include <arm_math.h>
#include <arm_const_structs.h>
#include <math.h>
#define FFT_SIZE 512
#define SIGNAL_FREQ (22.0f)
#define SAMPLE_FREQ (512.0f)
float32_t outputBuffer[FFT_SIZE*2];
float32_t magBuffer[FFT_SIZE];
int main ()
int i;
for(i=0;i<FFT_SIZE;i++)
outputBuffer[2*i] = sinf(SIGNAL_FREQ*2.0f*3.14159265358979f*(float)i/SAMPLE_FREQ);
outputBuffer[2*i+1] = 0;
}
#if FFT_SIZE == 512
arm_cfft_f32(&arm_cfft_sR_f32_len512, outputBuffer, 0, 1);
#elif FFT_SIZE == 1024
arm_cfft_f32(&arm_cfft_sR_f32_len1024, outputBuffer, 0, 1);
#endif
/* Calculate the magnitude at each bin */
arm_cmplx_mag_f32(outputBuffer, magBuffer, FFT_SIZE);
return 0;