Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
11/29/06 07:33
Read: times


 
#128652 - filter for DC offset removal
Hello,

I am working on 3 ph voltmeter.Hardware is like this 89c52,
10 bit adc chip , 4 seven segment displays , 3 keys.
mains voltage is given to isolation amp & then this ac vtg fed to adc pin which is biased to voltage adc ref/2.

In software I am thinking of following schem which I got from avr app note . the code needs lots of modification to suit my project but here is the schem -



//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

struct
{
signed int Fresh, Previous;
signed long Filtered,PreviousFiltered,Calibrated;
}Sample;

struct
{signed long U2;} Accumulator;

struct
{
float U;
}Result;



__interrupt void ADC_ISR(void)
{
signed int TempI;
signed long TempL;

// Sampled data from ADC: ADCW Range=[0000...03FF] = 1023
// Copy of sampled data: Sample Range=[0000...03FF]
// Scaled copy of data: Temp Range=00000000...0003FB01]
// DC filtered data: Filtered Range=FFFE0280...0001FD80]

Sample.Previous = Sample.Fresh; // x[n+1] <- x[n]
Sample.Fresh = ADC; // x[n] <- DATA

// Apply filter for DC offset removal.

//y[n] =(0.996 * y[n-1]) + (0.996 * x[n]) - (0.996 * x[n-1])
//y[n] = (0.996 * prv fltrd ) + (0.996 * fresh adc) - (0.996 * old adc)

Sample.PreviousFiltered = Sample.Filtered; // y[n] <- y[n-1]
TempL = 255 * (long)Sample.Filtered; TempL = TempL >> 8;
TempI = Sample.Fresh - Sample.Previous;
TempL = TempL + (255 * (long)TempI;)
Sample.Filtered = TempL;

//For voltage measurements: accumulate square of samples
//Filtered data: Filtered Range=[FFFE0280...0001FD80]
//Prescaled data (>>5): TempX Range=[FFFFF014...00000FEC]
//Prescaled data (>>6): TempX Range=[FFFFF80A...000007F6]
//Multiplication result:(n/a) Range=[FFC09F9C...003F6064]

Temp = Sample.Filtered >> 6;
Accumulator = Accumulator + (Temp * Temp);

if (SampleCounter == NMAX)
{
SampleCounter = 0;
Accumulator = 0;
CYCLE_FULL = 1;
}




void main(void)
{

while (1)
{

// Voltage:U = SQRT [ (accumulated data) / (number of samples) ]
// All data processing must be complete before next ccumulation cycle is completed.

if (CYCLE_FULL == 1)
{
Sum = Accumulator;
Accumulator = 0;

TempUL =(Sum + OFFSET)* NORM;
Result = sqrt(TempUL);

Result = Result * CalCoeff;// Calibrate.
printf(", %8.3f",Result); // disp
}

}

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx




here are my some doubts

1. I would sample adc inputs at rate 200usec as mains freq
is 50hz.

Adc conversion will require @ 20usec

time for executing following iir filter code @100 usec
[I am not sure it may take even more time]

y[n] =(0.996 * y[n-1]) + (0.996 * x[n]) - (0.996 * x[n-1])

total Isr code will take @ 120usec , so only 80usec left
in which I should do Disp mux and some other tasks.

I am first time using this iir filter, is this schem will
give smooth readings ?

2. is there is any trik to avoid 32 bit calculations in ISR
due to iir filter.

3. is there any alternative method for getting rms reading with
out external hardware.


Regards






List of 6 messages in thread
TopicAuthorDate
filter for DC offset removal            01/01/70 00:00      
   I think its already done            01/01/70 00:00      
   Some hints            01/01/70 00:00      
      confusion..            01/01/70 00:00      
         Do you need real time?            01/01/70 00:00      
         how this removes DC offset?            01/01/70 00:00      

Back to Subject List