function slide = opampdemo(slidenum)
%OPAMPDEMO  Feedback Amplifier Demo.
%
%   OPAMPDEMO demonstrates the design of a non-inverting feedback
%   amplifier circuit using the Control System Toolbox.  This design
%   is built around the operational amplifier (op amp), a standard
%   building block of electrical feedback circuits.
%
%   This tutorial demonstrates how a real electrical system can be
%   designed, modeled, and analyzed using the tools provided by the
%   Control System Toolbox.
%
%   Several important topics are covered:
%      - Creating LTI models
%      - Viewing system responses (BODE, STEP, etc.)
%      - Constructing feedback networks (FEEDBACK)
%      - System sensitivity analysis
%      - Stability margin analysis
%      - Compensator design & analysis (feedback lead compensation)
%      - Using LTI arrays

%   Authors: A. DiVergilio
%   Copyright 1986-2000 The MathWorks, Inc.
%   $Revision: 1.4 $  $Date: 2000/08/08 18:28:09 $

if nargin==0
   %---Start demo
   if nargout==0
      fg = playshow(mfilename);
      set(fg,'Name','Feedback Amplifier Demo','DoubleBuffer','on');
      return
   end
   %---Construct slides
   slidenum = 0;

   %========== Slide 1 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' This demo illustrates the design of a non-inverting feedback'
      ' amplifier circuit using the Control System Toolbox.'
      ' '
      ' The standard building block of electrical feedback circuits is'
      ' the operational amplifier (op amp), a differential voltage'
      ' amplifier designed to have extremely high dc gain, often in'
      ' the range of 1e5 to 1e7.'
      ' '
      ' The electrical symbol for the op amp is shown above.'
   };

   %========== Slide 2 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' This demo assumes the use of an uncompensated op amp with 2'
      ' poles (at frequencies w1,w2) and high dc gain (a0).  Assuming'
      ' this op amp is operated in its linear mode (not saturated), '
      ' then its open-loop transfer function can be represented as a'
      ' linear time-invariant (LTI) system, as shown above.'
      ' '
      ' Though higher-order poles will exist in a physical op amp, it'
      ' has been assumed in this case that these poles lie in a frequency'
      ' range where the magnitude has dropped well below unity.'
   };

   %========== Slide 3 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' The following system parameters are assumed:'
      ' '
      ' >> a0 = 1e5;'
      ' >> w1 = 1e4;'
      ' >> w2 = 1e6;'
      ' '
      ' Next, you want to create a transfer function model of this system'
      ' using the Control System Toolbox.  This model will be stored in'
      ' the MATLAB workspace as an LTI object.'
   };

   %========== Slide 4 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' First, define the Laplace variable, s, using the TF command.  Then'
      ' use ''s'' to construct the open-loop transfer function, a(s):'
   };

   %========== Slide 5 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' You can view the frequency response of a(s) using the BODE command:'
      ' '
      ' >> bode(a,''r'')'
      ' '
      ' Right-click on the plot to access a menu of properties for this'
      ' Bode Diagram.  Left-click on the curves to create moveable data'
      ' markers which can be used to obtain response details.'
   };

   %========== Slide 6 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' You can view the normalized step response of a(s) using the STEP'
      ' and DCGAIN commands:'
      ' '
      ' >> a_norm = a / dcgain(a);'
      ' >> step(a_norm,''r'')'
      ' '
      ' Right-click on the plot and select "Characteristics -> Settling Time"'
      ' to display the settling time. Hold the mouse over the settling time'
      ' marker to reveal the exact value of the settling time.'
   };

   %========== Slide 7 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' Now add a resistive feedback network and wire the system as a'
      ' non-inverting amplifier.'
      ' '
      ' This feedback network, b(s), is simply a voltage divider with'
      ' input Vo and output Vn.  Solving for the ratio Vn/Vo yields the'
      ' transfer function for b(s):'
      ' '
      '      b  =  Vn / Vo  =  R1 / (R1 + R2) '
   };

   %========== Slide 8 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' The block diagram representation of the system is shown above.'
      ' '
      ' Solving for the ratio Vo/Vp yields the closed-loop gain, A(s):'
      ' '
      '      A  =  Vo / Vp  =  a / (1 + ab)'
      ' '
      ' If the product ''ab'' is sufficiently large (>>1), then A(s) may'
      ' be approximated as'
      ' '
      '      A  =  1 / b'
   };

   %========== Slide 9 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' Now assume that you need to design an amplifier of dc gain 10 and'
      ' that R1 is fixed at 10 kOhm.  Solving for R2 yields:'
      ' '
      ' >> A0 = 10;'
      ' >> b = 1 / A0;    % approximation for ab>>1'
      ' >> R1 = 10000;'
      ' >> R2 = R1 * (1/b - 1)'
      ' '
      ' R2 = '
      '            90000'
   };

   %========== Slide 10 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' Construct the closed-loop system using the FEEDBACK command:'
      ' '
      ' >> A = feedback(a,b);'
      ' '
      ' Next, plot the frequency responses of a(s) and A(s) together'
      ' using the BODE command:'
      ' '
      ' >> bode(a,''r'',A,''b'')'
   };

   %========== Slide 11 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' The use of negative feedback to reduce the low-frequency (LF) gain'
      ' has led to a corresponding increase in the system bandwidth (defined'
      ' as the frequency where the gain drops 3dB below its maximum value).'
      ' '
      ' This gain / bandwidth tradeoff is a powerful tool in the design of'
      ' feedback amplifier circuits.'
      ' '
      ' Since the gain is now dominated by the feedback network, a useful'
      ' relationship to consider is the sensitivity of this gain to'
      ' variation in the op amp''s natural (open-loop) gain.'
   };

   %========== Slide 12 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' Before deriving the system sensitivity, however, it is useful to'
      ' define the loop gain, L(s), which is the total gain a signal'
      ' experiences traveling around the loop:'
      ' '
      ' >> L = a * b;'
      ' '
      ' You will use this quantity to evaluate the system sensitivity'
      ' and stability margins.'
   };

   %========== Slide 13 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' The system sensitivity, S(s), represents the sensitivity of A(s) to'
      ' variation in a(s).  The inverse relationship between S(s) and L(s)'
      ' reveals another benefit of negative feedback: "gain desensitivity".'
      ' '
      ' >> S = 1 / (1 + L);'
      ' '
      ' S(s) has the same form as the feedback equation and, therefore, may'
      ' be constructed using the more-robust FEEDBACK command:'
      ' '
      ' >> S = feedback(1,L);'
   };

   %========== Slide 14 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' The magnitudes of S(s) and A(s) may be plotted together using the'
      ' BODEMAG command:'
      ' '
      ' >> bodemag(A,''b'',S,''g'')'
      ' '
      ' The very small low-frequency sensitivity (about -80 dB) indicates'
      ' a design whose closed-loop gain suffers minimally from open-loop'
      ' gain variation.  Such variation in a(s) is common due to '
      ' manufacturing variability, temperature change, etc.'
   };

   %========== Slide 15 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' You can check the step response of A(s) using the STEP command:'
      ' '
      ' >> step(A)'
      ' '
      ' Note that the use of feedback has greatly reduced the settling'
      ' time (by about 98%).  However, the step response now displays'
      ' a large amount of ringing, indicating poor stability margin.'
   };

   %========== Slide 16 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' You can analyze the stability margin by plotting the loop gain,'
      ' L(s), with the MARGIN command:'
      ' '
      ' >> margin(L)'
      ' '
      ' The resulting plot indicates a phase margin of less than 6 degrees.'
      ' You will need to compensate this amplifier in order to raise the'
      ' phase margin to an acceptable level (generally 45 deg or more),'
      ' thus reducing excessive overshoot and ringing.'
   };

   %========== Slide 17 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' A commonly used method of compensation in this type of circuit is'
      ' "feedback lead compensation".  This technique modifies b(s) by'
      ' adding a capacitor, C, in parallel with the feedback resistor, R2.'
      ' '
      ' The capacitor value is chosen so as to introduce a phase lead to'
      ' b(s) near the crossover frequency, thus increasing the amplifier''s'
      ' phase margin.'
   };

   %========== Slide 18 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' The new feedback transfer function is shown above.'
      ' '
      ' You can approximate a value for C by placing the zero of b(s) at'
      ' the 0dB crossover frequency of L(s):'
      ' '
      ' >> [Gm,Pm,Wcg,Wcp] = margin(L);'
      ' >> C = 1/(R2*Wcp)'
      ' '
      ' C = '
      '            1.1139e-12'
   };

   %========== Slide 19 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' To study the effect of C on the amplifier response, create an LTI'
      ' model array of b(s) for several values of C around your initial'
      ' guess:'
      ' '
      ' >> K = R1/(R1+R2);'
      ' >> C = [1:.2:3]*1e-12;'
      ' >> for n = 1:length(C)'
      '         b_array(:,:,n) = tf([K*R2*C(n) K],[K*R2*C(n) 1]);'
      '      end'
   };

   %========== Slide 20 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' Now you can create LTI arrays for A(s) and L(s):'
      ' '
      ' >> A_array = feedback(a,b_array);'
      ' >> L_array = a*b_array;'
      ' '
      ' You can plot the step response of all models in the LTI array,'
      ' A_array(s), together with A(s) using the STEP command:'
      ' '
      ' >> step(A,''b:'',A_array,''b'');'
   };

   %========== Slide 21 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' The phase margins for our loop gain array, L_array(s), are found'
      ' using the MARGIN command:'
      ' '
      ' >> [Gm,Pm,Wcg,Wcp] = margin(L_array);'
      ' '
      ' The phase margins may now be plotted as a function of C:'
      ' '
      ' >> plot(C*1e12,Pm,''g'');'
      ' '
      ' A maximum phase margin of 58 deg is obtained when C=2pF (2e-12).'
   };

   %========== Slide 22 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' The model corresponding to C=2pF is the sixth model in the LTI'
      ' array, b_array(s).  You can plot the step response of the closed-'
      ' loop system for this model by selecting index 6 of the LTI array'
      ' A_array(s):'
      ' '
      ' >> A_comp = A_array(:,:,6);'
      ' >> step(A,''b:'',A_comp,''b'')'
      ' '
      ' Note that the settling time has been further reduced (by an'
      ' additional 85%).'
   };

   %========== Slide 23 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' We can overlay the frequency-response of all three models'
      ' (open-loop, closed-loop,compensated closed-loop) using the'
      ' BODE command:'
      ' '
      ' >> bode(a,''r'',A,''b:'',A_comp,''b'')'
      ' '
      ' Note how the addition of the compensation capacitor has'
      ' eliminated peaking in the closed-loop gain and also greatly'
      ' extended the phase margin.'
   };

   %========== Slide 24 ==========
   slidenum = slidenum+1;
   slide(slidenum).code={sprintf('%s(%d)',mfilename,slidenum)};
   slide(slidenum).text={
      ' A brief summary of the choice of component values in the design'
      ' of this non-inverting feedback amplifier circuit:'
      ' '
      ' * A resistive feedback network (R1,R2) was selected to yield a'
      '    broadband amplifier gain of 10 (20 dB).'
      ' '
      ' * Feedback lead compensation was used to tune the loop gain near'
      '    near the crossover frequency.  The value for the compensation'
      '    capacitor, C, was optimized to provide a maximum phase margin'
      '    of about 58 degrees.' 
   };

