VoltageToDutyCycle

block VoltageToDutyCycle "Linearly transforms voltage to duty cycle"
    parameter Boolean useBipolarVoltage = true "Enables bipolar input voltage range";
    parameter Boolean useConstantMaximumVoltage = true "Enables constant maximum voltage";
    parameter Modelica.SIunits.Voltage vMax = 0 "Maximum voltage range mapped to dutyCycle = 1"
        annotation (Dialog(enable = useConstantMaximumVoltage));
    Modelica.Blocks.Interfaces.RealInput v "Voltage"
        annotation (Placement(
            transformation(extent = {
                {-140, -20}, 
                {-100, 20}}),
            iconTransformation(extent = {
                {-140, -20}, 
                {-100, 20}})));
    Modelica.Blocks.Interfaces.RealOutput dutyCycle "Duty cycle"
        annotation (Placement(
            transformation(extent = {
                {100, -10}, 
                {120, 10}}),
            iconTransformation(extent = {
                {100, -10}, 
                {120, 10}})));
    Blocks.Math.Division divisionUnipolar if not useBipolarVoltage annotation (Placement(transformation(extent = {
        {-40, 20}, 
        {-20, 40}})));
    Blocks.Math.Division divisionBipolar if useBipolarVoltage annotation (Placement(transformation(extent = {
        {-40, -40}, 
        {-20, -20}})));
    Modelica.Blocks.Math.Add add(k1 = 0.5, k2 = 1) if useBipolarVoltage annotation (Placement(transformation(extent = {
        {0, -60}, 
        {20, -40}})));
    Modelica.Blocks.Sources.Constant offset(final k = 0.5) if useBipolarVoltage "Offset of 0.5 in case of bipolar operation"
        annotation (Placement(transformation(extent = {
            {-40, -80}, 
            {-20, -60}})));
    Blocks.Interfaces.RealInput vMaxExt if not useConstantMaximumVoltage "External maximum voltage"
        annotation (Placement(
            transformation(
                extent = {
                    {-20, -20}, 
                    {20, 20}},
                rotation = 270,
                origin = {0, 120}),
            iconTransformation(
                extent = {
                    {-20, -20}, 
                    {20, 20}},
                rotation = 270,
                origin = {0, 120})));
    Blocks.Sources.Constant vMaxConst(final k = vMax) if useConstantMaximumVoltage "Offset of 0.5 in case of bipolar operation"
        annotation (Placement(transformation(extent = {
            {40, 70}, 
            {20, 90}})));
protected
    Blocks.Interfaces.RealInput vMaxInt "External maximum voltage"
        annotation (Placement(transformation(
            extent = {
                {-4, -4}, 
                {4, 4}},
            rotation = 180,
            origin = {0, 80})));
equation
    connect(v,divisionBipolar.u1) annotation (Line(
        points = {
            {-120, 0}, 
            {-80, 0}, 
            {-80, -24}, 
            {-42, -24}},
        color = {0, 0, 127}));
    connect(v,divisionUnipolar.u1) annotation (Line(
        points = {
            {-120, 0}, 
            {-80, 0}, 
            {-80, 36}, 
            {-42, 36}},
        color = {0, 0, 127}));
    connect(vMaxExt,vMaxInt) annotation (Line(
        points = {
            {0, 120}, 
            {0, 80}},
        color = {0, 0, 127}));
    connect(vMaxInt,vMaxConst.y) annotation (Line(
        points = {
            {0, 80}, 
            {19, 80}},
        color = {0, 0, 127}));
    connect(vMaxInt,divisionBipolar.u2) annotation (Line(
        points = {
            {0, 80}, 
            {-60, 80}, 
            {-60, -36}, 
            {-42, -36}},
        color = {0, 0, 127}));
    connect(vMaxInt,divisionUnipolar.u2) annotation (Line(
        points = {
            {0, 80}, 
            {-60, 80}, 
            {-60, 24}, 
            {-42, 24}},
        color = {0, 0, 127}));
    connect(add.y,dutyCycle) annotation (Line(
        points = {
            {21, -50}, 
            {40, -50}, 
            {40, 0}, 
            {110, 0}},
        color = {0, 0, 127}));
    connect(offset.y,add.u2) annotation (Line(
        points = {
            {-19, -70}, 
            {-10, -70}, 
            {-10, -56}, 
            {-2, -56}},
        color = {0, 0, 127}));
    connect(divisionBipolar.y,add.u1) annotation (Line(
        points = {
            {-19, -30}, 
            {-10, -30}, 
            {-10, -44}, 
            {-2, -44}},
        color = {0, 0, 127}));
    connect(divisionUnipolar.y,dutyCycle) annotation (Line(
        points = {
            {-19, 30}, 
            {40, 30}, 
            {40, 0}, 
            {110, 0}},
        color = {0, 0, 127}));

    annotation (
        defaultComponentName = "adaptor",
        Icon(graphics = {
            Rectangle(
                extent = {
                    {-100, 100}, 
                    {100, -100}},
                fillColor = {255, 255, 255},
                fillPattern = FillPattern.Solid), 
            Line(
                points = {
                    {0, -60}, 
                    {60, 60}},
                pattern = LinePattern.Dash), 
            Line(points = {
                {-60, -60}, 
                {60, 60}}), 
            Polygon(
                points = {
                    {-78, -60}, 
                    {-76, -60}, 
                    {62, -60}, 
                    {62, -54}, 
                    {82, -60}, 
                    {62, -66}, 
                    {62, -60}, 
                    {62, -60}, 
                    {-78, -60}},
                fillPattern = FillPattern.Solid), 
            Polygon(
                points = {
                    {0, -80}, 
                    {0, 60}, 
                    {-6, 60}, 
                    {0, 80}, 
                    {6, 60}, 
                    {0, 60}, 
                    {0, -80}},
                fillPattern = FillPattern.Solid), 
            Text(
                extent = {
                    {-150, -120}, 
                    {150, -160}},
                textString = "%name",
                lineColor = {0, 0, 255})}),
        Documentation(info = "<html>\nThis model linearly transforms the input voltage signal into a duty cycle. For the unipolar case the input voltage range is between zero and <code>vMax</code>. In case of bipolar input the input voltage is in the range between <code>-vMax</code> and <code>vMax</code>.\n</html>"));
end VoltageToDutyCycle;