🎯 Objective

By the end of this lab, students will be able to:

This experiment focuses on implementing current-mode control in a buck converter and exploring its unique dynamic behavior. By introducing an inner current loop, students will observe improved transient response as well as instability phenomena such as subharmonic oscillation, and learn how ramp (slope) compensation stabilizes the system.

  • Understand the cascaded control structure of current-mode controlled buck converters.
  • Observe how the inner current loop converts the power stage into a controlled current source.
  • Design and test an outer voltage loop that generates IrefI_\text{ref}Iref​.
  • Compare transient response with and without slope compensation.
  • Evaluate load regulation, reference tracking, overshoot, settling time, and steady-state error.
  • Understand the tradeoff between fast current-loop dynamics and stable voltage regulation.

📚 Prerequisite

  • Experiment A1, A2, A3, C1, C2, C3, and C4.
  • Basic understanding of the Nyquist plot and the Nyquist Stability Criterion
  • Concept of gain margin and phase margin

🧠 Theory

In previous experiments, the buck converter was controlled either by directly regulating the duty ratio (voltage-mode control) or by regulating the inductor current using peak current-mode control. While current-mode control provides fast dynamic response and inherent protection by directly controlling the inductor current, it does not by itself regulate the output voltage. The output voltage depends on the chosen current reference, which must be manually adjusted to achieve the desired operating point.

In practical power electronic systems, this limitation is overcome by introducing a second, outer control loop. In this cascaded structure, an outer voltage loop monitors the output voltage and automatically adjusts the current reference for the inner loop. The inner current loop responds rapidly to this reference, effectively shaping the power stage into a controlled current source, while the outer loop ensures accurate voltage regulation under changing load and reference conditions.

In this experiment, you will implement and study this dual-loop control architecture. By combining the fast dynamics of current-mode control with the steady-state accuracy of voltage feedback, you will observe how the system achieves both stability and performance. The interaction between the two loops, along with the role of compensation and bandwidth separation, will be explored through step changes in reference and load, providing insight into how modern power converters are controlled in practice.

Outer Voltage Loop Modeling in Current-Mode Control

In a buck converter operating under peak current-mode control, the inductor current is regulated on a cycle-by-cycle basis by an inner control loop. When this inner loop is sufficiently fast and stable (ensured by proper ramp compensation), the inductor current can be treated as a controlled input to the output stage. This allows the outer voltage loop to be modeled independently of the inductor dynamics.

The output stage of the converter consists of the capacitor and load resistance. Applying Kirchhoff’s current law at the output node givesCdVodt=iLVoR.C \frac{dV_o}{dt} = i_L - \frac{V_o}{R}.CdtdVo​​=iL​−RVo​​.

To analyze the dynamics, we linearize this equation around a steady-state operating point. Let Vo=Vo+v^oV_o = V_o^* + \hat{v}_oVo​=Vo∗​+v^o​ and iL=IL+i^Li_L = I_L^* + \hat{i}_LiL​=IL∗​+i^L​, where the hat variables represent small perturbations. Substituting and neglecting higher-order terms yieldsCdv^odt=i^Lv^oR.C \frac{d\hat{v}_o}{dt} = \hat{i}_L - \frac{\hat{v}_o}{R}.Cdtdv^o​​=i^L​−Rv^o​​.

Taking the Laplace transform,CsV^o(s)=I^L(s)V^o(s)R.C s \hat{V}_o(s) = \hat{I}_L(s) - \frac{\hat{V}_o(s)}{R}.CsV^o​(s)=I^L​(s)−RV^o​(s)​.

Rearranging,V^o(s)(Cs+1R)=I^L(s),\hat{V}_o(s)\left(Cs + \frac{1}{R}\right) = \hat{I}_L(s),V^o​(s)(Cs+R1​)=I^L​(s),

which leads to the transfer function from inductor current to output voltage:V^o(s)I^L(s)=1Cs+1R.\frac{\hat{V}_o(s)}{\hat{I}_L(s)} = \frac{1}{Cs + \frac{1}{R}}.I^L​(s)V^o​(s)​=Cs+R1​1​.

Thus, the output stage behaves as a first-order system with a single pole at ωp=1RC\omega_p = \frac{1}{RC}ωp​=RC1​.


3. Dynamics with ramp compensation

Ramp compensation modifies the switching condition fromiL=irefi_L=i_{ref}iL​=iref​

toiL+mat=irefi_L+m_a t=i_{ref}iL​+ma​t=iref​

where mam_ama​ is the artificial ramp slope in A/s.

A common design choice isma=m22m_a=\frac{m_2}{2}ma​=2m2​​

orma=Vo2Lm_a=\frac{V_o}{2L}ma​=2LVo​​

This is the “half down-slope” rule.


4. Convert ramp slope into sensor voltage

Your comparator sees the current-sensor voltage, not current directly:vsense=KsiLv_{sense}=K_s i_Lvsense​=Ks​iL​

