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 (tim6 and tim7) 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; } }
So what is it like?
Is just like the input signal, with minor changes. If I compare adc buffer to the dac buffer they are different, so I guess the fir function is doing something, but not what I expected. In fact the filter should be a low pass filter with 5khz cut frequency, but If I go up to 10khz with the input signal, I can still see the output (it should be near zero or at least very attenuated). I also tried with another lowpass filter with 400hz cutoff frequency and I can still see an output signal at 10khz.
Thank you for your reply.
Seriously doubt you can interrupt and process a single sample at a time in the fashion shown.
So what would you suggest to do?
Thanks for your reply!
Problem solved! The code is 100% right. I figured out that I swapped some pins in MXCube32 and so I was not putting my probe on the DAC output! Many thanks to everyone who helped me!