Hello,
I have a Nucleo-L476RG board and I'm trying to make a lowpass filter with the FIR function (using cmsis libraries) to filter the samples I get from the ADC in realtime.Then I'd like to get the processed signal out through the DAC.
Both ADC and DAC work at a sampling frequency of 20khz, triggered by two different timers. They use DMA.
FIR function is called every time the ADC ends a conversion.
I'm using arrays of 1 element as buffers, so the number of blocks of the FIR function is 1.
I can get a signal on the output, but it does not match what the input signal processed through the filter would be.Thank you very much for your help. I hope my explanation is good enough.
Here is my code:
#include <math.h> #include "arm_math.h" uint32_t adcValue[1]; uint32_t adcValue1[1]; int i; float32_t signal_in = 0; float32_t signal_out = 0; #define TEST_LENGTH_SAMPLES 1 #define BLOCK_SIZE 1 #define NUM_TAPS 29 arm_fir_instance_f32 S; static float32_t firStateF32[BLOCK_SIZE + NUM_TAPS - 1]; static float32_t firCoeffs[NUM_TAPS] = {-0.0018225230f, -0.0015879294f, +0.0000000000f, +0.0036977508f, +0.0080754303f, +0.0085302217f, -0.0000000000f, -0.0173976984f, -0.0341458607f, -0.0333591565f, +0.0000000000f, +0.0676308395f, +0.1522061835f, +0.2229246956f, +0.2504960933f, +0.2229246956f, +0.1522061835f, +0.0676308395f, +0.0000000000f, -0.0333591565f, -0.0341458607f, -0.0173976984f, -0.0000000000f, +0.0085302217f, +0.0080754303f, +0.0036977508f, +0.0000000000f, -0.0015879294f, -0.0018225230f}; uint32_t blockSize = BLOCK_SIZE; uint32_t numBlocks = TEST_LENGTH_SAMPLES/BLOCK_SIZE; void SystemClock_Config(void); int main(void) { HAL_Init(); /* Configure the system clock */ SystemClock_Config(); /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); MX_DAC1_Init(); MX_TIM6_Init(); MX_ADC1_Init(); MX_TIM7_Init(); MX_ADC2_Init(); //Timers HAL_TIM_Base_Start(&htim6); HAL_TIM_Base_Start(&htim7); //ADC Start HAL_ADC_Start_DMA(&hadc1, adcValue, 1 ); //DAC Start HAL_DAC_Start(&hdac1,DAC_CHANNEL_1); HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1, (uint32_t*)adcValue1, 1, DAC_ALIGN_12B_R); //FIR Init arm_fir_init_f32(&S, NUM_TAPS, (float32_t *)&firCoeffs[0], (float32_t *)&firStateF32[0], blockSize); /* Infinite loop */ while (1) { } } void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { if(hadc->Instance == ADC1) { signal_in = (float32_t)adcValue[0]; arm_fir_f32(&S, &signal_in, &signal_out, blockSize); adcValue1[0] = (uint32_t)signal_out; //signal_out; } }
Hello Ruggine,
Im doing the same right now, could you get any improvement on your results? i think the issue with the difference between expected results and the reached results is regarding that in the FIR example has floating point input format, and in your case the ADC give a int format data, so you need to convert that into voltage floating point data and then pass through the FIR, hope you can get your expected results and let me know...kind regards
Msc Dmitri S.
NUM_TAPS should be even for Q15.
F32 Helium version the array of coefficients must be a multiple of 16 even if less then 16 coefficients are used.
arm-software.github.io/.../group__FIR.html