ARM CFFT Peak Velocity from Acceleration data

               Hello guys,

      I am using an NRF chip with Cortex M4. Currently I am reading data from an accelerometer (12 signed bit ADC) and I have to get peak velocity. For that I am using the Omega arithmetic algorithm, as follows:

         - remove offset from raw data (acceleration) and shift values with 4 bits; copy the array in a x2 length array with interleaving 0 complex values;

         - do a CFFT on the new array;

         - try to divide each complex value by (0 + 2*pi*df I); now we have velocity  in frequency domain;

         - to inverse CFFT, calculate magnitude, remove offset and shift back 4 bytes;

         - check for peak velocity and convert data into mm/s value;

   I used a test array (sine wave of ~208 hz with peak value of 2048 - that is the max signed value for signed 12 bits) , sampling frequency of 3332hz and a total of 4096 samples.  Problem is that if I divide my complex values with 2*pi*f (according to the complex division formulas), I get very low values in the frequency domain for real and complex parts, and the final array has inside it a bunch of zeroes and -1. I am not getting back a sine wave in time domain.

    Does anybody has an idea if I should shift with some bits or something the values before doing the Inverse CFFT? Here is a part of the code below:

 Many thanks!

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#define FFT_LENGTH 4096
#define NUMBER_OF_VIBRATION_MEASUREMENTS 4096
....
static q15_t fft_data_out[FFT_LENGTH*2];
static q15_t fft_data_in[FFT_LENGTH];
memcpy(&fft_data_in[0], &p_edwin_service->vibrations.raw[0], sizeof(p_edwin_service->vibrations.raw)); // copy adc data to in buffer
#ifdef USE_TEST_DATA
memcpy(fft_data_in, test_data, sizeof(test_data)); // for test only
#endif
arm_shift_q15(fft_data_in, 4, fft_data_in, NUMBER_OF_VIBRATION_MEASUREMENTS);
q15_t mean2 = 0;
arm_mean_q15(fft_data_in, NUMBER_OF_VIBRATION_MEASUREMENTS, &mean2);
mean2 = -mean2;
arm_offset_q15(fft_data_in, mean2, fft_data_in, NUMBER_OF_VIBRATION_MEASUREMENTS);
NRF_LOG_INFO("mean before fft %d", mean2)
for (uint32_t i = 0; i < FFT_LENGTH; i++) {
fft_data_out[(i * 2)] = fft_data_in[i];
fft_data_out[(i*2)+1] = 0;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void to_velocity_freq(q15_t *signal)
{
int N=4096;
float tmp=0;
float df = 0;
float tmp1 = 0;
for (int n = 0; n < N/2; n++)
{
df = n * (3332.0/(float)(NUMBER_OF_VIBRATION_MEASUREMENTS));
tmp =0.0;
tmp1= 0.0;
if (df != (float)0.0){
tmp = (float)signal[n*2] / (2*pi*df);
tmp1= (-1)*(float)(signal[n*2+1]) /(2*pi*df);
}
signal[n*2] = (q15_t) __SSAT((q31_t) (tmp), 16);
signal[n*2+1] = (q15_t) __SSAT((q31_t) (tmp1), 16);
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
static const int16_t test_data[4096] = {
0,
784,
1448,
1892,
2048,
1892,
1448,
784,
0,
-784,
-1448,
-1892,
-2048,
-1892,
-1448,
-784,
0,
784,
1448,
1892,
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

0