package EmbeddedControl extends Modelica.Icons.Package; package Boundary model ADC extends Modelica.Blocks.Icons.DiscreteBlock; parameter Real stepSize = 0.1; parameter Real scale = 1; Modelica.Blocks.Interfaces.RealInput u annotation( Placement(transformation(origin = {-122, 2}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {-120, 0}, extent = {{-20, -20}, {20, 20}}))); Modelica.Blocks.Interfaces.IntegerOutput y annotation( Placement(transformation(origin = {86, -34}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {110, 0}, extent = {{-10, -10}, {10, 10}}))); Modelica.Blocks.Interfaces.BooleanInput tickInput annotation( Placement(transformation(origin = {-130, -88}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {0, -120}, extent = {{-20, -20}, {20, 20}}, rotation = 90))); protected discrete Integer yInt(start=0, fixed=true); algorithm when tickInput then yInt := integer(floor((scale*u)/stepSize+ 0.5)); end when; equation y = yInt; annotation( Documentation(info = "

Integer analog-to-digital conversion block.

The real-valued input u is quantized to an integer code using:

y = floor((scale*u)/stepSize + 0.5)

This produces a rounded integer representation of the scaled input, intended for embedded-style control chains that operate on integer counts.

Parameters:

"), Icon(graphics = {Line(origin = {5, 10}, points = {{-61, -68}, {-35, -68}, {-35, -22}, {-21, -22}, {-21, 38}, {7, 38}, {7, 68}, {41, 68}, {41, 24}, {61, 24}, {61, 24}}, color = {255, 85, 0}, thickness = 1.25), Text(origin = {49, -50}, extent = {{-51, 50}, {51, -50}}, textString = "AD")})); end ADC; model DAC extends Modelica.Blocks.Icons.DiscreteBlock; parameter Real stepSize = 0.1; parameter Real scale = 1; Modelica.Blocks.Interfaces.IntegerInput u annotation( Placement(transformation(origin = {-136, -2}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {-120, 0}, extent = {{-20, -20}, {20, 20}}))); Modelica.Blocks.Interfaces.RealOutput y annotation( Placement(transformation(origin = {126, 10}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {110, 0}, extent = {{-10, -10}, {10, 10}}))); Modelica.Blocks.Interfaces.BooleanInput tickInput annotation( Placement(transformation(origin = {-130, -88}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {0, -120}, extent = {{-20, -20}, {20, 20}}, rotation = 90))); protected discrete Real yReal(start = 0, fixed = true); algorithm when tickInput then yReal := (stepSize * scale) * u; end when; equation y = yReal; annotation( Documentation(info = "

Integer digital-to-analog conversion block.

The integer input u is mapped back to a real-valued physical signal using:

y = (stepSize*scale)*u

When used with matching parameter values, this block acts as the inverse conversion of the ADC block.

Parameters:

"), Diagram(graphics), Icon(graphics = {Line(origin = {5, 10}, points = {{-61, -68}, {-35, -68}, {-35, -22}, {-21, -22}, {-21, 38}, {7, 38}, {7, 68}, {41, 68}, {41, 24}, {61, 24}, {61, 24}}, color = {0, 0, 127}, thickness = 1.25, smooth = Smooth.Bezier), Text(origin = {49, -50}, extent = {{-51, 50}, {51, -50}}, textString = "DA")})); end DAC; extends Modelica.Icons.Package; model tickGenerator extends Modelica.Blocks.Interfaces.partialBooleanSource; Modelica.Blocks.Interfaces.IntegerOutput tickPeriodUs annotation( Placement(transformation(origin = {134, -58}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {110, -80}, extent = {{-10, -10}, {10, 10}}))); Modelica.Blocks.Sources.SampleTrigger sampleTrigger(period = period) annotation( Placement(transformation(extent = {{-10, -10}, {10, 10}}))); parameter Modelica.Units.SI.Time period = 0.1; equation tickPeriodUs = integer(period*1000*1000); connect(sampleTrigger.y, y) annotation( Line(points = {{12, 0}, {110, 0}}, color = {255, 0, 255})); annotation( Diagram(graphics), Icon(graphics = {Line(points = {{-60, -70}, {-60, 70}}), Line(points = {{-20, -70}, {-20, 70}}), Line(points = {{20, -70}, {20, 70}}), Line(points = {{60, -70}, {60, 70}})})); end tickGenerator; annotation( Icon(graphics = {Line(origin = {-48.92, -4.33}, points = {{-35.0829, -47.6744}, {-17.0829, 18.3256}, {-3.08288, -9.6744}, {10.9171, 48.3256}, {34.9171, 14.3256}, {34.9171, 14.3256}}, color = {0, 0, 127}, thickness = 1.5, smooth = Smooth.Bezier), Line( points = {{0, 81}, {0, -81}}, pattern = LinePattern.Dash, thickness = 2.75), Line(origin = {54, -10}, points = {{-36, -42}, {-36, -20}, {-30, -20}, {-30, -10}, {-20, -10}, {-20, 10}, {-6, 10}, {-6, 4}, {6, 4}, {6, 42}, {28, 42}, {28, 18}, {36, 18}, {36, 6}, {36, 6}}, color = {255, 85, 0}, thickness = 1.5)})); end Boundary; package Math extends Modelica.Icons.Package; model DDifference extends EmbeddedControl.Bases.discreteIntegerSISO; discrete Integer x(start=0, fixed=true) "Initial or guess value of state"; protected discrete Integer y_internal(start=0, fixed=true); algorithm if tickUpdate then y_internal := u - pre(x); x := u; end if; equation y = y_internal; annotation( Diagram(graphics), Icon(graphics = {Text(textColor = {156, 156, 156}, extent = {{-30, 14}, {86, 60}}, textString = "D"), Line(points = {{-90, -80}, {82, -80}}, color = {156, 156, 156}), Line(points = {{-80, 78}, {-80, -90}}, color = {156, 156, 156}), Polygon(lineColor = {156, 156, 156}, fillColor = {156, 156, 156}, fillPattern = FillPattern.Solid, points = {{-80, 90}, {-88, 68}, {-72, 68}, {-80, 90}}), Polygon(lineColor = {156, 156, 156}, fillColor = {156, 156, 156}, fillPattern = FillPattern.Solid, points = {{90, -80}, {68, -72}, {68, -88}, {90, -80}}), Line(origin = {-9, -4}, points = {{-63, 66}, {-63, 40}, {-53, 40}, {-53, -20}, {-39, -20}, {-39, -54}, {3, -54}, {3, -66}, {63, -66}, {63, -66}}, color = {255, 85, 0}, thickness = 0.5)})); end DDifference; model DAccumulate extends EmbeddedControl.Bases.discreteIntegerSISO; discrete Integer y_internal(start=0, fixed=true); algorithm if tickUpdate then y_internal := u + pre(y_internal); end if; equation y = y_internal; annotation( Diagram(graphics), Icon(graphics = {Line(points = {{-90, -80}, {82, -80}}, color = {156, 156, 156}), Line(points = {{-80, 78}, {-80, -90}}, color = {156, 156, 156}), Polygon(lineColor = {156, 156, 156}, fillColor = {156, 156, 156}, fillPattern = FillPattern.Solid, points = {{-80, 90}, {-88, 68}, {-72, 68}, {-80, 90}}), Polygon(lineColor = {156, 156, 156}, fillColor = {156, 156, 156}, fillPattern = FillPattern.Solid, points = {{90, -80}, {68, -72}, {68, -88}, {90, -80}}), Text(textColor = {156, 156, 156}, extent = {{0, -70}, {60, -10}}, textString = "A"), Line(origin = {-2, -1}, points = {{-70, -73}, {-70, -53}, {-48, -53}, {-48, -33}, {-26, -33}, {-26, -9}, {-2, -9}, {-2, 11}, {22, 11}, {22, 33}, {46, 33}, {46, 57}, {70, 57}, {70, 73}}, color = {255, 85, 0}, thickness = 0.5)})); end DAccumulate; model UnitDelay extends EmbeddedControl.Bases.discreteIntegerSISO; discrete Integer x(start=0, fixed=true) "Initial or guess value of state"; protected discrete Integer y_internal(start=0, fixed=true); algorithm if tickUpdate then y_internal := pre(x); x := u; end if; equation y = y_internal; annotation( Icon(graphics = {Text(textColor = {255, 85, 0},extent = {{-100, 100}, {100, -100}}, textString = "z"), Text(origin = {58, 50}, textColor = {255, 85, 0}, extent = {{-24, 22}, {24, -22}}, textString = "-1")})); end UnitDelay; model Gain extends EmbeddedControl.Bases.discreteIntegerSISO; parameter Integer k = 1; protected discrete Integer y_internal(start=0, fixed=true); algorithm y_internal := k * u; equation y = y_internal; annotation( Icon(graphics = {Text(textColor = {255, 85, 0}, extent = {{-100, 100}, {100, -100}}, textString = "k"), Text(extent = {{-150, -140}, {150, -100}}, textString = "k=%k")}), Diagram(graphics)); end Gain; model FractionalGain extends Bases.discreteIntegerSISO; parameter Integer k = 1; parameter Integer f = 1; protected discrete Integer y_internal(start=0, fixed=true); algorithm y_internal := div((k*u),f); equation y = y_internal; annotation( Icon(graphics = {Text(textColor = {255, 85, 0}, extent = {{-100, 100}, {100, -100}}, textString = "k"), Text(extent = {{-150, -140}, {150, -100}}, textString = "k=%k f=%f")}), Diagram(graphics)); end FractionalGain; model DDifferentiate extends EmbeddedControl.Bases.discreteIntegerSISO; discrete Integer x(start=0, fixed=true) "Initial or guess value of state"; parameter Integer scaleNumerator = 1000000; outer Integer tickPeriodUs; protected discrete Integer y_internal(start=0, fixed=true); algorithm if tickUpdate then y_internal := integer((u - pre(x))*scaleNumerator / tickPeriodUs); x := u; end if; equation y = y_internal; annotation( Diagram(graphics), Icon(graphics = {Text(textColor = {156, 156, 156}, extent = {{-30, 14}, {86, 60}}, textString = "DT1"), Line(points = {{-90, -80}, {82, -80}}, color = {156, 156, 156}), Line(points = {{-80, 78}, {-80, -90}}, color = {156, 156, 156}), Polygon(lineColor = {156, 156, 156}, fillColor = {156, 156, 156}, fillPattern = FillPattern.Solid, points = {{-80, 90}, {-88, 68}, {-72, 68}, {-80, 90}}), Polygon(lineColor = {156, 156, 156}, fillColor = {156, 156, 156}, fillPattern = FillPattern.Solid, points = {{90, -80}, {68, -72}, {68, -88}, {90, -80}}), Line(origin = {-9, -4}, points = {{-63, 66}, {-63, 40}, {-53, 40}, {-53, -20}, {-39, -20}, {-39, -54}, {3, -54}, {3, -66}, {63, -66}, {63, -66}}, color = {255, 85, 0}, thickness = 0.5)}), experiment(StartTime = 0, StopTime = 1, Tolerance = 1e-06, Interval = 0.002)); end DDifferentiate; model DIntegrate extends Bases.discreteIntegerSISO; discrete Integer y_internal(start = 0, fixed = true); parameter Integer scaleDenominator = 1000000; outer Integer tickPeriodUs; algorithm if tickUpdate then y_internal := u + pre(y_internal); end if; equation y = integer(y_internal*tickPeriodUs / scaleDenominator); annotation( Diagram(graphics), Icon(graphics = {Line(points = {{-90, -80}, {82, -80}}, color = {156, 156, 156}), Line(points = {{-80, 78}, {-80, -90}}, color = {156, 156, 156}), Polygon(lineColor = {156, 156, 156}, fillColor = {156, 156, 156}, fillPattern = FillPattern.Solid, points = {{-80, 90}, {-88, 68}, {-72, 68}, {-80, 90}}), Polygon(lineColor = {156, 156, 156}, fillColor = {156, 156, 156}, fillPattern = FillPattern.Solid, points = {{90, -80}, {68, -72}, {68, -88}, {90, -80}}), Text(textColor = {156, 156, 156}, extent = {{0, -70}, {60, -10}}, textString = "I"), Line(origin = {-2, -1}, points = {{-70, -73}, {-70, -53}, {-48, -53}, {-48, -33}, {-26, -33}, {-26, -9}, {-2, -9}, {-2, 11}, {22, 11}, {22, 33}, {46, 33}, {46, 57}, {70, 57}, {70, 73}}, color = {255, 85, 0}, thickness = 0.5)})); end DIntegrate; model ScaledGain extends Bases.discreteIntegerSISO; parameter Integer k = 1; parameter Integer scaleNumerator = 1000000; parameter Integer scaleDenominator = 1000000; outer Integer tickPeriodUs; parameter Boolean scaleMode = false; protected discrete Integer y_internal(start=0, fixed=true); algorithm if scaleMode then y_internal := integer(u * k * tickPeriodUs / scaleDenominator); else y_internal := integer(u * k * scaleNumerator / tickPeriodUs); end if; equation y = y_internal; annotation( Icon(graphics = {Text(textColor = {255, 85, 0}, extent = {{-100, 100}, {100, -100}}, textString = "k"), Text(extent = {{-150, -140}, {150, -100}}, textString = "k=%k")}), Diagram(graphics)); end ScaledGain; annotation( Icon(graphics = {Line(origin = {-0.95, 0.62}, points = {{-75.0496, -68.6246}, {-61.0496, 1.37545}, {-29.0496, 69.3754}, {-5.04956, 1.37545}, {20.9504, -64.6246}, {50.9504, -2.62455}, {74.9504, 65.3754}, {74.9504, 65.3754}}, color = {255, 85, 0}, thickness = 2, smooth = Smooth.Bezier)})); end Math; package Bases extends Modelica.Icons.BasesPackage; partial model ControlBase extends Modelica.Blocks.Icons.DiscreteBlock; Modelica.Blocks.Interfaces.BooleanInput tickInput annotation( Placement(iconTransformation(origin = {0, -120}, extent = {{-20, -20}, {20, 20}}, rotation = 90))); Modelica.Blocks.Interfaces.IntegerInput tickPeriodIn annotation( Placement(iconTransformation(origin = {-80, -120}, extent = {{-20, -20}, {20, 20}}, rotation = 90))); protected inner Boolean tickUpdate; inner Integer tickPeriodUs; inner Integer tickPeriodMs; inner Integer tickPeriodS; algorithm if tickInput then if pre(tickInput) then tickUpdate := false; else tickUpdate := true; end if; else tickUpdate := false; end if; equation tickPeriodUs = tickPeriodIn; tickPeriodMs = tickPeriodUs/1000; tickPeriodS = tickPeriodMs/1000; end ControlBase; partial model discreteInteger extends Modelica.Blocks.Icons.DiscreteBlock; outer Boolean tickUpdate; end discreteInteger; partial model discreteIntegerSISO extends EmbeddedControl.Bases.discreteInteger; Modelica.Blocks.Interfaces.IntegerInput u annotation( Placement(transformation(origin = {-100, 0}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {-120, 0}, extent = {{-20, -20}, {20, 20}}))); Modelica.Blocks.Interfaces.IntegerOutput y annotation( Placement(transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {110, 0}, extent = {{-10, -10}, {10, 10}}))); equation end discreteIntegerSISO; equation end Bases; annotation( Icon(graphics = {Text(origin = {1, 1}, textColor = {255, 170, 0}, extent = {{-99, 99}, {99, -99}}, textString = "EC", textStyle = {TextStyle.Bold})}), uses(Modelica(version = "4.1.0"))); end EmbeddedControl;