Skip to content

Commit

Permalink
Merge pull request #3897 from AHaumer/HBridge
Browse files Browse the repository at this point in the history
PowerConverters.DCDC.HBridge
  • Loading branch information
christiankral authored Jan 19, 2022
2 parents 0021e1a + 4eaef61 commit 5ce526c
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 50 deletions.
108 changes: 79 additions & 29 deletions Modelica/Electrical/PowerConverters/DCDC/Control/SignalPWM.mo
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ model SignalPWM
parameter SI.Frequency f=1000 "Switching frequency";
parameter SingleReferenceType refType=Modelica.Electrical.PowerConverters.Types.SingleReferenceType.Sawtooth
"Type of reference signal";
parameter Boolean commonComparison=true "Common or separated comparison for fire_p and fire_n"
annotation(choices(checkBox=true));
parameter SI.Time startTime=0 "Start time";
Modelica.Blocks.Interfaces.RealInput dutyCycle if not
useConstantDutyCycle "Duty cycle"
Expand All @@ -26,23 +28,23 @@ model SignalPWM
origin={60,110})));
Modelica.Blocks.Sources.Constant const(final k=constantDutyCycle) if
useConstantDutyCycle
annotation (Placement(transformation(extent={{-100,-60},{-80,-40}})));
annotation (Placement(transformation(extent={{-10,-10},{10,10}},
rotation=90,
origin={-90,-30})));
Modelica.Blocks.Nonlinear.Limiter limiter(uMax=1, uMin=0)
annotation (Placement(transformation(extent={{-60,-10},{-40,10}})));
Modelica.Blocks.Logical.Less greaterEqual annotation (Placement(
transformation(
extent={{-10,10},{10,-10}},
origin={22,-8})));
annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));