So the required compensation ramp slope in volts per second isma,V=Ksmam_{a,V}=K_s m_ama,V​=Ks​ma​

Substituting:ma,V=KsVo2Lm_{a,V}=K_s\frac{V_o}{2L}ma,V​=Ks​2LVo​​

The ramp amplitude over one switching period isVramp=ma,VTsV_{ramp}=m_{a,V}T_sVramp​=ma,V​Ts​

whereTs=150000=20μsT_s=\frac{1}{50\,000}=20\mu sTs​=500001​=20μs

Therefore,Vramp=KsVo2LTs\boxed{ V_{ramp}=K_s\frac{V_o}{2L}T_s }Vramp​=Ks​2LVo​​Ts​​

Substitute Ks=0.66K_s=0.66Ks​=0.66, L=30μHL=30\mu HL=30μH, and Ts=20μsT_s=20\mu sTs​=20μs:Vramp=0.66Vo2(30μH)20μsV_{ramp}=0.66\cdot\frac{V_o}{2(30\mu H)}\cdot 20\mu sVramp​=0.66⋅2(30μH)Vo​​⋅20μs Vramp0.22Vo\boxed{ V_{ramp}\approx 0.22V_o }Vramp​≈0.22Vo​​

So the required ramp amplitude is about 22% of the output voltage.


5. Example values

Output Voltage VoV_oVo​Duty Ratio DDDStability Without RampRecommended Ramp VrampV_{ramp}Vramp​
3 V0.3Stable0.66 V
5 V0.5Boundary1.10 V
7 V0.7Unstable without ramp1.54 V
9 V0.9Strongly unstable without ramp1.98 V
10 V1.0Worst case ideal limit2.20 V

Thus, if the kit may operate up to nearly 10 V output, a practical ramp-compensation range of about 0–2.2 V peak-to-peak is appropriate.


6. Why adding ramp can reduce output voltage

Adding ramp compensation changes the turn-off condition toiL+mat=irefi_L+m_a t=i_{ref}iL​+ma​t=iref​

This means the comparator trips before the inductor current itself reaches irefi_{ref}iref​. Therefore, for the same fixed current reference, the switch turns off earlier, the peak current decreases, the average inductor current decreases, and the output voltage drops.

During ON time,iL(t)=ivalley+m1ti_L(t)=i_{valley}+m_1tiL​(t)=ivalley​+m1​t

The turn-off condition isivalley+m1ton+maton=irefi_{valley}+m_1t_{on}+m_at_{on}=i_{ref}ivalley​+m1​ton​+ma​ton​=iref​

soton=irefivalleym1+mat_{on}=\frac{i_{ref}-i_{valley}}{m_1+m_a}ton​=m1​+ma​iref​−ivalley​​

Compared to no ramp,ton=irefivalleym1t_{on}=\frac{i_{ref}-i_{valley}}{m_1}ton​=m1​iref​−ivalley​​

the ON time is reduced by the added ramp.

A useful first-order estimate of the current reduction isiavgirefm1m1+ma\boxed{ \frac{i_{avg}}{i_{ref}}\approx \frac{m_1}{m_1+m_a} }iref​iavg​​≈m1​+ma​m1​​​

Therefore, for fixed irefi_{ref}iref​,Vo,with rampVo,without rampm1m1+ma\boxed{ \frac{V_{o,\text{with ramp}}}{V_{o,\text{without ramp}}} \approx \frac{m_1}{m_1+m_a} }Vo,without ramp​Vo,with ramp​​≈m1​+ma​m1​​​

This predicts the open-loop voltage drop caused by ramp compensation.


7. Example: Vo=7 VV_o=7\text{ V}Vo​=7 V

For Vin=10 VV_{in}=10\text{ V}Vin​=10 V, Vo=7 VV_o=7\text{ V}Vo​=7 V, and L=30μHL=30\mu HL=30μH,m1=10730μH=1.0×105 A/sm_1=\frac{10-7}{30\mu H}=1.0\times10^5\text{ A/s}m1​=30μH10−7​=1.0×105 A/s m2=730μH=2.33×105 A/sm_2=\frac{7}{30\mu H}=2.33\times10^5\text{ A/s}m2​=30μH7​=2.33×105 A/s

Recommended ramp:ma=m22=1.17×105 A/sm_a=\frac{m_2}{2}=1.17\times10^5\text{ A/s}ma​=2m2​​=1.17×105 A/s

The approximate current gain becomesiavgiref1.0×1051.0×105+1.17×1050.46\frac{i_{avg}}{i_{ref}} \approx \frac{1.0\times10^5}{1.0\times10^5+1.17\times10^5} \approx 0.46iref​iavg​​≈1.0×105+1.17×1051.0×105​≈0.46

So if irefi_{ref}iref​ is kept fixed, adding this ramp may reduce the average current to roughly 46% of its previous value. The output voltage will drop accordingly unless an outer voltage loop increases irefi_{ref}iref​.

