Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Problem with digital low pass filter

Status
Not open for further replies.

kekon

Full Member level 3
Joined
Sep 19, 2002
Messages
155
Helped
5
Reputation
10
Reaction score
3
Trophy points
1,298
Location
Poland, Białystok
Activity points
1,493
I have a problem with converting analog low pass RC filter into digital one. My goal is to realize digital feedback loop compensation in software. To begin with, i decided to do some training with the simplest RC filter. The low pass filter is built with R = 1000Ω resistor and C = 1µF capacitor. First i wrote the transfer function as G(s) = 1 / (sRC + 1). Then using bilinear transformation i converted it into z transform as G(z) = (b0 + b1 * z^-1) / (1 + a1 * z^-1). b0 = b1 = 0.0155 and a1 = -1. To realize the filter in software i used the IIR Direct Form I

(https://ccrma.stanford.edu/~jos/fp3/Direct_Form_I.html)

The to simulate it i created a function in C# language (to simulate it in my PC before i use it in a microcontroller).

The "Filter" function calculates its output value follows:


Code C# - [expand]
1
2
3
4
5
6
7
8
9
10
double InputValue = 2048;
 double OutputValue;
 
            for (int i = 0; i < 20; i++)
            {
                 OutputValue = InputValue * b0 + Reg1 * b1 + a1 * Reg2;
                 Reg1 = InputValue;
                 Reg2 = OutputValue;
                 Console.WriteLine(OutputValue.ToString());
            }



(initially the Reg1 and Reg2 equal to 0).

The problem is that the OutputValue always stays at constant value (for example it is 31.744 for InputValue = 2048) . I have no idea what i'm doing wrong. With this analog low pass filter the output value achievies the input value after some time when constant voltage is applied to it. In case with my digital filter it seems as it works like a voltage divider,not a filter... :(
 

I might be wrong but I think it should be "-a1*Reg2" and not "+a1*Reg2"

- - - Updated - - -

With this analog low pass filter the output value achievies the input value after some time when constant voltage is applied to it
To be precise, it reaches the input DC value after 3 ms in your case.
 

I might be wrong but I think it should be "-a1*Reg2" and not "+a1*Reg2"

- - - Updated - - -


To be precise, it reaches the input DC value after 3 ms in your case.

a1 is -1 so i think it is OK. Even when i use thousands of input samples it is always 31.744 at the output.
 

Try with this G(z)=z^-1/(1-3.72*10^-44*z^-1) (sampling time 0.1 s)
 

You forgot to mention the sampling frequency used in your Z transformation. a1=-1 is wrong in any case (refers to infinite time constant respectively an integrator).

I don't recognize the advantage of using Direct Form I. You need only one register when using e.g. observable canonical form.
 

Samplig frequency is 20 kHz.
Why 10^-44 ?
How the G(z)=z^-1/(1-3.72*10^-44*z^-1) equation should be realized ?
 

Why 10^-44 ?
Obviously wrong.

I get b0=b1=0.0244 and a1=-0.9512 for 20 kHz and bilinear transformation. Or use simpler step invariant transformation which shifts the output by a half sampling period; b0=0.0488, same a1.

Consider that ∑-an + ∑bn must be 1 for unity DC gain.
 
  • Like
Reactions: kekon

    kekon

    Points: 2
    Helpful Answer Positive Rating
Obviously wrong.

I get b0=b1=0.0244 and a1=-0.9512 for 20 kHz and bilinear transformation. Or use simpler step invariant transformation which shifts the output by a half sampling period; b0=0.0488, same a1.

Consider that ∑-an + ∑bn must be 1 for unity DC gain.

Yes, you're right. I made a mistake.
Now it works ! Thanks !
 

What's your plan for the rest of the control loop?

This RC code, plus a straight up integrator (which shuts off when saturation is detected) and a proportional term produce a Type II compensator very nicely (two poles and one zero).

My point is that I found it preferable to use discrete I and P terms rather than use a second order IIR for the same transfer function. I've done both and found the discrete implementation much preferable as the coefficients map directly to the shape on the bode plot, saturation is easy to deal with (pause the I accumulator) and subtle problems like quantification errors and precision problems are eliminated or easier to understand (on the other hand floating point helps with those two).
 

Indeed by using the Bilinear method you get to FvM's post #7 with 20 kHz sampling. However, I have gave you the zero-order hold with sampling time 0.1s because I did not know what was your sampling time. You can check the zero-order hold also for 20 kHz which is:
G(z)=0.04877/(z-0.9512)
 

My point was that 10^-44 can't be right in any case. You can't implement a 160 Hz low-pass with 10 Hz sampling frequency. If your calculator outputs coefficient numbers though, it's just an artifact. If you round the coefficients to implementable values, the post #4 "filter" does nothing except delaying the signal by one sample.

The "zero order hold" implementation is already given in post #7.
 
  • Like
Reactions: CataM

    CataM

    Points: 2
    Helpful Answer Positive Rating
What's your plan for the rest of the control loop?

Well, I design synchronous buck converter which will work in constant voltage and constant current mode. This converter will have also additional features. To realize this goal would require to use many components such as op-amps, resistors etc. I've been designing such converters and SMPS power supplies for some time now. As you know each converter requires frequency compensation. I came to the conlusion that it will be more convinient to use a microcontroller and realize the compensation loop in software (using small ARM microcontrollers). To start with, I decided to see how a simple low-pass digital filter works to learn some basics.
 

So I have experience doing the same thing - digitally controlled converter with both voltage and current modes.

The best simulation tool in my opinion for this is PSIM, which is targeted at exactly this. It has spice-like circuit simulation (though typically less detailed, for example gate drive is considered ideal) plus simulink-like signal processing and is very efficient at marrying the two.

The library includes a whole bunch of relevant signal processing blocks like "single pole low-pass filter", "z domain transfer function block", S-Domain, PID, etc but also lets you place C-code blocks that run your own code (this costs money but the other stuff should be in the free demo).

So I started with the high level blocks like "Type II Compensation" and moved step-by-step from that, to the Z-domain block, then to my own C-code implementation of the Z-domain block and its very easy to check each step along the way.
 

I looked for any free tool for converting s transform to z transform using bilinear transformation but i didn't find anything. I decided to write my own console application to do the job. If you are interested i can post it here.
 

You may as well post it but there are a few I'm aware of:

This is a great site in general with a biquad coefficient calculator:
https://www.earlevel.com/main/2010/12/20/biquad-calculator/

Octave is an open source version of Matlab which has the relevant coefficient calculating functions.

PSIM has a s2z converter utility that covers up to 3rd order conversion (I think this is available in the free demo).

The wikipedia article on 'bilinear transform' has a detailed walkthrough for a biquad'



Are you using fixed point or floating point math? Although the coefficients are relatively easy to calculate there are a whole bunch of implementation hazards that can wreak havoc on the end result. Particularly rounding problems and loss of precision with fixed point math can drastically alter the real life transfer function - particularly at the small values which an error amplifier will mostly be operating on.
 

The program uses floating point numbers (double type) with 15 precision digits. It was created in C# and needs .NET framework to be installed (in Windows 7 and later systems it is installed by default).
 

Attachments

  • bilinear_transform.zip
    9.4 KB · Views: 41

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top