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
adc Filter and other filters
Re: adc Filter and other filters
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
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
Re: adc Filter and other filters
no,this is not the same...
Re: adc Filter and other filters
Hi Corado,
the following code is a 3-phased analogic to PWM converter for dsPIC30F4011. It uses a filter like you describe: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
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.
I hope this helps