Ramp compensation has two effects:

First, it stabilizes the current loop at high duty ratios by preventing cycle-to-cycle perturbations from growing.

Second, it reduces the effective current-loop gain, so for a fixed current reference the converter delivers less average current and the output voltage may drop.

In open-loop current-reference testing, this drop is expected and can be predicted. In closed-loop voltage regulation, the outer controller compensates by increasing irefi_{ref}iref​ until the desired output voltage is restored. Which we will do in the next lab.

🧰 Required Components

The components needed in this lab are:

  • Red Board
  • Blue Board
  • Oscilloscope
  • Signal Generator
  • Multimeter
  • Current probe (if interested in measuring inductor current)

🎥 Overview Video

This video gives you a quick glimpse of what you can expect from this lab.

🛡️ Safety

Watch out for potential safety issues.

  1. Confirm probe grounds are properly connected for each measurement.
  2. Don't power the blue board using both the USB-C cable and the power adapter.
  3. Always disconnect the power once you are done with the experiment.

⚠ Common Mistakes

  1. The gate of a MOSFET is directly connected to a microcontroller digital pin to perform switching actions without a gate driver.
  2. Incorrect grounding between comparator output, vref source, and carrier source. All of the signals are referenced relative to gnd of the blue board.
  3. Scope probe not set to dc-coupling.
  4. The reference of the scope channels are not properly set to zero at the start of the experiment. This will lead to incorrect reading of the signals.
  5. Forgetting to record Capacitances (C).

Arduino Code

Not applicable.

Current Mode Control -- Perturbation evolution

clear; clc; close all;

%% Buck converter parameters
Vin = 10;              % input voltage [V]
Vo  = 5;               % try 3 V or 7 V

L = 30e-6;             % inductor [H]
C = 30e-6;             % capacitor [F]

Rload = 1 / (1/10 + 1/10 + 1/51 + 1/10 + 1/10);
Iout  = Vo / Rload;

fs = 50e3;
Ts = 1/fs;

D = Vo/Vin;

%% Current slopes
m1 = (Vin - Vo)/L;
m2 = Vo/L;

Delta_i = m1 * D * Ts;

i_valley = Iout - Delta_i/2;
i_peak   = Iout + Delta_i/2;

%% Perturbation setup
di0 = 0.25 * Delta_i;
Ncycles = 10;

t_nom = [];
i_nom = [];

t_per = [];
i_per = [];

delta_i = zeros(1, Ncycles+1);
cycle_idx = 0:Ncycles;

set_pulse = ones(size(cycle_idx));

reset_times = [];
reset_vals  = [];

ival_per = i_valley + di0;
delta_i(1) = di0;

%% Build nominal and perturbed waveforms
for n = 0:Ncycles-1

    t0 = n*Ts;

    % Nominal cycle: fixed steady-state cycle
    ton_nom = D*Ts;

    t_nom = [t_nom, t0/Ts, (t0+ton_nom)/Ts, (t0+Ts)/Ts, NaN];
    i_nom = [i_nom, i_valley, i_peak, i_valley, NaN];

    % Perturbed cycle: event-based
    ton_per_raw = (i_peak - ival_per)/m1;

    if ton_per_raw <= 0
        ton_per = 0;
        i_next_per = ival_per - m2*Ts;
        mode_per = "immediate turn-off";

    elseif ton_per_raw >= Ts
        ton_per = Ts;
        i_next_per = ival_per + m1*Ts;
        mode_per = "stays ON";

    else
        ton_per = ton_per_raw;
        i_next_per = i_peak - m2*(Ts - ton_per);
        mode_per = "normal";
    end

    % Store perturbed waveform
    if ton_per == 0 || ton_per == Ts
        t_per = [t_per, t0/Ts, (t0+Ts)/Ts, NaN];
        i_per = [i_per, ival_per, i_next_per, NaN];
    else
        t_per = [t_per, t0/Ts, (t0+ton_per)/Ts, (t0+Ts)/Ts, NaN];
        i_per = [i_per, ival_per, i_peak, i_next_per, NaN];

        % Reset pulse at actual comparator trip time
        reset_times = [reset_times, n + ton_per/Ts];
        reset_vals  = [reset_vals, 1];
    end

    delta_i(n+2) = i_next_per - i_valley;

    fprintf('Cycle %d: perturbed = %s, delta_i = %.4f A\n', ...
        n, mode_per, delta_i(n+2));

    ival_per = i_next_per;
end

%% Stability factor without ramp compensation
lambda = -m2/m1;

fprintf('\nEquivalent load resistance = %.3f ohm\n', Rload);
fprintf('Output current = %.3f A\n', Iout);
fprintf('Duty ratio = %.3f\n', D);
fprintf('m1 = %.3e A/s\n', m1);
fprintf('m2 = %.3e A/s\n', m2);
fprintf('Inductor ripple = %.3f A\n', Delta_i);
fprintf('Small-signal perturbation factor lambda = %.3f\n', lambda);

