0% found this document useful (0 votes)
100 views9 pages

Digital Filters For Offset Removal: Digital High Pass Filter

The document discusses digital filtering techniques to remove offset from sampled AC waveforms. It describes implementing a high pass filter and low pass filter using floating point and integer arithmetic. For the high pass filter, it explains that using scaled integer values provides higher resolution and better filtering performance compared to direct integer calculations. For the low pass filter, preloading the filter value and using a very small filter constant allows it to settle quickly while minimizing ripple.

Uploaded by

Prince Blissful
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
100 views9 pages

Digital Filters For Offset Removal: Digital High Pass Filter

The document discusses digital filtering techniques to remove offset from sampled AC waveforms. It describes implementing a high pass filter and low pass filter using floating point and integer arithmetic. For the high pass filter, it explains that using scaled integer values provides higher resolution and better filtering performance compared to direct integer calculations. For the low pass filter, preloading the filter value and using a very small filter constant allows it to settle quickly while minimizing ripple.

Uploaded by

Prince Blissful
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 9

Digitalfiltersforoffsetremoval

TheAtmegaADC(Arduino)hasaninputvoltagerangeof0toVccandsowhen
samplinganACwaveformthewaveformneedstobebiasedatVcc/2.This
translatestoadigitaloffsetvalueofapproximately512.Thewaveformsample
digitalvaluewillbebetween0and1023,centeredaround512.
Todothemathsforrealpower,rmsvoltageandcurrentcalculations,weneed
removethisoffset.Thiscanbedonewithadigitalfilter.Therearetwo
approaches:thehighpassfilter,whichallowsthehighfrequencycomponent
throughremovingthebias,orthelowpassfilter,whichfirstfindsthebias,then
subtractsthebiasfromthesignal.Let'sstartwiththehighpassfilter.

Digitalhighpassfilter
Thefloatingpointimplementationlookslikethis:
filtered_value=0.996(last_filtered_value+samplelast_sample)