%---Slide code
else
   [tag,action] = democlean(slidenum);
   if strcmpi(action,'autoplay'), action='next'; end

   %---Common layout parameters
    p = localParameters;
    ax = gca;

   %---Slides
   switch slidenum
   case 1
      localCanvas(ax)
      set(ax,'Position',[0.085 0.49 0.65 0.45]);
      delete(findobj(get(gcbf,'Children'),'flat','UserData','DeleteMe'));
      axis(ax,'equal');
      text('Parent',ax,'String','Ideal Op Amp','Position',[.5 .8],...
         'FontSize',p.fs3,'FontWeight',p.fw3,'Hor','center','Ver','middle','Tag',tag);
      opamp('Parent',ax,'Position',[.2 .3 .6 .2],'FaceColor',[1 1 .9],'FontSize',p.fs2,'FontWeight',p.fw2,...
         'Name','a','ShowTerminals',1,'Label',{'Vp','Vn','Vo'},'Info2','Vo = a(Vp - Vn)','Tag',tag);

   case 2
      axis(ax,'normal'); set(ax,'XLim',[0 1],'YLim',[0 1]);
      text('Parent',ax,'Position',[0 0.8],'String','Open-Loop Transfer Function:',...
         'FontSize',p.fs3,'FontWeight',p.fw3,'Hor','left','Ver','bottom','Tag',tag);
      equation('Parent',ax,'Position',[.25 .6],'Name','a(s)','Num','a_{0}','Den','(1 + s/\omega_1)(1 + s/\omega_2)',...
         'Color',[.8 0 0],'Anchor','left','FontSize',p.fs3,'Tag',tag);

   case 3
      axis(ax,'normal'); set(ax,'XLim',[0 1],'YLim',[0 1]);
      text('Parent',ax,'Position',[0 0.8],'String','Open-Loop Transfer Function:',...
         'FontSize',p.fs3,'FontWeight',p.fw3,'Hor','left','Ver','bottom','Tag',tag);
      equation('Parent',ax,'Position',[.25 .6],'Name','a(s)','Num','a_{0}','Den','(1 + s/\omega_1)(1 + s/\omega_2)',...
         'Anchor','left','FontSize',p.fs3,'Tag',tag);
      equation('Parent',ax,'Position',[.25 0.30],'Name','a_{0}','Num','10^{5}',...
         'Color',[.8 0 0],'Anchor','left','FontSize',p.fs3,'Tag',tag);
      equation('Parent',ax,'Position',[.25 0.15],'Name','\omega_{1}','Num','10^4',...
         'Color',[.8 0 0],'Anchor','left','FontSize',p.fs3,'Tag',tag);
      equation('Parent',ax,'Position',[.25 0.00],'Name','\omega_{2}','Num','10^6',...
         'Color',[.8 0 0],'Anchor','left','FontSize',p.fs3,'Tag',tag);

   case 4
      if strcmpi(action,'back')
         localCanvas(ax)
      end
      axis(ax,'normal'); set(ax,'XLim',[0 1],'YLim',[0 1]);
      text('Parent',ax,'Position',[0 0.8],'String','Open-Loop Transfer Function:',...
         'FontSize',p.fs3,'FontWeight',p.fw3,'Hor','left','Ver','bottom','Tag',tag);
      equation('Parent',ax,'Position',[.25 .6],'Name','a(s)','Num','a_{0}','Den','(1 + s/\omega_1)(1 + s/\omega_2)',...
         'Anchor','left','FontSize',p.fs3,'Tag',tag);
      equation('Parent',ax,'Position',[.25 0.30],'Name','a_{0}','Num','10^{5}',...
         'Anchor','left','FontSize',p.fs3,'Tag',tag);
      equation('Parent',ax,'Position',[.25 0.15],'Name','\omega_{1}','Num','10^4',...
         'Anchor','left','FontSize',p.fs3,'Tag',tag);
      equation('Parent',ax,'Position',[.25 0.00],'Name','\omega_{2}','Num','10^6',...
         'Anchor','left','FontSize',p.fs3,'Tag',tag);
      text('Parent',ax,'Position',[0.9 0],'String',{'LTI','Object'},...
         'FontSize',p.fs2,'FontWeight',p.fw2,'Color',[.8 0 0],'Hor','center','Ver','middle','Tag',tag);
      wire('Parent',ax,'XData',[0.58 0.78],'YData',[0.12 0.02],'Color',[.8 0 0],'ArrowSize',p.as*1.5,'Tag',tag);
      wire('Parent',ax,'XData',[0.65 0.8],'YData',[0.3 0.1],'Color',[.8 0 0],'ArrowSize',p.as*1.5,'Tag',tag);
      ud = get(gcbf,'UserData');
      pp = get(ud.txthandle,'Position');
      str = {
      '  >> s = tf(''s'');          '
      '  >> a = a0/(1+s/w1)/(1+s/w2)'
      '                             '
      '  Transfer function:         '
      '            100000           '
      '  -------------------------- '
      '  1e-10 s^2 + 0.000101 s + 1 '};
      uicontrol('Parent',gcbf,'Style','text','FontName','FixedWidth','FontSize',get(ud.txthandle,'FontSize'),...
         'Back',get(ud.txthandle,'Back'),'Units','norm','Position',[pp(1) pp(2) pp(3) pp(4)*length(str)/10],...
         'String',str,'Hor','left','Tag',tag,'UserData','DeleteMe');

   case 5
      if strcmpi(action,'next')
         reset(ax)
      end
      a = p.a;
      bode(a,'r',p.Frequency1)
      set(gcr,'FrequencyUnits','rad/sec','MagnitudeUnits','dB','PhaseUnits','deg',...
         'UnwrapPhase','on','Grid','off','YLim',{[0 110],[-180 0]});
      setscale(gcr,'FrequencyScale','log');

   case 6
      if strcmpi(action,'back')
         reset(ax)
      end
      a = p.a;
      a_norm = p.a_norm;
      step(a_norm,'r',p.Time1)
      set(gcr,'Grid','off','SettlingTimeThreshold',.02,'YLim',{[0 1.1]},...
         'YLabel','Normalized Amplitude','Title','Normalized Open-Loop Step Response');
      pa = get(gcr,'PlotAxes');
      equation('Parent',pa(1),'Position',[1.4e-4 .6],'Num','step(a)','Den','dcgain(a)',...
         'FontSize',p.fs1,'FontWeight',p.fw1,'Color',[0 0 0],'Anchor','left','Tag',tag);

   case 7
      if strcmpi(action,'next')
         localCanvas(ax)
      end
      axis(ax,'equal'); set(ax,'XLim',[0 1.2],'YLim',[0 1.2]);
      x = 0.7;
      y = 0.8;
      opamp('Parent',ax,'Position',[x-.6 y-.1 .6 .2],'FaceColor',[1 1 .9],...
         'FontSize',p.fs2,'FontWeight',p.fw2,'Name','a','Tag',tag);
      resistor('Parent',ax,'Position',[x-.30 y-.35],'Size',.25,'Tag',tag);
      text('Parent',ax,'String','R2','Position',[x-0.30+.2 y-.42],...
         'FontSize',p.fs2,'FontWeight',p.fw2,'Hor','center','Ver','top','Tag',tag);
      resistor('Parent',ax,'Position',[x-.45 y-.40],'Size',.25,'Angle',-90,'Tag',tag);
      text('Parent',ax,'String','R1','Position',[x-0.38 y-.40-.2],...
         'FontSize',p.fs2,'FontWeight',p.fw2,'Hor','left','Ver','middle','Tag',tag);
      wire('Parent',ax,'XData',x+[-.75 -.6 NaN -.6 -.6 -.3 NaN -.45 -.45 NaN -.05 .05 .05 NaN 0 .2 NaN -.45 -.45],...
         'YData',y+[.1 .1 NaN -.1 -.35 -.35 NaN -.35 -.40 NaN -.35 -.35 0 NaN 0 0 NaN -.65 -.7],'Tag',tag);
      ground('Parent',ax,'Position',[x-.45 y-.70],'Size',.14,'Tag',tag);
      line('Parent',ax,'LineStyle','--','LineWidth',1,'Clipping','off',...
         'XData',x+[-.55 0 0 -.55 -.55],'YData',y+[-.68 -.68 -.25 -.25 -.68],'Tag',tag);
      text('Parent',ax,'String',' Feedback network, b(s)','Position',[x y-.6],...
         'FontSize',p.fs1,'FontWeight',p.fw1,'Hor','left','Ver','middle','Tag',tag);
      xx = x + [-.75 -.6 .2];
      yy = y + [.1 -.225 0];
      line('Parent',ax,'LineWidth',2,'LineStyle','none','Marker','o','MarkerSize',6,...
         'MarkerFaceColor','w','XData',xx([1 3]),'YData',yy([1 3]),'Tag',tag);
      text('Parent',ax,'String','Vp  ','Position',[xx(1) yy(1)],...
         'FontSize',p.fs2,'FontWeight',p.fw2,'Hor','right','Ver','middle','Tag',tag);
      text('Parent',ax,'String','Vn ', 'Position',[xx(2) yy(2)],...
         'FontSize',p.fs2,'FontWeight',p.fw2,'Hor','right','Ver','middle','Tag',tag);
      text('Parent',ax,'String','  Vo','Position',[xx(3) yy(3)],...
         'FontSize',p.fs2,'FontWeight',p.fw2,'Hor','left', 'Ver','middle','Tag',tag);

   case {8,9}
      if (slidenum==8) & strcmpi(action,'next')
         axis(ax,'equal'); set(ax,'XLim',[0 1],'YLim',[0 1]);
      elseif (slidenum==9) & strcmpi(action,'back')
         localCanvas(ax)
         axis(ax,'equal'); set(ax,'XLim',[0 1],'YLim',[0 1]);
      end
      y1 = 0.65;
      y2 = 0.15;
      x1 = -0.1;
      x2 = 1.04;
      rw1 = .74;
      rw2 = .4;
      xstart = x1-.2;
      xend = x2+.15;
      sumblock('Parent',ax,'Position',[x1 y1],'Radius',p.sbr,'LabelRadius',3*p.sbr,'Tag',tag);
      sysblock('Parent',ax,'Position',[(x2+x1)/2-rw1/2 y1-.15 rw1 .30],...
         'Name','op amp, a(s)','Numerator','a_{0}','Denominator','(1+s/\omega_{1})(1+s/\omega_{2})',...
         'FaceColor',[1 1 .9],'FontSize',p.fs1,'FontWeight',p.fw1,'Tag',tag);
      sysblock('Parent',ax,'Position',[(x2+x1)/2-rw2/2 y2-.15 rw2 .30],...
         'Name','feedback network, b(s)','Numerator','R1','Denominator','R1 + R2',...
         'FaceColor',[1 1 .9],'FontSize',p.fs1,'FontWeight',p.fw1,'Tag',tag);
      wire('Parent',ax,'XData',[xstart x1-p.sbr],         'YData',[y1 y1],         'ArrowSize',p.as,'Tag',tag);
      wire('Parent',ax,'XData',[x1+p.sbr (x2+x1)/2-rw1/2],'YData',[y1 y1],         'ArrowSize',p.as,'Tag',tag);
      wire('Parent',ax,'XData',[(x2+x1)/2+rw1/2 xend],    'YData',[y1 y1],         'ArrowSize',p.as,'Tag',tag);
      wire('Parent',ax,'XData',[x2 x2 (x2+x1)/2+rw2/2],   'YData',[y1 y2 y2],      'ArrowSize',p.as,'Tag',tag);
      wire('Parent',ax,'XData',[(x2+x1)/2-rw2/2 x1 x1],   'YData',[y2 y2 y1-p.sbr],'ArrowSize',p.as,'Tag',tag);
      text('Parent',ax,'String','Vp ','Position',[xstart y1],...
         'FontSize',p.fs2,'FontWeight',p.fw2,'Hor','right','Ver','middle','Tag',tag);
      text('Parent',ax,'String','Vn ','Position',[x1 y2],...
         'FontSize',p.fs2,'FontWeight',p.fw2,'Hor','right','Ver','middle','Tag',tag);
      text('Parent',ax,'String',' Vo','Position',[xend y1],...
         'FontSize',p.fs2,'FontWeight',p.fw2,'Hor','left', 'Ver','middle','Tag',tag);
      if (slidenum==9)
         text('Parent',ax,'String',{'Vo/Vp = 10','(dc)'},'Position',[x2+.05 y1+.14],...
            'Color',[.8 0 0],'FontSize',p.fs1,'FontWeight',p.fw1,'Hor','center','Ver','middle','Tag',tag);
         text('Parent',ax,'String',{'R1 = 10000','R2 = 90000'},'Position',[x2-.18 y2-.14],...
            'Color',[.8 0 0],'FontSize',p.fs1,'FontWeight',p.fw1,'Hor','left','Ver','middle','Tag',tag);
      end

   case {10,11}
      if ((slidenum==10) & strcmpi(action,'next')) | ((slidenum==11) & strcmpi(action,'back'))
         reset(ax)
         a = p.a;
         A = p.A;
         bode(a,'r',A,'b',p.Frequency1)
         set(gcr,'FrequencyUnits','rad/sec','MagnitudeUnits','dB','PhaseUnits','deg',...
            'UnwrapPhase','on','Grid','off','YLim',{[0 110],[-180 0]});
         setscale(gcr,'FrequencyScale','log');
      end
      pa = get(gcr,'PlotAxes');
      if slidenum==10
         text('Parent',pa(1),'Position',[2e5 80],'String','Open-Loop Gain (a)',...
            'Hor','left','Ver','bottom','FontSize',p.fs1,'Tag',tag);
         text('Parent',pa(1),'Position',[2e3 27],'String','Closed-Loop Gain (A)',...
            'Hor','left','Ver','bottom','FontSize',p.fs1,'Tag',tag);
      elseif slidenum==11
         CC = [1 0 1];
         %---Logarithmic arrows:  dd=log2(x2)-log2(x1); x3=pow2(log2(x2)+dd);
         line('Parent',pa(1),'LineWidth',2,'Color',CC,'XData',[2e3 2e3],'YData',[25 95],'Tag',tag);
         patch('Parent',pa(1),'EdgeColor',CC,'FaceColor',CC,'XData',[1.6e3 2e3 2.5e3],'YData',[40 25 40],'Tag',tag);
         line('Parent',pa(1),'LineWidth',2,'Color',CC,'XData',[2e3 1e7],'YData',[10 10],'Tag',tag);
         patch('Parent',pa(1),'EdgeColor',CC,'FaceColor',CC,'XData',[7e6 1e7 7e6],'YData',[2 10 18],'Tag',tag);
         text('Parent',pa(1),'Position',[2e3 82],'String',' Reduced LF gain',...
            'Hor','left','Ver','top','FontSize',p.fs1,'Tag',tag);
         text('Parent',pa(1),'Position',[1.3e5 24],'String','Increased system bandwidth',...
            'Hor','center','Ver','bottom','FontSize',p.fs1,'Tag',tag);
      end

   case 12
      if strcmpi(action,'next')
         localCanvas(ax)
         axis(ax,'normal'); set(ax,'XLim',[0 1],'YLim',[0 1]);
      end
      text('Parent',ax,'Position',[0 0.8],'String','Loop Gain:',...
         'FontSize',p.fs3,'FontWeight',p.fw3,'Hor','left','Ver','bottom','Tag',tag);
      equation('Parent',ax,'Position',[.5 .6],'Name','L(s)','Num','a(s)b(s)',...
         'Anchor','equal','FontSize',p.fs3,'Tag',tag);

   case 13
      if strcmpi(action,'back')
         localCanvas(ax)
         axis(ax,'normal'); set(ax,'XLim',[0 1],'YLim',[0 1]);
      end
      text('Parent',ax,'Position',[0 0.8],'String','System Sensitivity:',...
         'FontSize',p.fs3,'FontWeight',p.fw3,'Hor','left','Ver','bottom','Tag',tag);
      equation('Parent',ax,'Position',[.5 0.6],'Name','S','Num','\deltaA/A','Den','\deltaa/a',...
         'Anchor','equal','FontSize',p.fs3,'Tag',tag);
      equation('Parent',ax,'Position',[.5 0.3],'Name',' ','Num','1','Den','1 + a(s)b(s)',...
         'Anchor','equal','FontSize',p.fs3,'Tag',tag);
      equation('Parent',ax,'Position',[.5 0.0],'Name',' ','Num','1','Den','1 + L(s)',...
         'Anchor','equal','FontSize',p.fs3,'Tag',tag);

   case 14
      if strcmpi(action,'next')
         reset(ax)
      end
      A = p.A;
      S = p.S;
      bodemag(A,'b',S,'g',p.Frequency1)
      set(gcr,'FrequencyUnits','rad/sec','MagnitudeUnits','dB','PhaseUnits','deg',...
         'UnwrapPhase','on','Grid','off','YLim',{[-90 50]});
      setscale(gcr,'FrequencyScale','log');
      pa = get(gcr,'PlotAxes');
      text('Parent',pa(1),'Position',[3e4 15],'String',{'Closed-Loop Gain','(A)'},...
         'FontSize',p.fs1,'FontWeight',p.fw1,'Hor','center','Ver','top','Tag',tag);
      text('Parent',pa(1),'Position',[2e6 -45],'String',{'System','Sensitivity','(S)'},...
         'FontSize',p.fs1,'FontWeight',p.fw1,'Hor','center','Ver','top','Tag',tag);

   case 15
      A = p.A;
      step(A,'b',p.Time2)
      set(gcr,'Grid','off','SettlingTimeThreshold',.02,'Title','Closed-Loop Step Response');
      pa = get(gcr,'PlotAxes');
      text('Parent',pa(1),'Position',[2.4e-6 15],'String','Excessive ringing  \rightarrow  poor phase margin',...
         'FontSize',p.fs1,'FontWeight',p.fw1,'Hor','left','Ver','middle','Tag',tag);

   case 16
      if strcmpi(action,'back')
         reset(ax)
      end
      L = p.L;
      margin(L)
      set(gcr,'FrequencyUnits','rad/sec','MagnitudeUnits','dB','PhaseUnits','deg',...
         'Grid','off','YLim',{[-10 90],[-180 0]});
      setscale(gcr,'FrequencyScale','log');
      pa = get(gcr,'PlotAxes');
      text('Parent',pa(1),'Position',[6e5 50],'String','Loop Gain (L)',...
         'FontSize',p.fs1,'FontWeight',p.fw1,'Hor','left','Ver','bottom','Tag',tag);

   case 17
      if strcmpi(action,'next')
         localCanvas(ax)
      end
      axis(ax,'equal'); set(ax,'XLim',[0 1.2],'YLim',[0 1.2]);
      x = 0.8;
      y = 0.8+.08;
      dd = 0.2;
      text('Parent',ax,'Position',[x-1.1 y-.3],'String',{'Feedback','Lead','Compensation'},...
         'FontSize',p.fs2,'FontWeight',p.fw2,'Color',[.8 0 0],'Hor','center','Ver','middle','Tag',tag);
      opamp('Parent',ax,'Position',[x-.6 y-.1 .6 .2],'FaceColor',[1 1 .9],...
         'FontSize',p.fs2,'FontWeight',p.fw2,'Name','a','Tag',tag);
      capacitor('Parent',ax,'Position',[x-.30 y-.35+.02],'Size',.25,'Color',[.8 0 0],'Tag',tag);
      text('Parent',ax,'String','C','Position',[x-0.30+.2 y-.42+.02],...
         'FontSize',p.fs2,'FontWeight',p.fw2,'Color',[.8 0 0],'Hor','center','Ver','top','Tag',tag);
      resistor('Parent',ax,'Position',[x-.30 y-.35-dd],'Size',.25,'Tag',tag);
      text('Parent',ax,'String','R2','Position',[x-0.30+.2 y-.42-dd],...
         'FontSize',p.fs2,'FontWeight',p.fw2,'Hor','center','Ver','top','Tag',tag);
      resistor('Parent',ax,'Position',[x-.45 y-.40-dd],'Size',.25,'Angle',-90,'Tag',tag);
      text('Parent',ax,'String','R1','Position',[x-0.38 y-.40-.2-dd],...
         'FontSize',p.fs2,'FontWeight',p.fw2,'Hor','left','Ver','middle','Tag',tag);
      wire('Parent',ax,'XData',x+[-.75 -.6 NaN -.6 -.6 -.3 NaN -.45 -.45 NaN -.05 .05+.05 .05+.05 NaN 0 .2+.05 NaN -.45 -.45],...
         'YData',y+[.1 .1 NaN -.1 -.35-dd -.35-dd NaN -.35-dd -.40-dd NaN -.35-dd -.35-dd 0 NaN 0 0 NaN -.65-dd -.7-dd],'Tag',tag);
      wire('Parent',ax,'Color',[.8 0 0],'XData',x+[-.35 -.35 -.3 NaN -.05 0 0],...
         'YData',y+[-.35-dd -.35+.02 -.35+.02 NaN -.35+.02 -.35+.02 -.35-dd],'Tag',tag);
      ground('Parent',ax,'Position',[x-.45 y-.70-dd],'Size',.14,'Tag',tag);
      line('Parent',ax,'LineStyle','--','LineWidth',1,...
         'XData',x+[-.55 0.05 0.05 -.55 -.55],'YData',y+[-.68-dd -.68-dd -.25 -.25 -.68-dd],'Tag',tag);
      text('Parent',ax,'String',' Feedback network, b(s)','Position',[x+.05 y-.6-dd],...
         'FontSize',p.fs1,'FontWeight',p.fw1,'Hor','left','Ver','middle','Tag',tag);
      xx = x + [-.75 -.6 .2+.05];
      yy = y + [.1 -.225-dd 0];
      line('Parent',ax,'LineWidth',2,'LineStyle','none','Marker','o',...
         'MarkerSize',6,'MarkerFaceColor','w','XData',xx([1 3]),'YData',yy([1 3]),'Tag',tag);
      text('Parent',ax,'String','Vp  ','Position',[xx(1) yy(1)],...
         'FontSize',p.fs2,'FontWeight',p.fw2,'Hor','right','Ver','middle','Tag',tag);
      text('Parent',ax,'String','Vn ', 'Position',[xx(2) yy(2)],...
         'FontSize',p.fs2,'FontWeight',p.fw2,'Hor','right','Ver','middle','Tag',tag);
      text('Parent',ax,'String','  Vo','Position',[xx(3) yy(3)],...
         'FontSize',p.fs2,'FontWeight',p.fw2,'Hor','left', 'Ver','middle','Tag',tag);

   case 18
      if strcmpi(action,'next')
         axis(ax,'equal'); set(ax,'XLim',[0 1],'YLim',[0 1]);
      end
      y1 = 0.65;
      y2 = 0.15;
      x1 = -0.1;
      x2 = 1.04;
      rw1 = .74;
      rw2 = .56;
      xstart = x1-.2;
      xend = x2+.15;
      sumblock('Parent',ax,'Position',[x1 y1],'Radius',p.sbr,'LabelRadius',3*p.sbr,'Tag',tag);
      sysblock('Parent',ax,'Position',[(x2+x1)/2-rw1/2 y1-.15 rw1 .30],...
         'Name','op amp, a(s)','Numerator','a_{0}','Denominator','(1+s/\omega_{1})(1+s/\omega_{2})',...
         'FaceColor',[1 1 .9],'FontSize',p.fs1,'FontWeight',p.fw1,'Tag',tag);
      sysblock('Parent',ax,'Position',[(x2+x1)/2-rw2/2 y2-.15 rw2 .30],...
         'Name',{'feedback network,','b(s)'},'Gain','K ','Numerator','1 + \tau_{z} s','Denominator','1 + \tau_{p} s',...
         'FaceColor',[1 1 .9],'FontSize',p.fs1,'FontWeight',p.fw1,'Tag',tag);
      wire('Parent',ax,'XData',[xstart x1-p.sbr],         'YData',[y1 y1],         'ArrowSize',p.as,'Tag',tag);
      wire('Parent',ax,'XData',[x1+p.sbr (x2+x1)/2-rw1/2],'YData',[y1 y1],         'ArrowSize',p.as,'Tag',tag);
      wire('Parent',ax,'XData',[(x2+x1)/2+rw1/2 xend],    'YData',[y1 y1],         'ArrowSize',p.as,'Tag',tag);
      wire('Parent',ax,'XData',[x2 x2 (x2+x1)/2+rw2/2],   'YData',[y1 y2 y2],      'ArrowSize',p.as,'Tag',tag);
      wire('Parent',ax,'XData',[(x2+x1)/2-rw2/2 x1 x1],   'YData',[y2 y2 y1-p.sbr],'ArrowSize',p.as,'Tag',tag);
      text('Parent',ax,'String','Vp ','Position',[xstart y1],...
         'FontSize',p.fs2,'FontWeight',p.fw2,'Hor','right','Ver','middle','Tag',tag);
      text('Parent',ax,'String','Vn ','Position',[x1 y2],...
         'FontSize',p.fs2,'FontWeight',p.fw2,'Hor','right','Ver','middle','Tag',tag);
      text('Parent',ax,'String',' Vo','Position',[xend y1],...
         'FontSize',p.fs2,'FontWeight',p.fw2,'Hor','left', 'Ver','middle','Tag',tag);
      text('Parent',ax,'String',{'K_{ } = R1 / (R1 + R2)','\tau_{z} = R2 \cdot C','\tau_{p} = K \cdot \tau_{z}'},...
          'Position',[x2-.2 y2-.19],'Color',[.8 0 0],'FontSize',p.fs1,'FontWeight',p.fw1,'Hor','left','Ver','middle','Tag',tag);

   case 19
      if strcmpi(action,'back')
         localCanvas(ax)
         axis(ax,'equal'); set(ax,'XLim',[0 1],'YLim',[0 1]);
      end
      x1 = .3;
      y1 = 0;
      dx = .03;
      dy = .03;
      w = .6;
      h = .6;
      text('Parent',ax,'Position',[x1-2.5*dx+w/2 0.8],'String','LTI Model Array:  b\_array(s)',...
         'FontSize',p.fs3,'FontWeight',p.fw3,'Hor','center','Ver','bottom','Tag',tag);
      sysblock('Parent',ax,'Position',[x1-4*dx y1+4*dy w h],'FaceColor',[1 1 .9],'Tag',tag);
      sysblock('Parent',ax,'Position',[x1-3*dx y1+3*dy w h],'FaceColor',[1 1 .9],'Tag',tag);
      sysblock('Parent',ax,'Position',[x1-2*dx y1+2*dy w h],'FaceColor',[1 1 .9],'Tag',tag);
      sysblock('Parent',ax,'Position',[x1-1*dx y1+1*dy w h],'FaceColor',[1 1 .9],'Tag',tag);
      sysblock('Parent',ax,'Position',[x1-0*dx y1+0*dy w h],'FaceColor',[1 1 .9],'Tag',tag,...
         'Name','(n x 1 array)','Num','b\_array(:,:,n)','FontSize',p.fs1,'FontWeight',p.fw1);

   case 20
      if strcmpi(action,'back')
         localCanvas(ax)
      end
      reset(ax)
      A = p.A;
      A_array = p.A_array;
      step(A,'b:',A_array,'b',p.Time3)
      set(gcr,'Grid','off','SettlingTimeThreshold',.02,...
         'Title','Closed-Loop Step Response (Compensated)','YLim',{[0 14]});
      pa = get(gcr,'PlotAxes');
      CC = [1 0 1];
      ln = line('Parent',pa(1),'LineStyle','-','Color',CC,'XData',[.25e-6 .32e-6],'YData',[12 5],'Tag',tag);
      patch('Parent',pa(1),'EdgeColor',CC,'FaceColor',CC,'XData',[.32e-6 .29e-6 .34e-6],'YData',[5 5.6 5.8],'Tag',tag);
      text('Parent',pa(1),'Position',[.32e-6 4.9], 'String','   Increasing C',...
         'Color',CC,'FontSize',p.fs1,'FontWeight',p.fw1,'Hor','center','Ver','top','Tag',tag);
      text('Parent',pa(1),'Position',[.20e-6 13.2],'String','0 pF',...
         'Color',CC,'FontSize',p.fs1,'FontWeight',p.fw1,'Hor','right','Ver','middle','Tag',tag);
      text('Parent',pa(1),'Position',[.34e-6 12],  'String','1 pF',...
         'Color',CC,'FontSize',p.fs1,'FontWeight',p.fw1,'Hor','center','Ver','bottom','Tag',tag);
      text('Parent',pa(1),'Position',[.38e-6 7.8], 'String','3 pF',...
         'Color',CC,'FontSize',p.fs1,'FontWeight',p.fw1,'Hor','left','Ver','top','Tag',tag);

   case 21
      localCanvas(ax)
      reset(ax)
      set(ax,'XLim',[0.8 3.6],'YLim',[45 60],'Box','on','FontSize',p.fs1)
      set(get(ax,'XLabel'),'String','Compensation Capacitor, C (pF)','FontSize',p.fs1);
      set(get(ax,'YLabel'),'String','Phase Margin (deg)','FontSize',p.fs1);
      ln = line('Parent',ax,'LineStyle','-','Color',[0 .65 0],'XData',p.C*1e12,'YData',p.Pm);
      text('Parent',ax,'Position',[2.2 58],'String','\leftarrow Peak Phase Margin @ C = 2pF',...
         'FontSize',p.fs1,'FontWeight',p.fw1,'Hor','left','Ver','middle','Tag',tag);

   case 22
      A = p.A;
      A_comp = p.A_comp;
      step(A,'b:',A_comp,'b',p.Time2)
      set(gcr,'Grid','off','SettlingTimeThreshold',.02,'Title','Closed-Loop Step Response');
      pa = get(gcr,'PlotAxes');
      text('Parent',pa(1),'Position',[2.5e-6 15],'String',' Uncompensated response (0 pF)',...
         'FontSize',p.fs1,'FontWeight',p.fw1,'Hor','left','Ver','middle','Tag',tag);
      line('Parent',pa(1),'XData',[2.5e-6 1.75e-6],'YData',[15 13.6],'Tag',tag);
      text('Parent',pa(1),'Position',[2.5e-6 5],'String',' Compensated response (2 pF)',...
         'FontSize',p.fs1,'FontWeight',p.fw1,'Hor','left','Ver','middle','Tag',tag);
      line('Parent',pa(1),'XData',[2.5e-6 3.5e-7],'YData',[5 8.25],'Tag',tag);

   case 23
      if strcmpi(action,'back')
         localCanvas(ax)
         reset(ax)
      end
      a = p.a;
      A = p.A;
      A_comp = p.A_comp;
      bode(a,'r',A,'b:',A_comp,'b',p.Frequency1)
      set(gcr,'FrequencyUnits','rad/sec','MagnitudeUnits','dB','PhaseUnits','deg',...
         'UnwrapPhase','on','Grid','off','YLim',{[0 110],[-180 0]});
      setscale(gcr,'FrequencyScale','log');
      pa = get(gcr,'PlotAxes');
      text('Parent',pa(2),'Position',[1.30e4 -35],'String','a(s)',...
         'Hor','left','Ver','middle','FontSize',p.fs1,'Tag',tag);
      text('Parent',pa(2),'Position',[1.15e7 -35],'String','A(s)',...
         'Hor','left','Ver','middle','FontSize',p.fs1,'Tag',tag);
      text('Parent',pa(2),'Position',[1.70e6 -35],'String','A_comp(s)',...
         'Interp','none','Hor','right','Ver','middle','FontSize',p.fs1,'Tag',tag);

   case 24
      localCanvas(ax)
      axis(ax,'normal'); set(ax,'XLim',[0 1],'YLim',[0 1]);
      text('Parent',ax,'Position',[0 0.8],'String','Final Component Values:',...
         'FontSize',p.fs3,'FontWeight',p.fw3,'Hor','left','Ver','bottom','Tag',tag);
      equation('Parent',ax,'Position',[.25 0.60],'Name','R1','Num','10 kOhm',...
         'Anchor','equal','FontSize',p.fs3,'Tag',tag);
      equation('Parent',ax,'Position',[.25 0.45],'Name','R2','Num','90 kOhm',...
         'Anchor','equal','FontSize',p.fs3,'Tag',tag);
      equation('Parent',ax,'Position',[.25 0.30],'Name','C', 'Num','2 pF',...
         'Anchor','equal','FontSize',p.fs3,'Tag',tag);      
   end