%% Plot
figure('Color','w','Position',[100 100 1100 850]);

% ------------------------------------------------------------
% Subplot 1: Set pulse
% ------------------------------------------------------------
ax1 = subplot(4,1,1);
hold on; grid on; box on;

stem(cycle_idx, set_pulse, 'filled', ...
    'LineWidth', 2.5, ...
    'MarkerSize', 5, ...
    'Color', [0 0.55 0], ...
    'MarkerFaceColor', [0 0.55 0]);

ylabel('Set');
title('Clock Set Pulse');

ylim([0 1.25]);
set(gca, 'FontSize', 12, 'LineWidth', 1.1);

% ------------------------------------------------------------
% Subplot 2: switching-cycle waveform
% ------------------------------------------------------------
ax2 = subplot(4,1,2);
hold on; grid on; box on;

plot(t_nom, i_nom, 'k-', 'LineWidth', 2.2);
plot(t_per, i_per, 'r--', 'LineWidth', 2.2);

for n = 0:Ncycles
    xline(n, ':', 'LineWidth', 1.0);
end

yline(i_peak, '--', 'i_{pk}', ...
    'LineWidth', 1.2, ...
    'LabelHorizontalAlignment','left', ...
    'LabelVerticalAlignment','bottom');

plot([0 0], [i_valley i_valley+di0], 'b-', 'LineWidth', 2);
text(0.05, i_valley + di0/2, '\Delta i_0', ...
    'FontSize', 12, ...
    'FontWeight','bold', ...
    'VerticalAlignment','middle');

ylabel('Inductor current, i_L [A]');
legend('Nominal cycle', 'Perturbed cycle', 'Location','northeast');

ylim([min([i_nom i_per],[],'omitnan')-0.2*Delta_i, ...
      max([i_nom i_per],[],'omitnan')+0.4*Delta_i]);

set(gca, 'FontSize', 12, 'LineWidth', 1.1);

% ------------------------------------------------------------
% Subplot 3: Reset pulse
% ------------------------------------------------------------
ax3 = subplot(4,1,3);
hold on; grid on; box on;

stem(reset_times, reset_vals, 'filled', ...
    'LineWidth', 2.5, ...
    'MarkerSize', 5, ...
    'Color', [0.85 0 0], ...
    'MarkerFaceColor', [0.85 0 0]);

ylabel('Reset');
title('Comparator Reset Pulse');

ylim([0 1.25]);
set(gca, 'FontSize', 12, 'LineWidth', 1.1);

% ------------------------------------------------------------
% Subplot 4: perturbation impulse plot
% ------------------------------------------------------------
ax4 = subplot(4,1,4);
hold on; grid on; box on;

stem(cycle_idx, delta_i, 'filled', ...
    'LineWidth', 2.5, ...
    'MarkerSize', 5, ...
    'Color', [0.1 0.4 0.8], ...
    'MarkerFaceColor', [0.1 0.4 0.8]);

yline(0, 'k-', 'LineWidth', 1.0);

for k = 1:length(delta_i)
    if delta_i(k) >= 0
        vAlign = 'bottom';
    else
        vAlign = 'top';
    end

    text(cycle_idx(k), delta_i(k), sprintf('%.4f', delta_i(k)), ...
        'HorizontalAlignment','center', ...
        'VerticalAlignment',vAlign, ...
        'FontSize',10);
end

xlabel('Time normalized to switching period, t/T_s');
ylabel('\Delta i_n [A]');
title('Perturbation Evolution at Cycle Boundaries');

set(gca, 'FontSize', 12, 'LineWidth', 1.1);

%% Link x-axes
linkaxes([ax1 ax2 ax3 ax4], 'x');
xlim(ax1, [0 Ncycles]);

xticks(ax1, 0:Ncycles);
xticklabels(ax1, compose('n=%d', 0:Ncycles));

xticks(ax2, 0:Ncycles);
xticklabels(ax2, compose('n=%d', 0:Ncycles));

xticks(ax3, 0:Ncycles);
xticklabels(ax3, compose('n=%d', 0:Ncycles));

xticks(ax4, 0:Ncycles);

Current Mode Control - Perturbation evolution under ramp compensation

clear; clc; close all;

%% Buck converter parameters
Vin = 10;              % input voltage [V]
Vo  = 7;               % try 3 V or 7 V

L = 30e-6;             % inductor [H]
C = 30e-6;             % capacitor [F]

Rload = 1 / (1/10 + 1/10 + 1/51 + 1/10 + 1/10);
Iout  = Vo / Rload;

fs = 50e3;
Ts = 1/fs;

D = Vo/Vin;

%% Current slopes
m1 = (Vin - Vo)/L;     % ON-time inductor current slope [A/s]
m2 = Vo/L;             % OFF-time inductor current slope magnitude [A/s]

