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 I tested arm_rfft_fast_f32 function from CMSIS-DSP 1.4.4 with generated 50hz sine wave at 1000Hz sample rate using 1024 samples, but i get peek value at 102, not 51 which i should get 1000/1024 ~0,97 * 51 = 50Hz:
uint16_t i;
float32_t khz10[1024];
float32_t maxvalue;
uint32_t maxindex;
//float32_t output2[1024];
arm_rfft_fast_instance_f32 S;
arm_rfft_fast_init_f32(&S, 1024);
printf("Input=[");
for(i=0; i<1024; i++){
khz10[i] = 1.2f*arm_sin_f32(2*3.1415926f*50*i/1000)+1;
printf("%f,",khz10[i]);
}
printf("]\r\n");
arm_rfft_fast_f32(&S, khz10,khz10,0);
arm_abs_f32(khz10, khz10, 1024);
arm_max_f32(khz10+1, 1023, &maxvalue, &maxindex);
printf("Max:[%ld]:%f Output=[",maxindex,maxvalue);
I later tested this function with real data from adc and I can only get 1/4 of frequency spectrum
not about 1/2 as I expected. Can anyone could me explain this ?
My previous reply is for your previous post containing the plot for the real and imaginary parts. I wonder why I didn't see your follow-up post and prior to my posting of this reply, it was your post that was shown as latest in the welcome page.
Hi, i find what was wrong. We can't just use the same buffer for input and output in function arm_rfft_fast_f32
I pondered if it is possible to use the same buffer in arm_rfft_fast_f32. My attention was diverted from it because the signal and the spur has an interesting relationship. The frequency bin of the spur, 460, is equal to 511 - 51. Fortunately, you decided to restore the output buffer and found the trouble.
There is still a minor problem with the output spectrum. Earlier I stated that the CMSIS-DSP real FFT functions pack the data for frequency bins 0 (DC) and N/2 (Nyquist frequency) at the beginning of the output array. So if the output array is passed to arm_cmplx_mag_f32 right after arm_rfft_fast_f32, the magnitude for DC will be erroneous and the Nyquist frequency will be missing in the spectrum. We can have it corrected in two ways.
First, we use a temporary variable to save the Nyquist frequency data, later the saved data will be reinserted to the output array.
float32_t output[1024];
float32_t saveNyquist; // Variable for saving the Nyquist frequency data
arm_rfft_fast_f32(&S, khz10,output,0);
// Take the absolute value of the Nyquist frequency data and save it to saveNyquist
arm_abs_f32(output+1, &saveNyquist, 1);
// Convert real DC data to complex number with imaginary part = 0,
// this 0 obliterates the Nyquist frequency data at index=1
// so it was saved in the preceding function call
output[1] = 0;
arm_cmplx_mag_f32(output,output, 512);
// Append the saved Nyquist frequency data
output[512] = saveNyquist;
// There are now 513 frequency bins because of the Nyquist frequency
// and it should be included in the search for the bin with maximum magnitude
arm_max_f32(output+1, 512, &maxvalue, &maxindex);
maxindex++;
printf("Max Value:[%ld]:%f Output=[",maxindex,maxvalue);
for(i=0; i<513; i++){
printf("%f,",output[i]);
Second, instead of using a temporary variable, we extend the length of the output array to hold one more complex number. The Nyquist frequency data will be copied into the extended location.
float32_t output[1026];
// Unpack the DC and Nyquist frequency data
//
// Copy the Nyquist frequency data to the end of the buffer
output[1024] = output[1];
// Convert the DC and Nyquist frequency data to complex numbers
// with imaginary parts = 0
output[1] = output[1025] = 0;
arm_cmplx_mag_f32(output,output, 513);
Note: The corrections are with respect to the latest code that you posted, the one which you described as correct version.