adc Filter and other filters

Discuss with MikroElektronika software developers about current library development.
Post Reply
Author
Message
corado
Posts: 401
Joined: 28 Mar 2009 11:03

adc Filter and other filters

#1 Post by corado » 18 Feb 2014 13:33

Hallo,
I think really often many users use the µc for measure Voltage, current and so on.
It will be nice, if there will be a filtering Routine like this
Take 16 Values from ADC
Sort them from lowest to highest
Then throw away first two highest and the last two lowest.
Then with the other number calculate a middle value and send this as ready value to work with :-)
I need this very often, and can't do that :-(

tpetar
Posts: 593
Joined: 27 Apr 2012 18:44
Location: Pancevo, Serbia

Re: adc Filter and other filters

#2 Post by tpetar » 18 Feb 2014 19:19

Hello,

The easiest way to do this is to use a small capacitor on the ADC input (100nF-1uF).

Of course this can be solved with programming.


Best regards,
Peter

corado
Posts: 401
Joined: 28 Mar 2009 11:03

Re: adc Filter and other filters

#3 Post by corado » 18 Feb 2014 22:15

no,this is not the same...

VCC
Posts: 463
Joined: 08 Jun 2009 18:31
Location: Romania

Re: adc Filter and other filters

#4 Post by VCC » 19 Feb 2014 15:22

Hi Corado,
the following code is a 3-phased analogic to PWM converter for dsPIC30F4011. It uses a filter like you describe:

Code: Select all

program ADCToPWM;

var
  PWMOutputsEn: sbit at PortD.3;
  
  ADC_Ch1: array[16] of Word;
  ADC_Ch2: array[16] of Word;
  ADC_Ch3: array[16] of Word;
  
  ADC_Ch1_Filtered: Word;
  ADC_Ch2_Filtered: Word;
  ADC_Ch3_Filtered: Word;
  
  i: Word;
  
procedure Inititialize_PWM;
begin
  PTCON.PTEN := 0; //disable PWM Time Base while setting options
  PTCON.PTSIDL := 0; //run in IDLE mode
  
  //postscaler
  PTCON.PTOPS_3 := 0;
  PTCON.PTOPS_2 := 0;
  PTCON.PTOPS_1 := 0;
  PTCON.PTOPS_0 := 0;
  
  //prescaler
  PTCON.PTCKPS_1 := 0;
  PTCON.PTCKPS_0 := 0;
  
  //PWM mode - free running
  PTCON.PTMOD_1 := 0;
  PTCON.PTMOD_0 := 0;
  
  PTMR := 0; //timer value
  
  PTPER := $07FF; //max period    11-bit
  
  PWMCON1.PTMOD3 := 1; //independent, not complementary
  PWMCON1.PTMOD2 := 1; //independent, not complementary
  PWMCON1.PTMOD1 := 1; //independent, not complementary
  PWMCON1 := PWMCON1 or $00FF; //enable all PWM outputs
  
  PWMCON2.IUE := 0; //synchronize updates to the timebase
  PWMCON2.OSYNC := 1; //Output overrides via the OVDCON register are synchronized to the PWM time base
  PWMCON2.UDIS := 0; // Updates from duty cycle and period buffer registers are enabled

  PDC1 := $8000; //50%
  PDC2 := $8000; //50%
  PDC3 := $8000; //50%
  
  PTCON.PTEN := 1; //enable PWM Time Base
end;

begin
  Delay_ms(500);
  
  ADPCFG := 0xFFFF;
  TRISB := %0000000111000000;
  TRISC := 0;
  TRISD := %0000000000001000;
  TRISE := 0;
  TRISF := 0;
  
  LATB := 0;
  LATC := 0;
  LATD := 0;
  LATE := 0;
  LATF := 0;
  
  Inititialize_PWM;
  ADC1_Init;
  
  ADPCFG := ADPCFG and %0000000111000000;  //AN6, AN7, AN8, others = digital
  
  PDC1 := $0800; //50%   (2048 = 2^11 - 12-bit)
  PDC2 := $0800; //50%
  PDC3 := $0800; //50%
  
  repeat
    ADC_Ch1[15] := ADC1_Get_Sample(6);     //AN6       // 10-bit
    ADC_Ch2[15] := ADC1_Get_Sample(7);     //AN7
    ADC_Ch3[15] := ADC1_Get_Sample(8);     //AN8
    
    ADC_Ch1_Filtered := 0;
    ADC_Ch2_Filtered := 0;
    ADC_Ch3_Filtered := 0;
    
    for i := 0 to 14 do
    begin
      ADC_Ch1[i] := ADC_Ch1[i + 1];
      ADC_Ch1_Filtered := ADC_Ch1_Filtered + ADC_Ch1[i];
      
      ADC_Ch2[i] := ADC_Ch2[i + 1];
      ADC_Ch2_Filtered := ADC_Ch2_Filtered + ADC_Ch2[i];
      
      ADC_Ch3[i] := ADC_Ch3[i + 1];
      ADC_Ch3_Filtered := ADC_Ch3_Filtered + ADC_Ch3[i];
    end;
    
    ADC_Ch1_Filtered := ADC_Ch1_Filtered + ADC_Ch1[15];    // 14-bit
    ADC_Ch2_Filtered := ADC_Ch2_Filtered + ADC_Ch2[15];
    ADC_Ch3_Filtered := ADC_Ch3_Filtered + ADC_Ch3[15];
    
    //ADC_Ch3_Filtered := 24576 - (ADC_Ch1_Filtered + ADC_Ch2_Filtered);   //for a 3-phased sine system, the 3rd sine can be computed instead of being measured
    
    PDC1 := ADC_Ch1_Filtered shr 2;                        // 12-bit
    PDC2 := ADC_Ch2_Filtered shr 2;
    PDC3 := ADC_Ch3_Filtered shr 2;
    
    if PWMOutputsEn = 1 then
      PWMCON1 := PWMCON1 or $00FF //enable all PWM outputs
    else
      PWMCON1 := PWMCON1 and $FF00; //disable all PWM outputs

  until False;
end.
Summing up 16 samples, is like adding 4 bits of resolution to the filtered signal. This application needed only 12 bits of resolution for PWM so the filtered values are right shifted by two bits.
I hope this helps :D

Post Reply

Return to “Library Development Discussion”