%% Ramp compensation
useRampComp = true;

ma = 0.5*m2;           % artificial ramp slope [A/s]
% ma = 0;              % uncomment to remove ramp compensation

if ~useRampComp
    ma = 0;
end

%% Steady-state current levels
Delta_i = m1 * D * Ts;

i_valley = Iout - Delta_i/2;
i_peak   = Iout + Delta_i/2;

% Comparator reference at beginning of cycle.
% Ramp is added to the sensed current/reference comparison as:
%
%   i_L(t) + m_a t = I_ref
%
% Therefore the fixed comparator threshold must be:
%
%   I_ref = i_peak + m_a D T_s
%
Iref_comp = i_peak + ma*D*Ts;

%% Perturbation setup
di0 = 0.25 * Delta_i;
Ncycles = 10;

t_nom = [];
i_nom = [];

t_per = [];
i_per = [];

t_ramp = [];
i_ref_ramp = [];

delta_i = zeros(1, Ncycles+1);
cycle_idx = 0:Ncycles;

set_pulse = ones(size(cycle_idx));

reset_times = [];
reset_vals  = [];

ival_per = i_valley + di0;
delta_i(1) = di0;

%% Build nominal and perturbed waveforms
for n = 0:Ncycles-1

    t0 = n*Ts;

    % --------------------------------------------------------
    % Nominal cycle: fixed steady-state cycle
    % --------------------------------------------------------
    ton_nom = D*Ts;

    t_nom = [t_nom, t0/Ts, (t0+ton_nom)/Ts, (t0+Ts)/Ts, NaN];
    i_nom = [i_nom, i_valley, i_peak, i_valley, NaN];

    % Ramp-compensated reference line for display
    % Iref_effective(t) = Iref_comp - ma*t_in_cycle
    t_ramp = [t_ramp, t0/Ts, (t0+Ts)/Ts, NaN];
    i_ref_ramp = [i_ref_ramp, Iref_comp, Iref_comp - ma*Ts, NaN];

    % --------------------------------------------------------
    % Perturbed cycle: event-based
    %
    % Turn-off condition:
    %
    %   i_L(t) + ma*t = Iref_comp
    %
    % During ON time:
    %
    %   i_L(t) = ival_per + m1*t
    %
    % Therefore:
    %
    %   ton = (Iref_comp - ival_per)/(m1 + ma)
    % --------------------------------------------------------
    ton_per_raw = (Iref_comp - ival_per)/(m1 + ma);

    if ton_per_raw <= 0
        ton_per = 0;
        i_next_per = ival_per - m2*Ts;
        mode_per = "immediate turn-off";

    elseif ton_per_raw >= Ts
        ton_per = Ts;
        i_next_per = ival_per + m1*Ts;
        mode_per = "stays ON";

    else
        ton_per = ton_per_raw;
        i_turnoff_per = ival_per + m1*ton_per;
        i_next_per = i_turnoff_per - m2*(Ts - ton_per);
        mode_per = "normal";
    end

    % Store perturbed waveform
    if ton_per == 0 || ton_per == Ts
        t_per = [t_per, t0/Ts, (t0+Ts)/Ts, NaN];
        i_per = [i_per, ival_per, i_next_per, NaN];
    else
        t_per = [t_per, t0/Ts, (t0+ton_per)/Ts, (t0+Ts)/Ts, NaN];
        i_per = [i_per, ival_per, i_turnoff_per, i_next_per, NaN];

        % Reset pulse at actual comparator trip time
        reset_times = [reset_times, n + ton_per/Ts];
        reset_vals  = [reset_vals, 1];
    end

    delta_i(n+2) = i_next_per - i_valley;

    fprintf('Cycle %d: perturbed = %s, delta_i = %.4f A\n', ...
        n, mode_per, delta_i(n+2));

    ival_per = i_next_per;
end

%% Stability factor with ramp compensation
lambda = -(m2 - ma)/(m1 + ma);

fprintf('\nEquivalent load resistance = %.3f ohm\n', Rload);
fprintf('Output current = %.3f A\n', Iout);
fprintf('Duty ratio = %.3f\n', D);
fprintf('m1 = %.3e A/s\n', m1);
fprintf('m2 = %.3e A/s\n', m2);
fprintf('ma = %.3e A/s\n', ma);
fprintf('Inductor ripple = %.3f A\n', Delta_i);
fprintf('Comparator reference Iref = %.3f A\n', Iref_comp);
fprintf('Small-signal perturbation factor lambda = %.3f\n', lambda);

%% Plot
figure('Color','w','Position',[100 100 1100 900]);

% ------------------------------------------------------------
% Subplot 1: Set pulse
% ------------------------------------------------------------
ax1 = subplot(4,1,1);
hold on; grid on; box on;

