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.
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!