Digital low pass filter for DC offset removal

Hi There
I’m new at this forum.
I’m not at all familiar with digital low pass filters.
I was taking a look to the EmonLib and regarding the following code snippet I would like to ask some question about it:

offsetI = offsetI + ((sampleI-offsetI)/1024);
filteredI = sampleI - offsetI;

I know that this is a Low pass filter to remove the DC bias from the I samples, but I cannot associate
each equation term with the low pas filter’s corresponding ones.
I would appreciate some help on that.
Thank you very much.

t

What is your reference text for the low pass filter? Are you looking at the continuous time mathematical form or the discrete time (“digital”) form?

Be assured that the filter does work. Here is Wikipedia’s explanation.
You have not copied the first line correctly, and that might be confusing you. The second line is not part of the filter, it is applying the filter’s output to remove the offset.

Hi Robert
Thank you for your answer.

Good day,

I have read the wikipedia’s explanation given by Mr. Robert.Wall. In the link, it is mentioned that the discrete-time implementation of a simple RC low-pass filter is as follow:

y[n] = αx[n] + (1-α)y[n-1]
with:
α = ∆t / (RC + ∆t)

It is also mentioned that this discrete-time implementation of a simple RC low-pass filter is the exponentially weighted moving average with:

αx[n] = input contribution
(1-α)y[n-1] = inertia from previous output

In EmonLib.cpp, the digital low pass filters are implemented as follow

(line 111) offsetV = offsetV + ((sampleV-offsetV)/1024);
(line 112) filteredV = sampleV - offsetV;
(line 113) offsetI = offsetI + ((sampleI-offsetI)/1024);
(line 111) filteredI = sampleI - offsetI;

From this implementation, I concluded that:

offsetV (and also offsetI) = inertia from previous output, equivalent to the term (1-α)y[n-1] in the Wikipedia reference.
((sampleV-offsetV)/1024) (and also ((sampleI-offsetI)/1024)) = input contribution, equivalent to αx[n] in the Wikipedia reference.

However, so far I don’t understand why does the term ((sampleV-offsetV)/1024) (and also ((sampleI-offsetI)/1024)) for the input contribution implemented in EmonLib.cpp doesnt have the constant α = ∆t / (RC + ∆t). Is there any special case where the values of α is neglegible while implementing the digital low pass filters in EmonLib.cpp?

One more thing, after the filtered values are calculated digitally in Line 111 and 113, why should the the SampleV (and SampleI) be deducted with offsetV (and offestI) in line 112 and 114?

Thank you.

I don’t understand why/what you don’t understand! In α = ∆t / (RC + ∆t), everything is constant, therefore there is no reason to replace that expression with anything other than a constant number. The optimum value for ripple reduction versus response time seemed to be round about 1/1000, so I made (1-α) exactly an inverse power of 2 to allow the compiler to optimise it to a very fast and simple bit-shift operation.

[Edit: If you are measuring only 14 samples per cycle, your ∆t is different, you will need a different α to maintain roughly the same time constant.]

What (physically) is represented by the quantity that the ADC is reading, i.e. the filter input? What is the title of this thread? What does the filter output represent? What does the ‘filtered’ variable represent - physically?
(If you cannot answer those questions by thinking about it, then go back and read Resources > Building Blocks about how we use the Arduino to measure electrical quantities: CT sensors - Interfacing with an Arduino & Measuring AC Voltage with an AC to AC power adapter)

Thank so much Foxfaisal
Best Regards,

Just a question about DC offset: what do you think about reading the mid-point voltage physically (using an analog input) instead of any digital procession?

Welcome, Robert, to the OEM forum.

It has of course been considered. The obvious problem, given that each analogue input has its own bias supply, is it requires a dedicated “correction” input for each “actual” input, thereby halving the number of analogue inputs available, and in effect halving the rate at which the actual analogue inputs can be read.

And it would not be possible in any case with the input arrangement of the emonTx V4.

I am thinking about the “Buffered Voltage Bias” method, when adding an operational amplifier for a solid mid-point voltage for all transformers (Voltage and CT).

In my test arrangement it seems to work ok:
hw - ARDUINO Uno + AC adapter + CT + LM324 as mid-point circuit
code - analogRead for Voltage, Current and MIDPOINT (I don’t use the emon hw and library)

You did not make that clear.

https://docs.openenergymonitor.org/electricity-monitoring/ctac/acac-buffered-voltage-bias.html

We need only one extra analog input.