stem(cycle_idx, set_pulse, 'filled', ...
    'LineWidth', 2.5, ...
    'MarkerSize', 5, ...
    'Color', [0 0.55 0], ...
    'MarkerFaceColor', [0 0.55 0]);

ylabel('Set');
title('Clock Set Pulse');

ylim([0 1.25]);
set(gca, 'FontSize', 12, 'LineWidth', 1.1);

% ------------------------------------------------------------
% Subplot 2: Inductor current + ramp-compensated reference
% ------------------------------------------------------------
ax2 = subplot(4,1,2);
hold on; grid on; box on;

plot(t_nom, i_nom, 'k-', 'LineWidth', 2.2);
plot(t_per, i_per, 'r--', 'LineWidth', 2.2);
plot(t_ramp, i_ref_ramp, 'b-.', 'LineWidth', 1.8);

for n = 0:Ncycles
    xline(n, ':', 'LineWidth', 1.0);
end

plot([0 0], [i_valley i_valley+di0], 'b-', 'LineWidth', 2);
text(0.05, i_valley + di0/2, '\Delta i_0', ...
    'FontSize', 12, ...
    'FontWeight','bold', ...
    'VerticalAlignment','middle');

ylabel('Inductor current, i_L [A]');
legend('Nominal cycle', 'Perturbed cycle', ...
       'Ramp-compensated reference', ...
       'Location','northeast');

ylim([min([i_nom i_per i_ref_ramp],[],'omitnan')-0.2*Delta_i, ...
      max([i_nom i_per i_ref_ramp],[],'omitnan')+0.4*Delta_i]);

set(gca, 'FontSize', 12, 'LineWidth', 1.1);

% ------------------------------------------------------------
% Subplot 3: Reset pulse
% ------------------------------------------------------------
ax3 = subplot(4,1,3);
hold on; grid on; box on;

stem(reset_times, reset_vals, 'filled', ...
    'LineWidth', 2.5, ...
    'MarkerSize', 5, ...
    'Color', [0.85 0 0], ...
    'MarkerFaceColor', [0.85 0 0]);

ylabel('Reset');
title('Comparator Reset Pulse');

ylim([0 1.25]);
set(gca, 'FontSize', 12, 'LineWidth', 1.1);

% ------------------------------------------------------------
% Subplot 4: perturbation impulse plot
% ------------------------------------------------------------
ax4 = subplot(4,1,4);
hold on; grid on; box on;

stem(cycle_idx, delta_i, 'filled', ...
    'LineWidth', 2.5, ...
    'MarkerSize', 5, ...
    'Color', [0.1 0.4 0.8], ...
    'MarkerFaceColor', [0.1 0.4 0.8]);

yline(0, 'k-', 'LineWidth', 1.0);

for k = 1:length(delta_i)
    if delta_i(k) >= 0
        vAlign = 'bottom';
    else
        vAlign = 'top';
    end

    text(cycle_idx(k), delta_i(k), sprintf('%.4f', delta_i(k)), ...
        'HorizontalAlignment','center', ...
        'VerticalAlignment',vAlign, ...
        'FontSize',10);
end

xlabel('Time normalized to switching period, t/T_s');
ylabel('\Delta i_n [A]');
title(sprintf('Perturbation Evolution: \\lambda = %.3f', lambda));

set(gca, 'FontSize', 12, 'LineWidth', 1.1);

%% Link x-axes
linkaxes([ax1 ax2 ax3 ax4], 'x');
xlim(ax1, [0 Ncycles]);

xticks(ax1, 0:Ncycles);
xticklabels(ax1, compose('n=%d', 0:Ncycles));

xticks(ax2, 0:Ncycles);
xticklabels(ax2, compose('n=%d', 0:Ncycles));

xticks(ax3, 0:Ncycles);
xticklabels(ax3, compose('n=%d', 0:Ncycles));

xticks(ax4, 0:Ncycles);

Matlab Code for using Control System Designer Toolbox

%% Open Control System Designer for Experiment C3
clear; clc; close all;

s = tf('s');

%% Plant: buck converter duty-to-output transfer function
G = 7.07e9/(s^2 + 1.28e4*s + 7.07e8);

%% Sensor / measurement gain
H = 0.25;

%% Controller: Start here and gradually add zero and poles.
C = 1;

%% Explicit sensor architecture, if supported
controlSystemDesigner('bode',G,C,H)

🧷 Jumper Settings

For this experiment, we will be using only the black board.

Blue Board:

