??? 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 |
Topic | Author | Date |
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 |