Hi All;
I have some questions about correct use of the CMSIS DSP library call arm_fir_32. First, I'll provide some background about what I am doing and what the setup is.
I have a STM32F4 Discovery board, using IAR EWARM for programming. Just for testing purposes, I'm generating a low frequency test signal at 40Hz and feeding it into one of the ADC inputs. The signal is biased to swing from 0 to about 2.5Vpp. The signal has a low to moderate amount of broadband noise - but at this point I am not purposely mixing or introducing any other signals with it. There is a timer interrupt set to sample frequency of 2KHz, with a sampling buffer of 2048 samples.
I have already tested and am using the FFT function arm_cfft_f32, and can accurately determine (track) the frequency of the incoming signal when I change it at the source. This seems to be working well.
Now, I would like to use the arm_fir_32 filter. To do this, I started out reading the documentation from CMSIS on the function. To implement a FIR low pass, to generate the tap coefficients, I am using this website's only tool to do so.
I generated a 4th order filter, and set the sampling rate the same as my software, with a cutoff of 60Hz. I forced generation to 24 taps to be even. So the BLOCK_SIZE is 32, and the number of blocks is 1024/32 = 32.
Following the example from CMSIS on this function, I believe I've set up correctly. So the chain looks like this:
ADC --> FIR --> FFT
However, I'm not getting the result I would expect. The values returned from the FFT's output buffer are exponentially large (not this way if I comment out /circumvent the FIR calls). This leads me to believe I am missing a step. Do I need to normalize the values? I thought that because I input the rate into the FIR function setup, this wouldn't be required - but maybe this is incorrect.
Can someone please provide some insight or assistance as to what I am missing or doing incorrectly to apply the FIR processing?
Thank you,
Gary
Hi Gary,
I'm not an expert in solving DSP questions (more of a firmware coder), but I'll toss in my 2 cents. You could look at the SNR of the signal in question, and if it's large enough that should indicate it's not a part of the background noise. You could track the signal over multiple interrupts to see if it is still there and still at the same frequency. You could check that only 1 or 2 bins have very large values, as opposed to a plateau of large values.
That's about all I can think of. There's not much you can do if your noise produces a strong sinusoid at the frequency of interest aside from find a way to filter it out before you measure it.
Dan
Thanks Dan.
After looking at the CMSIS documentation, there's an example there that uses the SNR function of the CMSIS DSP library:
/* ----------------------------------------------------------------------
** Compare the generated output against the reference output computed
** in MATLAB.
** ------------------------------------------------------------------- */
snr = arm_snr_f32(&refOutput[0], &testOutput[0], TEST_LENGTH_SAMPLES);
if (snr < SNR_THRESHOLD_F32)
{
status = ARM_MATH_TEST_FAILURE;
}
else
status = ARM_MATH_SUCCESS;
Dan, since you indicated that your area isn't DSP, is it possible that Dr.Beckmann could answer this question:
In the CMSIS documentation example for SNR, the input signal AND the test signal is generated by Matlab. In the real world, how is a reference signal generated when receiving signals that have an amplitude = unknown? I am thinking that the answer isn't likely in one sentence. This is a whole side of DSP processing I have not done before, so if you can point me to some reading (website, document, book) that would provide some insight as to how to correctly use the CMSIS function I would be grateful.
To distinguish between signal and noise you need a good model of each. This is very common in other applications like communications in which you want to distinguish between 0's and 1's. It's usually not 100% reliable since noise can sometimes appear as signal and vice versa.
-Paul