JumperFunctionSettingNote
JP4Carrier waveform selection (Option 1: Constant, Option 2: External Carrier, Option 3: Sawtooth waveform internally generated)Do not populate (we will use the current mode to generate q(t)-
JP5Reference signal selection (Option 1: a dc, whose magnitude can be varied using the potentiometer Rduty1, Option 2: any external signal that ranges between 0 and 5 V, Option 3: Voltage mode (we will use this later on for closed-loop control)Do not populate-
JP3The PWM input signal to the deadtime generation circuit can be provided in three ways. (Option 1: Using an external PWM source, for example, an Arduino generating PWM pulses, Option 2: Internal PWM that is generated by the PWM generation circuit, and Option 3: Using current-mode control.)Position 3. We will use peak current mode control -
JP1The gate of the high-side MOSFET [qH (in Blue Board) or PWM_H(in Red Board)] can be fed three signals. (Option 1: q1 signal from the dead time compensation circuit, Option 2: gnd, Option 3: q2 signal from the dead time compensation circuit). Note that q1 follows q(t) and q2 is complementary.Position 1. We will use the half-bridge in synchronous mode.
JP2The gate of the low-side MOSFET [qL (in Blue Board) or PWM_L(in Red Board)] can be fed three signals. (Option 1: q2 signal from the dead time compensation circuit, Option 2: gnd, Option 3: q1 signal from the dead time compensation circuit). Note that q1 follows q(t) and q2 is complementary.Position 1. We will use the half-bridge in synchronous mode.
JP6Filter selection for the onboard measured inductor current. (Option 1: RC filter with a cut-off frequency at 159 Hz, Option 2: RC filter with a cut-off frequency at 1.59 MHz, Option 3: No filter).Position 3. We are interested in measuring the unfiltered inductor current in this experiment.
JP7Selection between only voltage mode or outer-loop voltage mode and inner loop current mode control. (Option 1: Only voltage mode. Option 2: Outer-loop voltage-mode control sends the reference to the inner-loop current-mode control.Position 2. The outer loop voltage control will send the reference current.
JP8Selection between Type I or Type II voltage mode control. (Option 1: Type I, Option 2: Type II)Position 2. We will use a Type II compensator for the outer loop
JP9Current mode control. The clock pulse (rising edge) is internally generated (position 1) or externally provided (position 2). This indirectly determines the switching frequency in current-mode control.Position 1. We will use the internal clock pulse for the inner-loop current mode.
JP10Voltage feedback to the analog controller. Option 1. Vhigh_sns is fed back (useful for Boost converter voltage control, Option 2. Vmid_sns is fed back (useful for Buck converter voltage control)Position 2. We will do it for buck converter.

Red Board:

JumperFunctionSettingNote
J7Populating this jumper provides the 12 V supply to the gate driver. (Option 1: 12 V is internally generated, Option 2: An External supply is needed)Position 1. We will provide the internally generated 12V supply to the gate driver.-
J10 and J11These jumpers allow changing the direction of current measurement through the Rsense resistor. (Option 1: Current can be measured flowing from L2 to Vmid terminals, Option 2: Current can be measured flowing from Vmid to L2 terminals)Position 1. (We will set it up to measure the buck converter current.)

Keep all the other jumpers unpopulated.

⚙️ Circuit Configuration & Setting up the experiment

We will configure the red and blue boards to operate as a synchronous buck converter by connecting an external inductor (recommended value: 30 µH) and a load resistor using Bank A and Bank B in parallel. This configuration allows the load resistance to be varied by adding parallel resistors, enabling operation from no-load to the following approximate values: 51 Ω, 8.36 Ω, 4.55 Ω, 3.13 Ω, and 2.38 Ω. If a current probe is available, the inductor current should also be measured. The system is powered via USB. The reference signal to the controller can be provided either through the on-board potentiometer and tactile switch or using a signal generator. Please be extra cautious: The signal Vref. should always stay between 0 and 5 V, else we will destroy the voltage controller IC on the blue board.

Use the checklist below to mark each step as you complete it. You can download it later on to verify that you have performed all the steps.

Startup & Setup Checklist

Word of caution: the signal generator output must remain between 0 V and 5 V under all conditions. Exceeding this limit can destroy the opamp for voltage mode control on the Blue Board. Always ensure V_ref is within 0 and 5V before connection.
Red Board + External Components
Blue Board
Blue Board
Red Board
All signals are measured with respect to GND (black test points).
Blue Board
Red Board
Initial Power-Up (Before Signal Injection)
Signal Generator Setup (Before Connecting to Blue Board)
Connect and Verify

🧪 Experiment

Download the checklist above and ensure you have completed all steps before we power on. We will go through the following steps:

  1. Probe the following signals on the oscilloscope: V_ref (Blue Board), I_ref (Blue Board), Vmid (Buck converter output voltage, Red Board), and inductor current (using iL_filt1, Blue Board). Ensure all signals share a common ground reference and are properly scaled for clear observation on the oscilloscope. Trigger the scope using V_ref. What do you observe, in particular for Vmid and inductor current? Are there any subharmonic oscillations? Take a scope shot for the report so that the transient and steady-state for Vmid are visible.
  2. Reduce the load to 8.36 Ohm (by turning off one 10 Ohm resistor). What do you observe, in particular for Vmid and inductor current? Are there any subharmonic oscillations? Why? Take a scope shot for the report so that the transient and steady-state for Vmid are visible.
  3. Next, we will tune the Ramp_gain and Rp1 potentiometers to add ramp compensation and improve dynamic performance.
  4. As you increase Ramp_gain for a fixed Rp1, what do you observe on Vmid and inductor current? Does it make sense? Take multiple scope shots to explain the phenomenon in the report so that the transient and steady-state for Vmid are visible.
  5. As you increase Rp1 (outer loop voltage mode controller gain) for a fixed Ramp_gain, what do you observe on Vmid and inductor current? Does it make sense? Take multiple scope shots to explain the phenomenon in the report so that the transient and steady-state for Vmid are visible.
  6. Increase the load to 2.38 Ohm (by turning on all the load resistors)
  7. Tune Ramp_gain and Rp1 to achieve the fastest rise time with no overshoot on output voltage and without subharmonic oscillations in the inductor current. Note the rise time and take a scope shot for the report so that the transient and steady-state for Vmid are visible.
  8. Now we will remove the load in steps and compare the performance. Increase the load resistance gradually from 2.38 Ohm to 51 Ohm. At each step, take scope shots and explain the observation in the report.
  9. If time permits, turn off the dc power supply. Disconnect the signal generator from V_ref, then reset the offset to 1.125 V and the peak-to-peak amplitude to 1.25 V. Ensure the signal generator output is within 0 and 5 V before connecting it back to V_ref. This should give us a command alternating between 2 V and 7 V at the output. Ensure the load resistance is 8.36 Ohms. Turn on the dc power supply and repeat steps 2 through 8.

Turn off Checklist

Before we close the experiment, please ensure:

Turn-Off & Shutdown Checklist

🧠 Observations & Analysis

Now, let us analyze the data you collected to write a brief report that solidifies our understanding. Structure the report to include the following:

  1. Restate the objectives of this experiment in your own words. Your response should address the following: How does controller design (Type I vs Type II) influence the transient response of a buck converter? What is the effect of controller gain on rise time, overshoot, and settling time? How does the load resistance influence the transient response, and how does this compare to the effect of controller design?
  2. Theory: Explain the role of the controller in shaping transient response: Why does increasing gain generally reduce rise time but increase overshoot? What is the role of the integrator (Type I) in steady-state accuracy? What additional feature does a Type II controller introduce, and how does it improve performance? Discuss how phase margin is related to: Overshoot, Damping, and Robustness.
  3. Using the scope shot of Step 3, explain the controller action and switching signal. Explain how the inductor current transients during the step change. Can you identify the effect of the reference feedforward on the controller output?
  4. Gain Variation Analysis (Type I Controller): Using the data collected in Subgroup 1, analyze the effect of increasing gain: As gain increases, how does rise time change? How does overshoot vary? Does the system transition from overdamped → underdamped behavior?
  5. Load Variation Analysis (Type I Controller) Using the data collected in Subgroup 2, analyze the effect of load variation: As load resistance increases (heavy → light load), how does: Does the system become more or less damped at light load?
  6. Gain Variation Analysis (Type II Controller)
  7. Using the data collected in Subgroup 3, repeat the same analysis: Compare rise time and overshoot trends with Type I. For the same overshoot, does Type II achieve faster response? For the same rise time, does Type II reduce overshoot? Explain why Type II outperforms Type I, referring to: Phase boost, improved phase margin near crossover.
  8. Using the data collected in Subgroup 4, repeat the analysis and compare the results with those from Type I. At which load condition does Type II provide the most benefit? At which load condition do Type I and Type II behave similarly? Explain why controller influence reduces at heavy load.
  9. Controller vs Plant Dominance: Based on your observations, when does the controller dominate system behavior? When does the plant (LC + load) dominate behavior? Explain how this depends on: Load resistance and Damping
  10. What would be the trade-off of changing the controller structure from Type II to Type III?
  11. If you have step 14, show your theoretical calculations along with experimental results and compare them.
  12. Write a short conclusion summarizing the main findings of the experiment. Your conclusion should address: How does controller design influence transient performance? Why does Type II provide improved performance over Type I? The role of load in determining system damping. The importance of balancing speed and stability in control design.

✔ Conclusion

The experiment demonstrates that controller design and gain strongly shape the transient response, with Type II control achieving a superior balance between speed and damping, while load conditions ultimately determine the system’s inherent performance limits.

🔍 References & further reading

  • Erickson, R.W. and Maksimovic, D. (2020). Fundamentals of Power Electronics. 3rd Edition, Springer, Berlin.
  • J. H. B. Deane, "Chaos in a current-mode controlled boost DC-DC converter," in IEEE Transactions on Circuits and Systems I: Fundamental Theory and Applications, vol. 39, no. 8, pp. 680-683, Aug. 1992, doi: 10.1109/81.168922
  • Dave Perreault: Lecture 27: Current mode control, https://www.youtube.com/watch?v=WJNPGXivqew&t=354s