2
\$\begingroup\$

I am trying to make a Low pass IIR filter in dsPIC(dsPIC33FJ12MC202) using mikroC compiler. I have generated filter coefficients using Filter Design Tool. My filter specifications are as follows:
LPF, Wp=4KHz, Ws=5KHz, Ap=0, As=60, Sampling about 20Khz

enter image description here

I am taking analog input from channel zero, filtering it and sending filtered value via UART. The code look something like this:

int adcValue;
char result[6];

const unsigned int BUFFER_SIZE   = 8;
const unsigned int FILTER_ORDER  = 3;

const unsigned int COEFF_B[FILTER_ORDER+1] = {0x17D9, 0x478B, 0x478B, 0x17D9};
const unsigned int COEFF_A[FILTER_ORDER+1] = {0x8000, 0xAF27, 0x383C, 0xF802};

const unsigned int SCALE_B = 1;
const unsigned int SCALE_A = 0;

unsigned int inext;
ydata unsigned int input[BUFFER_SIZE];
ydata unsigned int output[BUFFER_SIZE];

void filter(unsigned int adcValue)
{
  unsigned int CurrentValue;
  input[inext] = adcValue;

  CurrentValue = IIR_Radix( SCALE_B,
                            SCALE_A,
                            COEFF_B,        // b coefficients of the filter
                            COEFF_A,        // a coefficients of the filter
                            FILTER_ORDER+1, // Filter order + 1
                            input,          // Input buffer
                            BUFFER_SIZE,    // Input buffer length
                            output,         // Output buffer
                            inext);         // Current sample

  //CurrentValue = 2048;

  output[inext] = CurrentValue;
  inext = (inext+1) & (BUFFER_SIZE-1);    // inext = (inext + 1) mod BUFFER_SIZE;

  //Sending filtered value via UART
  WordToStr(CurrentValue, result);
  strcat(result, "\n\r");
  UART1_Write_Text(result);
}


void main()
{  
   inext  = 0;                                 // Initialize buffer index
   Vector_Set(input, BUFFER_SIZE, 0);         // Clear input buffer
   Vector_Set(output, BUFFER_SIZE, 0);       // Clear output buffer

   //Using R12, R13 for Rx, Tx
   PPS_Mapping(12, _INPUT, _U1RX);
   PPS_Mapping(13, _OUTPUT, _U1TX);

   UART1_Init(115200);
   ADC1_Init();

   while(1)
   {
      adcValue = ADC1_Read(0);
      Delay_us(50);
      filter(adcValue);
   }
}

The IIR_Radix function is provided by mikroC compiler, So I am expecting below 4Khz it should give output whatever the input is and above 4KHz it should attenuates input.

Currently I am simulating circuit using Proteus and when I apply Sine Wave generator(Amplitude 5v, Freq=1000 Hz) at ADC channel I am getting output which has maximum value 95(e.g 0, 22, 69, 95, 69, 22, 0...) on Virtual Terminal. But 1000 Hz is in passband so I should get whatever the input is, like(0, 25, 499, 1023, 499, 25, 0...). So why I am getting attenuated output even for passband frequencies?

I am analyzing output on virtual terminal inside proteus simulation, see on right.

enter image description here

\$\endgroup\$
1
\$\begingroup\$

You say that sampling frequency is "about 20kHz" (perhaps exactly 22.1kHz, typicaly for audio?). So the period of a 1kHz sine wave should be about 20 samples.

But your data has a period of 6 samples. It isn't 1kHz, but more like 3.5kHz. Getting somewhat close to the corner frequency, although not close enough to explain attenuation by a factor of 5.

Looking at the screenshot, though, every second value is zero. So your frequency is just under fs/2. And that is solidly in the stopband.

\$\endgroup\$
  • \$\begingroup\$ Actually my main target is to build LPF for audio signal but for now I am just trying to test DSP features of dsPIC. And 0, 22, 69, 95, 69, 22, 0... was just an example(not period of 6 sample). I am giving delay of 50us so sampling rate would be approximately 20KHz while UART speed is slow i.e 115200, that may be the reason that it is not printing every output value on terminal. BTW I didn't get your answer completely. \$\endgroup\$ – Dark_Prince Feb 21 '15 at 21:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.