end

%%%%%%%%%%%%%%%
% localCanvas %
%%%%%%%%%%%%%%%
function localCanvas(ax)
 %---Reset axes properties for use as a drawing canvas
  delete(findobj(allchild(ax),'flat','Serializable','on'));
  reset(ax);
  set(ax,'Visible','off','XLim',[0 1],'YLim',[0 1],...
     'DefaultLineClipping','off','DefaultTextClipping','off','DefaultPatchClipping','off');

%%%%%%%%%%%%%%%%%%%
% localParameters %
%%%%%%%%%%%%%%%%%%%
function p_out = localParameters
 %---Parameters/systems used in demo
 persistent p;
 if isempty(p)
    if ispc
       p.fs1 = 8;
       p.fs2 = 10;
       p.fs3 = 12;
    else
       p.fs1 = 10;
       p.fs2 = 12;
       p.fs3 = 14;
    end
    p.fw1 = 'normal';
    p.fw2 = 'bold';
    p.fw3 = 'bold';
    p.as = .05;  %---Arrow size
    p.sbr = .04; %---Sumblock radius
    p.s = tf('s');
    p.a0 = 1e5;
    p.w1 = 1e4;
    p.w2 = 1e6;
    p.R1 = 10e3;
    p.R2 = 90e3;
    p.Frequency1 = logspace(3,8,256);
    p.Time1 = [0:.01:1]*6e-4;
    p.Time2 = [0:.005:1]*1.0e-5;
    p.Time3 = [0:.005:1]*1.5e-6;
    p.a = p.a0/(1+p.s/p.w1)/(1+p.s/p.w2);
    p.a_norm = p.a/dcgain(p.a);
    p.b = p.R1/(p.R1+p.R2);
    p.A = feedback(p.a,p.b);
    p.L = p.a*p.b;
    p.S = feedback(1,p.L);
    p.K = p.R1/(p.R1+p.R2);
    p.C = [1:.2:3]*1e-12;
    for n = 1:length(p.C)
       b_array(:,:,n) = tf([p.K*p.R2*p.C(n) p.K],[p.K*p.R2*p.C(n) 1]);
    end
    p.b_array = b_array;
    p.A_array = feedback(p.a,p.b_array);
    p.L_array = p.a*p.b_array;
    [p.Gm,p.Pm,p.Wcg,p.Wcp] = margin(p.L_array);
    p.A_comp = p.A_array(:,:,6);
 end
 p_out = p;