Why0.996?Itisnotamagicnumber,allthatisrequiredisanumberreasonably
closetounityinordertoprovideanadequatelylongtimeconstantsothereis
somephaseandamplitudedistortionatthe50Hzfundamentalfrequencybeing
measured.0.996yieldsafiltertimeconstantof250sampleperiods.
Codeexample:
intsample=0;
intlast_sample=0;
doublea=0;
doublefiltered_value=0;
voidsetup()
{
Serial.begin(9600);
}
voidloop()
{
//Generateatestsignal
last_sample=sample;
a+=0.1;sample=512+sin(a)*100;

//Floatingmathsimplementationofhighpassfiltertakes3640microseconds
filtered_value=0.996*(filtered_value+samplelast_sample);

Serial.print(sample);
Serial.print('');
Serial.println(filtered_value);
delay(50);

Noticethatittakesasignificantamountoftimetosettletothepointwhere
filtered_valuegoesbothpositiveandnegativewithanamplitudeof100.
Integerbitwiseimplementation
Apartfrombeingclosetounity,andthereforesuitableforthetypeoffilterwe
want,thevalue0.996abovewasselectedbecauseyoucanmultiplyby0.996
efficientlyusinglowleveloperationsbitshiftsandsubtractions.0.996isnearly
equalto255/256,andmultiplicationordivisionby256iseasilydonewith
bitwiseoperators:
n256=n<<8(bitwiseleftshiftby8bits=multiplicationby256)
n/256=n>>8(bitwiserightshiftby8bits=divisionby256)
n255=n256n=((n<<8)n)

Wecanrewritethedigitalhighpassfilteras:
n=last_filtered_value+samplelast_sample
filtered_value=0.996n=255n/256=(n256n)/256

substitutingbitwiseoperatorsyields:
n=last_filtered_value+samplelast_sample
filtered_value=((n<<8)n)>>8

Codeexample:
intsample=0;
intlast_sample=0;
doublea=0;
longfiltered_value=0;
voidsetup()
{
Serial.begin(9600);
}
voidloop()
{
//Generateatestsignal
last_sample=sample;
a+=0.1;sample=512+sin(a)*100;

longn=filtered_value+samplelast_sample;
filtered_value=((n<<8)n)>>8;

filtered_value=((n<<8)n)>>8;

Serial.print(sample);
Serial.print('');
Serial.println(filtered_value);
delay(50);
}

Ifyouwatchthefiltersettle,italmostworks,itappearstobesettlingcorrectly,
butthere'saproblem.
filtered_valuecontinuestodecreaseuntilithasapositiveamplitudeofaround0
andanegativeamplitudeof200

Thisispartlyduetoroundingerror,wecanimprovethingsbyadding128before
bitshiftingright,atricktoroundtothenearestinteger:
128is<<8

Changingthefilterlineabovefrom
filtered_value=((n<<8)n)>>8;

to
filtered_value=((n<<8)n+128)>>8;

Plottingtheresultgives:

Butit'sstillnotcorrect.Theproblemisthefiltered_valuevariabledoesnothave
enoughresolutiontoworkcorrectly.Withfloatingpointmathstheresolutionisin
thedecimalpoints,withintegermathswe'reroundingtothenearestinteger
value.
Thesolutionistouseascaledfiltered_valueforthe'evolving'filtered_value
variableandthendividethescaledfiltered_valuewhenweneedfiltered_value.
Thisgivesusahigherresolutiontoworkwithfortheevolvingfiltered_value
variable.
Letslookagainatthefilterequationabove:
n=last_filtered_value+samplelast_sample
filtered_value=(n256n)/256

Withabitofrearranging,wecanbringoutfiltered_valuemultipliedby256asour
higherresolution'evolving'filtered_value.
Ifwemovethe256totheleftsideoftheequation,wecanrewriteitas:
256filtered_value=n256n

(letscall256filtered_valueshifted_filter,asmultiplyingby256isthesameas
bitshiftingtotheleftbyeight(<<8))
ifwethencalculaten256separately:
shiftedFCL=256filtered_value+256(samplelast_sample)

(shiftedFCLstandsforbitshiftedFilter_value+Current_sampleLast_sample).
Byseparatingoutfiltered_valuefromsamplelast_samplewecanuse
theshifted_filtervalue:
shiftedFCL=shifted_filter+256(samplelast_sample)

Wecannowrewrite256filtered_value=n256nas:
shiftedFCL=shifted_filter+256(samplelast_sample)
shifted_filter=shiftedFCL(shiftedFCL/256)

Thefinalstepistodivideshifted_filterby256toarriveattheactual
filtered_value:
shiftedFCL=shifted_filter+256(samplelast_sample)
shifted_filter=shiftedFCL(shiftedFCL/256)
filtered_value=shifted_filter/256;

Replacingmultiplyby256anddivideby256withbitshiftoperatorsthecomplete
filterlookslikethis:
longshiftedFCL=shifted_filter+(long)((samplelast_sample)<<8);
shifted_filter=shiftedFCL(shiftedFCL>>8);
longfiltered_value=(shifted_filter+128)>>8;

Noticetheadditional128toimproverounding.
Examplecode:
intsample=0;
intlast_sample=0;
doublea=0;
longshifted_filter=10000;
voidsetup()
{
Serial.begin(9600);
}
voidloop()
{
//Generateatestsignal
last_sample=sample;
a+=0.1;sample=512+sin(a)*100;

longshiftedFCL=shifted_filter+(long)((samplelast_sample)<<8);
shifted_filter=shiftedFCL(shiftedFCL>>8);
longfiltered_value=(shifted_filter+128)>>8;

Serial.print(sample);
Serial.print('');
Serial.println(filtered_value);
delay(50);
}

Here'stheoutput:

Here'sanexampletoshowthatthefilterworkswellwithamorecomplex
waveform.Thewaveformbelowiswhatyou'dexpectfromamixtureofresistive
loadsandanonlinearswitchmodepowersupplyforsay,alaptopcomputer.

Digitallowpassfilter
Whyalowpassfilter?ThelowpassfilterwasintroducedwiththeMk2Energy
Routerwhichusesacommonbiassupply(bufferedbyanoperationalamplifier)to
supplytheoffsetvoltageforbothvoltageandcurrentchannels.Thefilteronlyhas
tobecalculatedonce,andtheresultingoffsetisnaturallythesameforboth
channelsandthereforecanbesubtractedfrombothreadings.Thisreduces
processingtimebyasignificantamount.
Thefloatingpointimplementationoftheclassiclowpassfilterlookslikethis:
filtered_value=last_filtered_value+0.004(samplelast_filtered_value)

Why0.004?Allthatisrequiredisareasonablysmallnumbertoprovidean
adequatelylongtimeconstantsothereislittleripplefromthe50Hzfundamental
frequencybeingmeasured.=0.004givesafiltertimeconstantof(1)/=
250sampleperiods.

Codeexample:
intsample=0;
doublea=0;
doublefiltered_value=0;
doublelast_filtered_value;
voidsetup()
{
Serial.begin(9600);
}
voidloop()
{
//Generateatestsignal
last_filtered_value=filtered_value;
a+=0.1;sample=512+sin(a)*100;

//Floatingmathsimplementationofhighpassfiltertakes3236microseconds
filtered_value=last_filtered_value+0.004*(samplelast_filtered_value);

Serial.print(sample);
Serial.print('');
Serial.println(filtered_value);
delay(50);
}

Unfortunately,thistakesquitealongtimetosettleandthereisstillasignificant
ripplepresent.Reducingthefilterconstantwillimprovetheripplebutworsenthe
settlingtimehoweverbecausewehaveagoodideaofwhatthefinalvalueshould
be,itispossibletopreloadthefilterbysettingtheinitialvalueoftheoutputto
512.Nowthatwehavepreloadedthefilter,thefilterconstantcanbereducedto

averysmallvaluewithoutforcingalongwaitwhilstthefiltersettlesbeforeuseful
readingscanbehad.Thisiswhattheoutputlookslikewithafilterof0.000122
therippleiscount.

Thistoocanbeconvertedtousethemuchfasterintegermaths,andherethe
filterisupdatedfromthevoltageinputeachtimethevoltageisread.Thissnippet
appearsintheinterruptserviceroutineofMartinRsPLLimplementationofthe
Mk2router.Ratherthanmultiplyingthedifferencebetweenthecurrentsample
andthelastfilteredvaluebyasmallnumber<<1,thefilteredvalueis
multipliedby1/(=213)instead.Thisgivesanof0.000122andatime
constantof8191samples.Therippleis0.1%,whichisabout1countwiththe
normalamplitudeofvoltageinput.Itincludesthefixforintegerrounding:
#defineFILTERSHIFT13
//forlowpassfilterstodetermineADCoffsets
#defineFILTERROUNDING(1<<12)
intvoltsOffset=512;
staticlongfVoltsOffset=512L<<13;

ISR(ADC_vect)//interrupthander
{
newV=sampleVvoltsOffset;//sampleVisthevaluereadbyADC,
//newVistheoutputvalue

fVoltsOffset+=(sampleVvoltsOffset);//updatethefilter
voltsOffset=(int)((fVoltsOffset+FILTERROUNDING)>>FILTERSHIFT);
}

(Thecurrentreadingisobtainedsimilarlybysubtractingtheoffset.)
Analternativealgorithmforderivingtheoffsetistomakeaninitialguessatthe
valueoftheoffset,subtracttheoffsetfromthereadingtogivethedesiredvalue,

andaccumulatethedesiredvaluesoveronemainscycle.Ideally,theresulting
valuewillbezero.Anyerrorisusedtocorrecttheoffsetforthenextcycle.This
algorithmsuffersfromthedisadvantagethat,unlessyouknowwhereamains
cyclestartsandends,additionalcodeisnecessarytodeterminethat.This
algorithmgivesabsolutelyzerorippleontheoutput,butifthebiasdriftsfromone
cycletothenext(unlikelythoughthisis,withstablevoltages),therewillbeastep
changefromonecycletothenext.
Mk2RouterLowPassFilterusingfloatingpointmaths:
(allvariablesexceptsampleV&sampleIaredeclaredasdouble)
if(startingNewCycle)
{
prevDCoffset=DCoffset;
DCoffset=prevDCoffset+(0.01*cumVdeltasThisCycle);
cumVdeltasThisCycle=0;
}
sampleVminusDC=sampleVDCoffset;
sampleIminusDC=sampleIDCoffset;
cumVdeltasThisCycle+=(sampleVDCoffset);

You might also like