3

I created a multiple feedback second order lowpass filter that amplifies and also adds a dc reference to the output.

Differencial seconde order multiple feedback lowpass filter

To simulate it, I created the code below that used to work in a previous MATLAB version. Now in the 2013a version, it's not working any longer.

clear all
close all

syms s Rf R1 R2 C1 Cf Vref V2 V1

Zf1 = R2+1/s/Cf;
Al1 = [(1/Zf1+1/Rf+1/R1+s*C1) (-s*C1) (0)];
Al2 = [(-s*C1) (1/Zf1+1/Rf+1/R1+s*C1) (-1/Zf1-1/Rf)];
Al3 = [(-1/Zf1/s/Cf) (1/Zf1/s/Cf) (-1/Zf1/s/Cf+1)];
A = [Al1; Al2; Al3];

B = [(Vref*(1/Zf1+1/Rf)+V2/R1) ;(V1/R1) ; (Vref*(1-1/Zf1/s/Cf))];
V=A^-1*B;

Vo = simplify(V(3));
Vo = collect(Vo,Vref);
pretty(Vo);

%damp = sqrt(2)/2;   % butterworth filter
%wc = 2*pi*150;
%coef_s = 2*damp/wc;

fc = 150;
[z,p,k] = butter(2,1,'low','s');

modpole = abs(p(1));
alpha = abs(real(p(1)));
damp = alpha/modpole;   

wc = 2*pi*fc*modpole;
coef_s = 2*damp/wc;

Gain_0Hz = 4.7;

clear syms
R1 = 1E3
Rf = Gain_0Hz*R1
Cf = 82E-9

R2calc = solve('Cf*(Rf*R2/R1+R2+Rf)=coef_s',R2);
R2 = eval(R2calc)

C1calc = solve('2*C1*Rf*R2*Cf=1/wc^2',C1);
C1 = eval(C1calc)

Hs = (Vo - Vref)/(V2-V1);
Hs = simplify(Hs);
pretty(Hs);
s = tf('s');
numHs = eval(Hs);    % ofending command, should replace sym s by tf('s') as previous versions.
bode(numHs);

Unfortunately, after I upgraded to the 2013a MATLAB, this code stopped working. The error shown is:

Error using evalin
Undefined function 'power' for input arguments of
type 'tf'.

Error in sym/eval (line 11)
s = evalin('caller',vectorize(map2mat(char(x))));

After applying the fix from @Fija, the normal operation was recovered. And the results are shown below:

  Vref - (Rf V1 - Rf V2) / (R1 + Cf R1 R2 s + Cf R1 Rf s + 

                                    2 
     Cf R2 Rf s + 2 C1 Cf R1 R2 Rf s )

R1 =

        1000


Rf =

        4700


Cf =

   8.2000e-08


R2 =

   2.3858e+03


C1 =

   6.1218e-07


  Rf / (R1 + Cf R1 R2 s + Cf R1 Rf s + Cf R2 Rf s + 

                       2 
     2 C1 Cf R1 R2 Rf s )

Bode diagram of resulting filter

Prophet Daniel
  • 327
  • 2
  • 15
  • 1
    Apparently, something is trying to apply the `power` function to your `tf('s')`, which doesn't work. I don't really get what you script is doing, but the problem is `power`, not `eval`. – scenia Feb 14 '14 at 13:45
  • 1
    Well I get `Undefined function 'tf' for input arguments of type 'char'`, so it seems like you haven't given us enough to recreate the problem. – user664303 Feb 14 '14 at 14:37
  • Oh, I see it's a function in the Control System Toolbox. – user664303 Feb 14 '14 at 16:56

2 Answers2

3

I don't really know why this works, but at least it does with matlab 2013b. Add one step that does a character conversion just before you evaluate Hs:

HsChar= char(Hs);
numHs = eval(HsChar);   
bode(numHs);
Fija
  • 195
  • 8
  • Thank you. Your advice made it work now. The odd thing is that it was working on Matlab 2007. I don't know what Mathworks did, but your solution gives exact the same results Matlab 2007 was presenting. Thank you! – Prophet Daniel Apr 30 '14 at 12:15
1

Try this from the link http://www.mathworks.com/matlabcentral/answers/6355-how-do-i-get-the-coefficients-of-this-symbolic-expression ,

[c,t] = coeffs(evalin(symengine,['denom(' char(Hs) ')']),s);

Right after pretty in the code. Then you can use eval on c to calculate the coeffieients, numerically, then it is just to use tf with these coefficients in the denominator. So,

s = tf('s');
numHs = eval(Hs);    % ofending command, should replace sym s by tf('s') as previous versions.
bode(numHs);

becomes,

[c,t] = coeffs(evalin(symengine,['denom(' char(Hs) ')']),s);
H = tf(nominator,denominator);
bode(H);

Because you already had the nominatior right? This should do the trick.

patrik
  • 4,506
  • 6
  • 24
  • 48