This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

CMSIS DSP FFT does not give the correct result when number of points are changed

I have used the example provided in the CMSIS DSP example for 1024 point FFT. It works and there are no issues.

Next I used Matlab to generate 1024 sample points for a 100 Hz sine wave with 10 kHz sampling. The sine wave had a peak to peak amplitude of 1V and a DC offset of 1.25 V. The FFT results generated with CMSIS DSP show the value of the Bin-0 at 1.249 and it matches up with Matlab results.

Next I did the same steps for 512 sample points. However the Bin-0 for DC value now became 0.6249 when the CMSIS DSP is used while Matlab still shows it as 1.25 for FFT.

Finally to double check i used 2048 sample points and the value of Bin-0 DC doubled to 2.499 while output of Matlab did not change.

So the question is that

1. Does CMSIS scale the values internally when the time domain signal is transformed to frequency domain?

2. What is the Y-axis units when the signal is transformed to frequency domain?

Parents
  • Hello Amit, I have reproduced your test patterns on Matlab and generated the first 4 FFT output :

    F0 = 100; FS = 10000; for L=[512,1024,2048]; data = 1.25 + sin(2*pi*[1:1:L]*F0/FS); 
    x = fft(data); fprintf(1,'%8.3f %8.3f %8.3f %8.3f\n', abs(x(1)), abs(x(3)), abs(x(3)), abs(x(4)));
    end 

    Then I programmed a CortexM4 with the following code and found the same results. There is no scaling in the subroutine. There is no voltage consideration in floating point FFT outputs. 

    Please note the FFT output is proportional to the length of the input vector for pure tones or DC. You need to apply a scaling factor corresponding to the vector length.

    Best regards, Laurent.

    arm_cfft_f32(&arm_cfft_sR_f32_len512, sine512, ifftFlag, doBitReverse);
    arm_cmplx_mag_f32(sine512, testOutput, fftSize);

    arm_cfft_f32(&arm_cfft_sR_f32_len1024, sine1024, ifftFlag, doBitReverse);
    arm_cmplx_mag_f32(sine1024, testOutput, fftSize);

    arm_cfft_f32(&arm_cfft_sR_f32_len2048, sine2048, ifftFlag, doBitReverse);
    arm_cmplx_mag_f32(sine2048, testOutput, fftSize);

    And the output results are :

    644.654 7.398 7.398 11.928
    1295.410 16.324 16.324 17.565
    2591.758 32.064 32.064 32.454

Reply
  • Hello Amit, I have reproduced your test patterns on Matlab and generated the first 4 FFT output :

    F0 = 100; FS = 10000; for L=[512,1024,2048]; data = 1.25 + sin(2*pi*[1:1:L]*F0/FS); 
    x = fft(data); fprintf(1,'%8.3f %8.3f %8.3f %8.3f\n', abs(x(1)), abs(x(3)), abs(x(3)), abs(x(4)));
    end 

    Then I programmed a CortexM4 with the following code and found the same results. There is no scaling in the subroutine. There is no voltage consideration in floating point FFT outputs. 

    Please note the FFT output is proportional to the length of the input vector for pure tones or DC. You need to apply a scaling factor corresponding to the vector length.

    Best regards, Laurent.

    arm_cfft_f32(&arm_cfft_sR_f32_len512, sine512, ifftFlag, doBitReverse);
    arm_cmplx_mag_f32(sine512, testOutput, fftSize);

    arm_cfft_f32(&arm_cfft_sR_f32_len1024, sine1024, ifftFlag, doBitReverse);
    arm_cmplx_mag_f32(sine1024, testOutput, fftSize);

    arm_cfft_f32(&arm_cfft_sR_f32_len2048, sine2048, ifftFlag, doBitReverse);
    arm_cmplx_mag_f32(sine2048, testOutput, fftSize);

    And the output results are :

    644.654 7.398 7.398 11.928
    1295.410 16.324 16.324 17.565
    2591.758 32.064 32.064 32.454

Children
No data