Modelica.Blocks.Discrete.ZeroOrderHold zeroOrderHold(final startTime=
startTime, final samplePeriod=1/f)
annotation (Placement(transformation(extent={{-30,-10},{-10,10}})));
annotation (Placement(transformation(extent={{-40,-10},{-20,10}})));
Modelica.Blocks.Sources.SawTooth sawtooth(
final period=1/f,
final amplitude=1,
final nperiod=-1,
final offset=0,
final startTime=startTime) if refType==SingleReferenceType.Sawtooth
annotation (Placement(transformation(origin={-50,-50}, extent={{-10,-10},{10,10}})));
annotation (Placement(transformation(origin={20,30}, extent={{-10,-10},{10,10}},
rotation=90)));
Modelica.Blocks.Sources.Trapezoid triangle(
rising=0.5/f,
width=0,
Expand All @@ -52,31 +54,65 @@ model SignalPWM
final nperiod=-1,
final offset=0,
final startTime=startTime) if refType==SingleReferenceType.Triangle
annotation (Placement(transformation(origin={-50,-80}, extent={{-10,-10},{10,10}})));
Modelica.Blocks.Logical.Not inverse annotation (Placement(
annotation (Placement(transformation(origin={-20,30}, extent={{-10,-10},{10,10}},
rotation=90)));
Blocks.Logical.Greater greaterEqual_p annotation (Placement(
transformation(
extent={{-10,-10},{10,10}},
origin={-60,70},
rotation=90)));
Modelica.Blocks.Logical.Not inverse if commonComparison
annotation (Placement(
transformation(
extent={{-10,10},{10,-10}},
rotation=0,
origin={0,90})));
Blocks.Math.Add add(final k1=-1, final k2=+1) if
not commonComparison
annotation (Placement(transformation(extent={{0,-10},{20,10}})));
Blocks.Sources.Constant constOne(final k=1) if not commonComparison
annotation (Placement(
transformation(
extent={{-10,-10},{10,10}},
rotation=90,
origin={52,20})));
origin={-10,-30})));
Blocks.Logical.Greater greaterEqual_n if not commonComparison
annotation (Placement(transformation(
extent={{-10,10},{10,-10}},
origin={60,70},
rotation=90)));
equation
connect(const.y, limiter.u) annotation (Line(
points={{-79,-50},{-70,-50},{-70,0},{-62,0}}, color={0,0,127}));
points={{-90,-19},{-90,0},{-72,0}}, color={0,0,127}));
connect(dutyCycle, limiter.u) annotation (Line(
points={{-120,0},{-62,0}}, color={0,0,127}));
points={{-120,0},{-72,0}}, color={0,0,127}));
connect(limiter.y, zeroOrderHold.u) annotation (Line(
points={{-39,0},{-32,0}}, color={0,0,127}));
connect(zeroOrderHold.y, greaterEqual.u2) annotation (Line(
points={{-9,0},{10,0}}, color={0,0,127}));
connect(sawtooth.y, greaterEqual.u1) annotation (Line(
points={{-39,-50},{0,-50},{0,-8},{10,-8}}, color={0,0,127}));
connect(greaterEqual.y, inverse.u) annotation (Line(
points={{33,-8},{52,-8},{52,8}}, color={255,0,255}));
connect(greaterEqual.y, fire) annotation (Line(
points={{33,-8},{36,-8},{36,80},{-60,80},{-60,110}}, color={255,0,255}));
connect(inverse.y, notFire) annotation (Line(
points={{52,31},{52,80},{60,80},{60,110}}, color={255,0,255}));
connect(greaterEqual.u1, triangle.y) annotation (Line(points={{10,-8},{0,-8},{
0,-80},{-39,-80}}, color={0,0,127}));
points={{-49,0},{-42,0}}, color={0,0,127}));
connect(zeroOrderHold.y, add.u1)
annotation (Line(points={{-19,0},{-10,0},{-10,6},{-2,6}}, color={0,0,127}));
connect(constOne.y, add.u2)
annotation (Line(points={{-10,-19},{-10,-6},{-2,-6}}, color={0,0,127}));
connect(zeroOrderHold.y, greaterEqual_p.u1) annotation (Line(points={{-19,0},{-10,
0},{-10, 18},{-60, 18},{-60,58}}, color={0,0,127}));
connect(add.y, greaterEqual_n.u1)
annotation (Line(points={{21,0},{60,0},{60,58}}, color={0,0,127}));
connect(greaterEqual_p.y, fire)
annotation (Line(points={{-60,81},{-60,110}}, color={255,0,255}));
connect(greaterEqual_n.y, notFire)
annotation (Line(points={{60,81},{60,110}}, color={255,0,255}));
connect(greaterEqual_p.y, inverse.u)
annotation (Line(points={{-60,81},{-60,90},{-12,90}}, color={255,0,255}));
connect(inverse.y, notFire)
annotation (Line(points={{11,90},{60,90},{60,110}}, color={255,0,255}));
connect(triangle.y, greaterEqual_p.u2) annotation (Line(points={{-20,41},{-20,52},
{-52,52},{-52,58}}, color={0,0,127}));
connect(triangle.y, greaterEqual_n.u2) annotation (Line(points={{-20,41},{-20,48},
{52,48},{52,58}}, color={0,0,127}));
connect(greaterEqual_n.u2, sawtooth.y) annotation (Line(points={{52,58},{52,48},
{20,48},{20,41}}, color={0,0,127}));
connect(greaterEqual_p.u2, sawtooth.y) annotation (Line(points={{-52,58},{-52,
52},{20,52},{20,41}},
color={0,0,127}));
annotation (defaultComponentName="pwm",
Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},
{100,100}}),graphics={Line(
Expand All @@ -102,8 +138,8 @@ equation
Documentation(info="<html>
<p>
This controller can be used both for DC/DC and AC/DC converters.
The signal input of the PWM controller is the duty cycle; the duty cycle is the ratio of the on time
to the switching period. The output firing signal is strictly determined by the actual duty cycle, indicated as <code>d</code> in Fig.&nbsp;1.
The signal input of the PWM controller is the duty cycle; the duty cycle is the ratio of the on time to the switching period.
The output firing signal is strictly determined by the actual duty cycle, indicated as <code>d</code> in Fig.&nbsp;1.
</p>
<table border=\"0\" cellspacing=\"0\" cellpadding=\"2\">
Expand All @@ -116,7 +152,21 @@ to the switching period. The output firing signal is strictly determined by the
</table>
<p>
The firing signal is generated by comparing the sampled duty cycle input with a periodic saw tooth signal [<a href=\"modelica://Modelica.Electrical.PowerConverters.UsersGuide.References\">Williams2006</a>].
The firing signal is generated by comparing the sampled duty cycle input with a periodic saw tooth
[<a href=\"modelica://Modelica.Electrical.PowerConverters.UsersGuide.References\">Williams2006</a>] or triangular signal (carrier).
</p>
<h4>Note</h4>
<p>
The user has the choice between two comparison modes:
</p>
<p>commonComparison = true :
The result of the comparison dutyCyle &gt; carrier is fed to fire_p, the inverse signal to fire_n.
</p>
<p>commonComparison = false:
The result of the comparison dutyCyle &gt; carrier is fed to fire_p,
the result of the comparison (1 - dutyCyle) &gt; carrier is fed to fire_n.
(The result is the same for the comparison dutyCycle &gt; (1 - carrier), i.e. a signal shifted by 180&deg;.)
</p>
</html>"));
end SignalPWM;
70 changes: 50 additions & 20 deletions Modelica/Electrical/PowerConverters/DCDC/HBridge.mo
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ model HBridge "H bridge (four quadrant converter)"
final GoffDiode=GoffDiode,
final VkneeDiode=VkneeDiode,
final useHeatPort=useHeatPort)
annotation (Placement(transformation(extent={{-20,20},{0,40}})));
annotation (Placement(transformation(extent={{-30,20},{-10,40}})));
DCAC.SinglePhase2Level inverter_n(
final RonTransistor=RonTransistor,
final GoffTransistor=GoffTransistor,
Expand All @@ -34,7 +34,7 @@ model HBridge "H bridge (four quadrant converter)"
final GoffDiode=GoffDiode,
final VkneeDiode=VkneeDiode,
final useHeatPort=useHeatPort)
annotation (Placement(transformation(extent={{-58,-40},{-38,-20}})));
annotation (Placement(transformation(extent={{10,-30},{30,-10}})));
Modelica.Blocks.Interfaces.BooleanInput fire_p
"Firing signals of positive potential leg" annotation (Placement(
transformation(
Expand All @@ -47,34 +47,43 @@ model HBridge "H bridge (four quadrant converter)"
extent={{-20,-20},{20,20}},
rotation=90,
origin={60,-120})));
Blocks.Logical.Not not_p
annotation (Placement(transformation(extent={{-50,-10},{-30,10}})));
Blocks.Logical.Not not_n
annotation (Placement(transformation(extent={{50,-60},{30,-40}})));
equation
if not useHeatPort then
LossPower = inverter_p.LossPower + inverter_n.LossPower;
end if;
connect(inverter_n.heatPort, heatPort) annotation (Line(
points={{-48,-40},{-48,-70},{-10,-70},{-10,-100},{0,-100}}, color={191,0,0}));
points={{20,-30},{20,-100},{0,-100}}, color={191,0,0}));
connect(inverter_p.heatPort, heatPort) annotation (Line(
points={{-10,20},{-10,-100},{0,-100}}, color={191,0,0}));
points={{-20,20},{-20,-100},{0,-100}}, color={191,0,0}));
connect(dc_p1, inverter_p.dc_p) annotation (Line(
points={{-100,60},{-70,60},{-70,36},{-20,36}}, color={0,0,255}));
points={{-100,60},{-70,60},{-70,36},{-30,36}}, color={0,0,255}));
connect(dc_p1, inverter_n.dc_p) annotation (Line(
points={{-100,60},{-70,60},{-70,-24},{-58,-24}}, color={0,0,255}));
points={{-100,60},{-70,60},{-70,-14},{10,-14}}, color={0,0,255}));
connect(dc_n1, inverter_n.dc_n) annotation (Line(
points={{-100,-60},{-80,-60},{-80,-36},{-58,-36}}, color={0,0,255}));
points={{-100,-60},{-80,-60},{-80,-26},{10,-26}}, color={0,0,255}));
connect(dc_n1, inverter_p.dc_n) annotation (Line(
points={{-100,-60},{-80,-60},{-80,24},{-20,24}}, color={0,0,255}));
points={{-100,-60},{-80,-60},{-80,24},{-30,24}}, color={0,0,255}));
connect(inverter_p.ac, dc_p2) annotation (Line(
points={{0,30},{100,30},{100,60}}, color={0,0,255}));
points={{-10,30},{100,30},{100,60}},
color={0,0,255}));
connect(inverter_n.ac, dc_n2) annotation (Line(
points={{-38,-30},{100,-30},{100,-60}}, color={0,0,255}));
connect(andCondition_n.y, inverter_p.fire_n) annotation (Line(
points={{60,-69},{60,-50},{-4,-50},{-4,18}}, color={255,0,255}));
connect(andCondition_n.y, inverter_n.fire_p) annotation (Line(
points={{60,-69},{60,-50},{-54,-50},{-54,-42}}, color={255,0,255}));
connect(andCondition_p.y, inverter_n.fire_n) annotation (Line(
points={{-60,-69},{-60,-60},{-42,-60},{-42,-42}}, color={255,0,255}));
connect(andCondition_p.y, inverter_p.fire_p) annotation (Line(
points={{-60,-69},{-60,-60},{-16,-60},{-16,18}}, color={255,0,255}));
points={{30,-20},{100,-20},{100,-60}}, color={0,0,255}));
connect(andCondition_p.y, inverter_p.fire_p) annotation (Line(points={{-60,-69},
{-60, 14},{-26, 14},{-26,18}}, color={255,0,255}));
connect(andCondition_n.y, inverter_n.fire_p) annotation (Line(points={{60,-69},
{60, -64},{14, -64},{14,-32}}, color={255,0,255}));
connect(not_p.y, inverter_p.fire_n)
annotation (Line(points={{-29,0},{-14,0},{-14,18}}, color={255,0,255}));
connect(andCondition_p.y, not_p.u)
annotation (Line(points={{-60,-69},{-60,0},{-52,0}}, color={255,0,255}));
connect(andCondition_n.y, not_n.u)
annotation (Line(points={{60,-69},{60,-50},{52,-50}}, color={255,0,255}));
connect(not_n.y, inverter_n.fire_n)
annotation (Line(points={{29,-50},{26,-50},{26,-32}}, color={255,0,255}));
annotation (defaultComponentName="dcdc",
Icon(graphics={
Rectangle(
Expand Down Expand Up @@ -130,8 +139,29 @@ The H bridge is a four quadrant DC/DC converter. It consists of two single-phase
</tr>
</table>
<p>If the firing inputs <code>fire_p</code> and <code>fire_n</code> are inverse, the two legs are controlled symmetrically so that full positive or negative output voltage can be generated. See examples
<a href=\"modelica://Modelica.Electrical.PowerConverters.Examples.DCDC.HBridge\">DCDC.HBridge</a>.
<p>If the firing inputs <code>fire_p</code> and <code>fire_n</code> are inverse, the two legs are controlled symmetrically so that full positive or negative output voltage can be generated.
See examples <a href=\"modelica://Modelica.Electrical.PowerConverters.Examples.DCDC.HBridge\">DCDC.HBridge</a>.
</p>
<h4>Note</h4>
<p>In the first version, the following signal connections were implementented:</p>
<ul>
<li>fire_p to inverter_p.fire_p and inverter_n.fire_n</li>
<li>fire_n to inverter_p.fire_n and inverter_n.fire_p</li>
</ul>
<p>Therefore the two fire signal had be supplied complentary to avoid a short circuit on the source.</p>
<p>In the enhanced version, the following signal connections are implementented:</p>
<ul>
<li>inverter_p.fire_p to fire_p</li>
<li>inverter_p.fire_n to not fire_p</li>
<li>inverter_n.fire_p to fire_n</li>
<li>inverter_n.fire_n to not fire_n</li>
</ul>
<p>Therefore a short circuit on the source is avoided intrinsically.</p>
<p>
If both versions are provided with the same (complementary) fire signals, identical results are obtained.
Additionally, two more switching states are possible:
fire_p = fire_n = true (which means switching on both upper switches) and fire_p = fire_n = false (which means switching on both lower switches).
</p>
</html>"));
end HBridge;
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
within Modelica.Electrical.PowerConverters.Examples.DCDC.HBridge;
model HBridge_DC_Drive "H bridge DC/DC converter with DC drive"
extends ExampleTemplates.HBridge(signalPWM(useConstantDutyCycle=false),
extends ExampleTemplates.HBridge(signalPWM(useConstantDutyCycle=false,
refType=Modelica.Electrical.PowerConverters.Types.SingleReferenceType.Triangle,
commonComparison=false),
constantVoltage(V=120));

extends Modelica.Icons.Example;
parameter SI.Inductance Ld=3*dcpmData.La
"Smoothing inductance";
Expand Down
6 changes: 6 additions & 0 deletions Modelica/package.mo
Original file line number Diff line number Diff line change
Expand Up @@ -2391,6 +2391,12 @@ The following <font color=\"blue\"><strong>existing components</strong></font> h
<tr><td colspan=\"2\"><strong>Modelica.Blocks.Tables</strong></td></tr>
<tr><td>CombiTable1Ds<br>CombiTable1Dv<br>CombiTable2Ds<br>CombiTable2Dv</td>
<td>Added support of reading CSV files.</td></tr>
<tr><td colspan=\"2\"><strong>Electrical.PowerConverters.DCDC</strong></td></tr>
<tr><td>HBridge</td>
<td>An enhanced distribution of the fire signals avoids a short circuit on the source, and enables an enhanced pwm algorithm.</td></tr>
<tr><td>Control.SignalPWM</td>
<td>The reference signal can be choosen between sawtooth and triangle, and
the comparison between dutyCycle and reference signal is either applied common or separated for both fire ports.</td></tr>
<tr><td colspan=\"2\"><strong>Mechanics.Rotational.Components</strong></td></tr>
<tr><td>BearingFriction</td>
<td>The table interpolation in <code>tau_pos</code> utilizes the interpolation based on <a href=\"modelica://Modelica.Blocks.Types.ExternalCombiTable1D\">ExternalCombiTable1D</a>.</td></tr>
Expand Down

0 comments on commit 5ce526c

Please sign in to comment.