Fixed Modbus register access
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
<DUT Name="E_BATTERY_STATUS" Id="{99b02815-2b47-4159-a889-c86170baa34d}">
|
||||
<Declaration><![CDATA[{attribute 'qualified_only'}
|
||||
{attribute 'strict'}
|
||||
{attribute 'to_string'}
|
||||
TYPE E_BATTERY_STATUS :
|
||||
(
|
||||
ERROR := 1,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<DUT Name="E_CHARGE_STATUS" Id="{7a281462-bf73-4949-96d8-aca55bee6c60}">
|
||||
<Declaration><![CDATA[{attribute 'qualified_only'}
|
||||
{attribute 'strict'}
|
||||
{attribute 'to_string'}
|
||||
TYPE E_CHARGE_STATUS :
|
||||
(
|
||||
UNDEFINED := 1,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<DUT Name="E_REACTIVE_POWER_TYPE" Id="{e2c788a7-c536-4b02-910e-6cbe600afdab}">
|
||||
<Declaration><![CDATA[{attribute 'qualified_only'}
|
||||
{attribute 'strict'}
|
||||
{attribute 'to_string'}
|
||||
TYPE E_REACTIVE_POWER_TYPE :
|
||||
(
|
||||
INDUCTIVE := 1,
|
||||
|
||||
28
PLC/DUTs/Modbus/HoldingRegisters/ST_MODBUS_REG_10.TcDUT
Normal file
28
PLC/DUTs/Modbus/HoldingRegisters/ST_MODBUS_REG_10.TcDUT
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.12">
|
||||
<DUT Name="ST_MODBUS_REG_10" Id="{0c25ea41-552d-4ad4-8369-cc4ac1877b46}">
|
||||
<Declaration><![CDATA[{attribute 'pack_mode' := '1'}
|
||||
TYPE ST_MODBUS_REG_10 :
|
||||
STRUCT
|
||||
// Addr: 10.000
|
||||
sManufacturer : STRING(32); // 1 char = 1 byte
|
||||
|
||||
// Addr: 10.016
|
||||
sModelname : STRING(32);
|
||||
|
||||
// Addr: 10.032
|
||||
sSerialnumber : STRING(32);
|
||||
|
||||
// Addr: 10.048
|
||||
sBMSVersion : STRING(64);
|
||||
|
||||
// Addr: 10.080
|
||||
uiTotalParallelMembers : UINT; //uint 16bit = 1 Word
|
||||
|
||||
// Addr: 10.081
|
||||
uiActiveParallelMembers : UINT;
|
||||
END_STRUCT
|
||||
END_TYPE
|
||||
]]></Declaration>
|
||||
</DUT>
|
||||
</TcPlcObject>
|
||||
@@ -1,27 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.12">
|
||||
<DUT Name="ST_EMS_MODBUS_INTERFACE" Id="{c26c9ee9-feee-46cf-86e6-45d1a1e6819c}">
|
||||
<Declaration><![CDATA[TYPE ST_EMS_MODBUS_INTERFACE :
|
||||
<DUT Name="ST_MODBUS_REG_11" Id="{7e772293-d4e3-4809-9da8-3d4e0412ede6}">
|
||||
<Declaration><![CDATA[{attribute 'pack_mode' := '1'}
|
||||
TYPE ST_MODBUS_REG_11 :
|
||||
STRUCT
|
||||
// Size = 16 * 2 byte = 32 byte
|
||||
// Addr: 10.000
|
||||
sManufacturer : STRING(32); // 1 char = 1 byte
|
||||
|
||||
// Addr: 10.016
|
||||
sModelname : STRING(32);
|
||||
|
||||
// Addr: 10.032
|
||||
sSerialnumber : STRING(32);
|
||||
|
||||
// Addr: 10.048
|
||||
sBMSVersion : STRING(64);
|
||||
|
||||
// Addr: 10.080
|
||||
uiTotalParallelMembers : UINT; //uint 16bit = 1 Word
|
||||
|
||||
// Addr: 10.081
|
||||
uiActiveParallelMembers : UINT;
|
||||
|
||||
// Addr: 11.000
|
||||
eBatteryStatus : E_BATTERY_STATUS;
|
||||
|
||||
@@ -38,19 +20,19 @@ STRUCT
|
||||
|
||||
// Addr: 11.006
|
||||
// Unit: W
|
||||
udiMaxChargingActivePower : UDINT;
|
||||
udiMaxChargingActivePower : UDINT := 30_000;
|
||||
|
||||
// Addr: 11.008
|
||||
// Unit: W
|
||||
udiMaxDischargingActivePower : UDINT;
|
||||
udiMaxDischargingActivePower : UDINT := 30_000;
|
||||
|
||||
// Addr: 11.010
|
||||
// Unit: var
|
||||
udiMaxAvailableInductiveReactivePower : UDINT;
|
||||
udiMaxAvailableInductiveReactivePower : UDINT := 0;
|
||||
|
||||
// Addr: 11.012
|
||||
// Unit: var
|
||||
udiMaxAvailableCapacitiveReactivePower : UDINT;
|
||||
udiMaxAvailableCapacitiveReactivePower : UDINT := 0;
|
||||
|
||||
// Addr: 11.014
|
||||
// Unit: %
|
||||
@@ -58,11 +40,11 @@ STRUCT
|
||||
|
||||
// Addr: 11.015
|
||||
// Unit: %
|
||||
uiMaxAllowedSOC : UINT;
|
||||
uiMaxAllowedSOC : UINT := 100;
|
||||
|
||||
// Addr: 11.016
|
||||
// Unit: %
|
||||
uiMinAllowedSOC : UINT;
|
||||
uiMinAllowedSOC : UINT := 0;
|
||||
|
||||
// Addr: 11.017
|
||||
// Unit: %
|
||||
@@ -82,53 +64,43 @@ STRUCT
|
||||
|
||||
// Addr: 11.023
|
||||
// Unit: %
|
||||
uiCurrentSOH : UINT;
|
||||
uiCurrentSOH : UINT := 100;
|
||||
|
||||
// Addr: 11.024
|
||||
// Unit: A
|
||||
diTotalACCurrentPhase1 : DINT;
|
||||
|
||||
// Addr: 11.025
|
||||
// Addr: 11.026
|
||||
// Unit: A
|
||||
diTotalACCurrentPhase2 : DINT;
|
||||
|
||||
// Addr: 11.026
|
||||
// Addr: 11.028
|
||||
// Unit: A
|
||||
diTotalACCurrentPhase3 : DINT;
|
||||
|
||||
// Addr: 11.027
|
||||
// Addr: 11.030
|
||||
// Unit: W
|
||||
diSetpointActivePowerMirror : DINT;
|
||||
|
||||
// Addr: 11.028
|
||||
// Addr: 11.032
|
||||
rSetpointCosPhiMirror : REAL; // 32 bit
|
||||
|
||||
// Addr: 11.030
|
||||
// Addr: 11.034
|
||||
// Unit: W
|
||||
diCurrentActivePower : DINT;
|
||||
|
||||
// Addr: 11.031
|
||||
// Addr: 11.036
|
||||
// Unit: var
|
||||
diCurrentReactivePower : DINT;
|
||||
|
||||
// Addr: 11.032
|
||||
// Addr: 11.038
|
||||
udiLifeMessage : UDINT;
|
||||
|
||||
// Addr: 11.033
|
||||
// Addr: 11.040
|
||||
lwWarningBitmap : LWORD;
|
||||
|
||||
// Addr: 11.035
|
||||
// Addr: 11.044
|
||||
lwErrorBitmap : LWORD;
|
||||
|
||||
// Addr: 12.000
|
||||
// Unit: W
|
||||
diSetpointActivePower : DINT;
|
||||
|
||||
// Addr: 12.001
|
||||
rSetpointCosPhi : REAL;
|
||||
|
||||
// Addr: 12.003
|
||||
eReactivePowerType : E_REACTIVE_POWER_TYPE;
|
||||
END_STRUCT
|
||||
END_TYPE
|
||||
]]></Declaration>
|
||||
19
PLC/DUTs/Modbus/HoldingRegisters/ST_MODBUS_REG_12.TcDUT
Normal file
19
PLC/DUTs/Modbus/HoldingRegisters/ST_MODBUS_REG_12.TcDUT
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.12">
|
||||
<DUT Name="ST_MODBUS_REG_12" Id="{7c428918-2d8d-43ab-8096-edbee8bd4171}">
|
||||
<Declaration><![CDATA[{attribute 'pack_mode' := '1'}
|
||||
TYPE ST_MODBUS_REG_12 :
|
||||
STRUCT
|
||||
// Unit: W
|
||||
diSetpointActivePower : DINT;
|
||||
|
||||
// Addr: 12.002
|
||||
rSetpointCosPhi : REAL;
|
||||
|
||||
// Addr: 12.004
|
||||
eReactivePowerType : E_REACTIVE_POWER_TYPE;
|
||||
END_STRUCT
|
||||
END_TYPE
|
||||
]]></Declaration>
|
||||
</DUT>
|
||||
</TcPlcObject>
|
||||
28
PLC/DUTs/Modbus/ST_EMS_MODBUS_INTERFACE.TcDUT
Normal file
28
PLC/DUTs/Modbus/ST_EMS_MODBUS_INTERFACE.TcDUT
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.12">
|
||||
<DUT Name="ST_EMS_MODBUS_INTERFACE" Id="{c26c9ee9-feee-46cf-86e6-45d1a1e6819c}">
|
||||
<Declaration><![CDATA[// Speicherbereiche, welche über einen kontinuierlichen Registerbereich
|
||||
// gelesen werden sollen, müssen in einer Struktur mit dem attribut {attribute 'pack_mode' := '1'}
|
||||
// angelegt werden.
|
||||
// Der Grund ist, dass der TwinCAT Modbus Server beim zugriff über den ADS
|
||||
// Server nur die Symbolische erste Adresse anfragt und dann davon ausgeht,
|
||||
// dass die anderen Register im Speicherbereich hintereinander liegen.
|
||||
// Bei rein symbolisch angelegten Variablen müss dies nicht der Fall sein und es kommt zu einem
|
||||
// Fehler beim lesen über die symbolischen grenzen der variablen hinaus.
|
||||
|
||||
{attribute 'pack_mode' := '1'}
|
||||
TYPE ST_EMS_MODBUS_INTERFACE :
|
||||
STRUCT
|
||||
// Modbus Registers 10.000 to 10.999
|
||||
stModbusReg10 : ST_MODBUS_REG_10;
|
||||
|
||||
// Modbus Registers 11.000 to 11.999
|
||||
stModbusReg11 : ST_MODBUS_REG_11;
|
||||
|
||||
// Modbus Registers 12.000 to 12.999
|
||||
stModbusReg12 : ST_MODBUS_REG_12;
|
||||
END_STRUCT
|
||||
END_TYPE
|
||||
]]></Declaration>
|
||||
</DUT>
|
||||
</TcPlcObject>
|
||||
@@ -200,7 +200,7 @@ VAR_GLOBAL
|
||||
diMaxStringDischargePower : DINT := 30_000;
|
||||
|
||||
// Inverter ip address
|
||||
sInverterIp : STRING := '192.168.0.1';
|
||||
sInverterIp : STRING := '192.168.42.11';
|
||||
|
||||
// Absolute shutdown discharge power (Watt)
|
||||
rAbsShutdownDischargePower : REAL := 5_000;
|
||||
@@ -214,6 +214,9 @@ VAR_GLOBAL
|
||||
// String empty voltage (Volt)
|
||||
rStringEmptyVoltage : REAL := 672.0;
|
||||
|
||||
// Unit wait startup time
|
||||
timUnitStartupTime : TIME := T#5S;
|
||||
|
||||
END_VAR]]></Declaration>
|
||||
</GVL>
|
||||
</TcPlcObject>
|
||||
@@ -5,19 +5,16 @@
|
||||
VAR_GLOBAL
|
||||
// Modbus interface to customer EMS
|
||||
stModbusEMSComm : ST_EMS_MODBUS_INTERFACE := (
|
||||
sManufacturer := 'cmblu energy ag',
|
||||
sModelname := 'all liquid',
|
||||
sSerialnumber := '202312151643',
|
||||
sBMSVersion := '0.8.0',
|
||||
uiTotalParallelMembers := 2,
|
||||
eChargeStatus := E_CHARGE_STATUS.UNDEFINED,
|
||||
eBatteryStatus := E_BATTERY_STATUS.OFF);
|
||||
|
||||
// Modbus default config
|
||||
//mb_Input_Coils : ARRAY [0..255] OF BOOL;
|
||||
//mb_Output_Coils : ARRAY [0..255] OF BOOL;
|
||||
//mb_Input_Registers : ARRAY [0..255] OF WORD;
|
||||
//mb_Output_Registers : ARRAY [0..255] OF WORD;
|
||||
stModbusReg10 := (
|
||||
sManufacturer := 'cmblu energy ag',
|
||||
sModelname := 'all liquid',
|
||||
sSerialnumber := '202312151643',
|
||||
sBMSVersion := '0.8.0',
|
||||
uiTotalParallelMembers := 1),
|
||||
stModbusReg11 := (
|
||||
eChargeStatus := E_CHARGE_STATUS.UNDEFINED,
|
||||
eBatteryStatus := E_BATTERY_STATUS.OFF)
|
||||
);
|
||||
END_VAR]]></Declaration>
|
||||
</GVL>
|
||||
</TcPlcObject>
|
||||
19
PLC/GVLs/GVL_MQTT.TcGVL
Normal file
19
PLC/GVLs/GVL_MQTT.TcGVL
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.12">
|
||||
<GVL Name="GVL_MQTT" Id="{b8376b04-66fc-43a7-b673-600aa359c597}">
|
||||
<Declaration><![CDATA[{attribute 'qualified_only'}
|
||||
VAR_GLOBAL
|
||||
// Mqtt brocker ip address
|
||||
sMQTTBrokerAddr : STRING := '127.0.0.1';
|
||||
|
||||
// Mqtt keep alive (s)
|
||||
uiMQTTKeepAlive : UINT := 60;
|
||||
|
||||
// MQTT prefix
|
||||
sMQTTPrefix : STRING := 'cmblu/uniper/1/';
|
||||
|
||||
// MQTT QOS (Default 0 -> At most once; 1 -> At least once; 2 -> Exactly once
|
||||
eMQTTQoS : TcIoTMqttQos := TcIoTMqttQos.AtMostOnceDelivery;
|
||||
END_VAR]]></Declaration>
|
||||
</GVL>
|
||||
</TcPlcObject>
|
||||
@@ -27,7 +27,16 @@
|
||||
<Compile Include="DUTs\E_REACTIVE_POWER_TYPE.TcDUT">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DUTs\ST_EMS_MODBUS_INTERFACE.TcDUT">
|
||||
<Compile Include="DUTs\Modbus\HoldingRegisters\ST_MODBUS_REG_10.TcDUT">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DUTs\Modbus\HoldingRegisters\ST_MODBUS_REG_11.TcDUT">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DUTs\Modbus\HoldingRegisters\ST_MODBUS_REG_12.TcDUT">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DUTs\Modbus\ST_EMS_MODBUS_INTERFACE.TcDUT">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DUTs\ST_MODULE_HMI_INTERFACE.TcDUT">
|
||||
@@ -50,6 +59,10 @@
|
||||
<SubType>Code</SubType>
|
||||
<LinkAlways>true</LinkAlways>
|
||||
</Compile>
|
||||
<Compile Include="GVLs\GVL_MQTT.TcGVL">
|
||||
<SubType>Code</SubType>
|
||||
<LinkAlways>true</LinkAlways>
|
||||
</Compile>
|
||||
<Compile Include="GVLs\GVL_SCADA.TcGVL">
|
||||
<SubType>Code</SubType>
|
||||
<LinkAlways>true</LinkAlways>
|
||||
@@ -72,12 +85,17 @@
|
||||
<Compile Include="POUs\Sunspec\FB_PowerSupplySunspec.TcPOU">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="POUs\Sunspec\ST_SUNSPEC_CURRENT_VALUES.TcDUT">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="POUs\Sunspec\U_SUNSPEC_ERROR.TcDUT">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="DUTs" />
|
||||
<Folder Include="DUTs\Modbus" />
|
||||
<Folder Include="DUTs\Modbus\HoldingRegisters" />
|
||||
<Folder Include="GVLs" />
|
||||
<Folder Include="POUs\Sunspec" />
|
||||
<Folder Include="VISUs" />
|
||||
@@ -100,8 +118,16 @@
|
||||
<DefaultResolution>Tc2_System, * (Beckhoff Automation GmbH)</DefaultResolution>
|
||||
<Namespace>Tc2_System</Namespace>
|
||||
</PlaceholderReference>
|
||||
<PlaceholderReference Include="Tc2_Utilities">
|
||||
<DefaultResolution>Tc2_Utilities, * (Beckhoff Automation GmbH)</DefaultResolution>
|
||||
</PlaceholderReference>
|
||||
<PlaceholderReference Include="Tc3_EventLogger">
|
||||
<DefaultResolution>Tc3_EventLogger, * (Beckhoff Automation GmbH)</DefaultResolution>
|
||||
<Namespace>Tc3_EventLogger</Namespace>
|
||||
</PlaceholderReference>
|
||||
<PlaceholderReference Include="Tc3_IotBase">
|
||||
<DefaultResolution>Tc3_IotBase, * (Beckhoff Automation GmbH)</DefaultResolution>
|
||||
<Namespace>Tc3_IotBase</Namespace>
|
||||
</PlaceholderReference>
|
||||
<PlaceholderReference Include="Tc3_Module">
|
||||
<DefaultResolution>Tc3_Module, * (Beckhoff Automation GmbH)</DefaultResolution>
|
||||
|
||||
344
PLC/PLC.tmc
344
PLC/PLC.tmc
File diff suppressed because one or more lines are too long
@@ -12,6 +12,9 @@ VAR_INPUT
|
||||
// Module completely off
|
||||
xOff : BOOL := TRUE;
|
||||
|
||||
// All safetyinterlocks are ok
|
||||
xSafetyIntlksOk : BOOL;
|
||||
|
||||
// HMI Interface
|
||||
stHMIInterface : REFERENCE TO ST_MODULE_HMI_INTERFACE;
|
||||
|
||||
@@ -44,10 +47,10 @@ VAR_OUTPUT
|
||||
xWarning : BOOL;
|
||||
END_VAR
|
||||
VAR
|
||||
_fbUnit1 : FB_Unit(CONCAT(_sName, ' Unit 1'));
|
||||
_fbUnit2 : FB_Unit(CONCAT(_sName, ' Unit 2'));
|
||||
_fbUnit3 : FB_Unit(CONCAT(_sName, ' Unit 3'));
|
||||
_fbUnit4 : FB_Unit(CONCAT(_sName, ' Unit 4'));
|
||||
_fbUnit1 : FB_Unit('Unit 1');
|
||||
_fbUnit2 : FB_Unit('Unit 2');
|
||||
_fbUnit3 : FB_Unit('Unit 3');
|
||||
_fbUnit4 : FB_Unit('Unit 4');
|
||||
|
||||
// Flag for unit balance checking
|
||||
_xBalanceOk : BOOL;
|
||||
@@ -55,6 +58,9 @@ VAR
|
||||
// All units are ready
|
||||
_xAllUnitsReady : BOOL;
|
||||
|
||||
// Units out of balance alarm
|
||||
_fbUnitsOutOfBalanceAlarm : FB_TcAlarm;
|
||||
|
||||
// Module name
|
||||
_sName : STRING;
|
||||
END_VAR
|
||||
@@ -64,6 +70,10 @@ END_VAR
|
||||
xError := FALSE;
|
||||
xWarning := FALSE;
|
||||
|
||||
// Reset safety interlocks flag
|
||||
xSafetyIntlksOk := TRUE;
|
||||
|
||||
|
||||
// ===============================
|
||||
// Unit 1
|
||||
// ===============================
|
||||
@@ -87,6 +97,10 @@ IF _fbUnit1.xError THEN
|
||||
xError := TRUE;
|
||||
END_IF
|
||||
|
||||
IF NOT _fbUnit1.xSafetyIntlksOk THEN
|
||||
xSafetyIntlksOk := FALSE;
|
||||
END_IF
|
||||
|
||||
|
||||
// ===============================
|
||||
// Unit 2
|
||||
@@ -111,6 +125,10 @@ IF _fbUnit2.xError THEN
|
||||
xError := TRUE;
|
||||
END_IF
|
||||
|
||||
IF NOT _fbUnit2.xSafetyIntlksOk THEN
|
||||
xSafetyIntlksOk := FALSE;
|
||||
END_IF
|
||||
|
||||
|
||||
// ===============================
|
||||
// Unit 3
|
||||
@@ -135,6 +153,10 @@ IF _fbUnit3.xError THEN
|
||||
xError := TRUE;
|
||||
END_IF
|
||||
|
||||
IF NOT _fbUnit3.xSafetyIntlksOk THEN
|
||||
xSafetyIntlksOk := FALSE;
|
||||
END_IF
|
||||
|
||||
|
||||
// ===============================
|
||||
// Unit 4
|
||||
@@ -159,6 +181,10 @@ IF _fbUnit4.xError THEN
|
||||
xError := TRUE;
|
||||
END_IF
|
||||
|
||||
IF NOT _fbUnit4.xSafetyIntlksOk THEN
|
||||
xSafetyIntlksOk := FALSE;
|
||||
END_IF
|
||||
|
||||
|
||||
// ===============================
|
||||
// Units ready check
|
||||
@@ -230,6 +256,21 @@ IF _xAllUnitsReady AND (NOT _xBalanceOk) THEN
|
||||
xError := TRUE;
|
||||
END_IF
|
||||
|
||||
// Raise error
|
||||
IF (NOT _xBalanceOk) AND (NOT _fbUnitsOutOfBalanceAlarm.bRaised) THEN
|
||||
_fbUnitsOutOfBalanceAlarm.Raise(0);
|
||||
END_IF
|
||||
|
||||
// Clear error
|
||||
IF _xBalanceOk AND _fbUnitsOutOfBalanceAlarm.bRaised THEN
|
||||
_fbUnitsOutOfBalanceAlarm.Clear(0, FALSE);
|
||||
END_IF
|
||||
|
||||
// Confirm error
|
||||
IF _fbUnitsOutOfBalanceAlarm.eConfirmationState = TcEventConfirmationState.WaitForConfirmation AND xConfirmAlarms THEN
|
||||
_fbUnitsOutOfBalanceAlarm.Confirm(0);
|
||||
END_IF
|
||||
|
||||
// ===============================
|
||||
// Module ready validation check
|
||||
// ===============================
|
||||
@@ -249,21 +290,79 @@ VAR_INPUT
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[_sName := sName;]]></ST>
|
||||
<ST><![CDATA[_sName := sName;
|
||||
|
||||
// Set unit names
|
||||
_fbUnit1.Name := CONCAT(_sName, 'Unit 1');
|
||||
_fbUnit2.Name := CONCAT(_sName, 'Unit 2');
|
||||
_fbUnit3.Name := CONCAT(_sName, 'Unit 3');
|
||||
_fbUnit4.Name := CONCAT(_sName, 'Unit 4');
|
||||
|
||||
// Create out of balance alarm
|
||||
_fbUnitsOutOfBalanceAlarm.CreateEx(stEventEntry := TC_EVENTS.BMSEvents.ModuleImbalance, bWithConfirmation := TRUE, 0);
|
||||
|
||||
// Create alarm message
|
||||
_fbUnitsOutOfBalanceAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Property Name="Name" Id="{bc8bc990-5071-47c9-a928-a129c60c6f41}">
|
||||
<Declaration><![CDATA[PROPERTY Name : String]]></Declaration>
|
||||
<Get Name="Get" Id="{c00a6d41-9156-49b5-aa08-e4cc4c913fca}">
|
||||
<Declaration><![CDATA[VAR
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[Name := _sName;]]></ST>
|
||||
</Implementation>
|
||||
</Get>
|
||||
<Set Name="Set" Id="{ade5f4d9-ff42-4236-b5fc-e43a53c9ca28}">
|
||||
<Declaration><![CDATA[VAR
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[_sName := Name;
|
||||
|
||||
// Set unit names
|
||||
_fbUnit1.Name := CONCAT(_sName, ' - Unit 1');
|
||||
_fbUnit2.Name := CONCAT(_sName, ' - Unit 2');
|
||||
_fbUnit3.Name := CONCAT(_sName, ' - Unit 3');
|
||||
_fbUnit4.Name := CONCAT(_sName, ' - Unit 4');
|
||||
|
||||
// Create alarm message
|
||||
_fbUnitsOutOfBalanceAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||
</Implementation>
|
||||
</Set>
|
||||
</Property>
|
||||
<LineIds Name="FB_Module">
|
||||
<LineId Id="248" Count="7" />
|
||||
<LineId Id="248" Count="2" />
|
||||
<LineId Id="557" Count="1" />
|
||||
<LineId Id="556" Count="0" />
|
||||
<LineId Id="575" Count="0" />
|
||||
<LineId Id="251" Count="4" />
|
||||
<LineId Id="456" Count="0" />
|
||||
<LineId Id="256" Count="22" />
|
||||
<LineId Id="256" Count="16" />
|
||||
<LineId Id="560" Count="0" />
|
||||
<LineId Id="559" Count="0" />
|
||||
<LineId Id="561" Count="1" />
|
||||
<LineId Id="273" Count="5" />
|
||||
<LineId Id="457" Count="0" />
|
||||
<LineId Id="279" Count="22" />
|
||||
<LineId Id="279" Count="16" />
|
||||
<LineId Id="563" Count="2" />
|
||||
<LineId Id="296" Count="0" />
|
||||
<LineId Id="574" Count="0" />
|
||||
<LineId Id="297" Count="4" />
|
||||
<LineId Id="458" Count="0" />
|
||||
<LineId Id="302" Count="22" />
|
||||
<LineId Id="302" Count="16" />
|
||||
<LineId Id="566" Count="2" />
|
||||
<LineId Id="319" Count="0" />
|
||||
<LineId Id="573" Count="0" />
|
||||
<LineId Id="320" Count="4" />
|
||||
<LineId Id="459" Count="0" />
|
||||
<LineId Id="325" Count="15" />
|
||||
<LineId Id="188" Count="0" />
|
||||
<LineId Id="569" Count="2" />
|
||||
<LineId Id="441" Count="0" />
|
||||
<LineId Id="572" Count="0" />
|
||||
<LineId Id="436" Count="0" />
|
||||
<LineId Id="438" Count="1" />
|
||||
<LineId Id="437" Count="0" />
|
||||
@@ -317,6 +416,17 @@ END_VAR
|
||||
<LineId Id="422" Count="0" />
|
||||
<LineId Id="377" Count="0" />
|
||||
<LineId Id="449" Count="1" />
|
||||
<LineId Id="580" Count="0" />
|
||||
<LineId Id="579" Count="0" />
|
||||
<LineId Id="581" Count="0" />
|
||||
<LineId Id="584" Count="0" />
|
||||
<LineId Id="583" Count="0" />
|
||||
<LineId Id="586" Count="0" />
|
||||
<LineId Id="585" Count="0" />
|
||||
<LineId Id="587" Count="2" />
|
||||
<LineId Id="592" Count="0" />
|
||||
<LineId Id="591" Count="0" />
|
||||
<LineId Id="593" Count="2" />
|
||||
<LineId Id="452" Count="0" />
|
||||
<LineId Id="460" Count="1" />
|
||||
<LineId Id="451" Count="0" />
|
||||
@@ -327,6 +437,27 @@ END_VAR
|
||||
</LineIds>
|
||||
<LineIds Name="FB_Module.FB_init">
|
||||
<LineId Id="7" Count="0" />
|
||||
<LineId Id="29" Count="0" />
|
||||
<LineId Id="28" Count="0" />
|
||||
<LineId Id="31" Count="2" />
|
||||
<LineId Id="30" Count="0" />
|
||||
<LineId Id="16" Count="0" />
|
||||
<LineId Id="15" Count="0" />
|
||||
<LineId Id="17" Count="0" />
|
||||
<LineId Id="19" Count="0" />
|
||||
<LineId Id="18" Count="0" />
|
||||
<LineId Id="20" Count="0" />
|
||||
</LineIds>
|
||||
<LineIds Name="FB_Module.Name.Get">
|
||||
<LineId Id="2" Count="0" />
|
||||
</LineIds>
|
||||
<LineIds Name="FB_Module.Name.Set">
|
||||
<LineId Id="2" Count="0" />
|
||||
<LineId Id="8" Count="0" />
|
||||
<LineId Id="12" Count="3" />
|
||||
<LineId Id="11" Count="0" />
|
||||
<LineId Id="6" Count="1" />
|
||||
<LineId Id="5" Count="0" />
|
||||
</LineIds>
|
||||
</POU>
|
||||
</TcPlcObject>
|
||||
@@ -37,13 +37,16 @@ VAR_OUTPUT
|
||||
// String completely off
|
||||
xOff : BOOL;
|
||||
|
||||
// All safetyinterlocks are ok
|
||||
xSafetyIntlksOk : BOOL;
|
||||
|
||||
xError : BOOL;
|
||||
xWarning : BOOL;
|
||||
END_VAR
|
||||
VAR
|
||||
_fbModule1 : FB_Module(CONCAT(_sName, 'Module 1'));
|
||||
_fbModule2 : FB_Module(CONCAT(_sName, 'Module 2'));
|
||||
_fbModule3 : FB_Module(CONCAT(_sName, 'Module 3'));
|
||||
_fbModule1 : FB_Module('Module 1');
|
||||
_fbModule2 : FB_Module('Module 2');
|
||||
_fbModule3 : FB_Module('Module 3');
|
||||
|
||||
// All modules are ready
|
||||
_xAllModulesReady : BOOL;
|
||||
@@ -54,6 +57,12 @@ VAR
|
||||
// Flag for module balance checking
|
||||
_xBalanceOk : BOOL;
|
||||
|
||||
// Modules out of balance alarm message
|
||||
_fbModulesOutOfBalanceAlarm : Fb_TcAlarm;
|
||||
|
||||
// Safetyinterlocks pending alarm
|
||||
_fbSafetyInterlocksNotOkAlarm : FB_TcAlarm;
|
||||
|
||||
// String name
|
||||
_sName : STRING;
|
||||
END_VAR
|
||||
@@ -62,6 +71,9 @@ END_VAR
|
||||
<ST><![CDATA[// Reset error flag
|
||||
xError := FALSE;
|
||||
|
||||
// Reset safety interlocks flag
|
||||
xSafetyIntlksOk := TRUE;
|
||||
|
||||
// ===============================
|
||||
// Module 1
|
||||
// ===============================
|
||||
@@ -81,6 +93,10 @@ IF _fbModule1.xError THEN
|
||||
xError := TRUE;
|
||||
END_IF
|
||||
|
||||
IF NOT _fbModule1.xSafetyIntlksOk THEN
|
||||
xSafetyIntlksOk := FALSE;
|
||||
END_IF
|
||||
|
||||
|
||||
// ===============================
|
||||
// Module 2
|
||||
@@ -101,6 +117,10 @@ IF _fbModule2.xError THEN
|
||||
xError := TRUE;
|
||||
END_IF
|
||||
|
||||
IF NOT _fbModule2.xSafetyIntlksOk THEN
|
||||
xSafetyIntlksOk := FALSE;
|
||||
END_IF
|
||||
|
||||
|
||||
// ===============================
|
||||
// Module 3
|
||||
@@ -121,6 +141,22 @@ IF _fbModule3.xError THEN
|
||||
xError := TRUE;
|
||||
END_IF
|
||||
|
||||
IF NOT _fbModule3.xSafetyIntlksOk THEN
|
||||
xSafetyIntlksOk := FALSE;
|
||||
END_IF
|
||||
|
||||
|
||||
// ===============================
|
||||
// Handle safety interlock alarm
|
||||
// ===============================
|
||||
IF NOT xSafetyIntlksOk AND NOT _fbSafetyInterlocksNotOkAlarm.bRaised THEN
|
||||
_fbSafetyInterlocksNotOkAlarm.Raise(0);
|
||||
END_IF
|
||||
|
||||
IF xSafetyIntlksOk AND _fbSafetyInterlocksNotOkAlarm.bRaised THEN
|
||||
_fbSafetyInterlocksNotOkAlarm.Clear(0, TRUE);
|
||||
END_IF
|
||||
|
||||
|
||||
// ===============================
|
||||
// Modules ready check
|
||||
@@ -179,6 +215,21 @@ IF _xAllModulesReady AND (NOT _xBalanceOk) THEN
|
||||
xError := TRUE;
|
||||
END_IF
|
||||
|
||||
// Raise error
|
||||
IF (NOT _xBalanceOk) AND (NOT _fbModulesOutOfBalanceAlarm.bRaised) THEN
|
||||
_fbModulesOutOfBalanceAlarm.Raise(0);
|
||||
END_IF
|
||||
|
||||
// Clear error
|
||||
IF _xBalanceOk AND _fbModulesOutOfBalanceAlarm.bRaised THEN
|
||||
_fbModulesOutOfBalanceAlarm.Clear(0, FALSE);
|
||||
END_IF
|
||||
|
||||
// Confirm error
|
||||
IF _fbModulesOutOfBalanceAlarm.eConfirmationState = TcEventConfirmationState.WaitForConfirmation AND xConfirmAlarms THEN
|
||||
_fbModulesOutOfBalanceAlarm.Confirm(0);
|
||||
END_IF
|
||||
|
||||
// ===============================
|
||||
// String ready validation check
|
||||
// ===============================
|
||||
@@ -198,12 +249,56 @@ VAR_INPUT
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[_sName := sName;]]></ST>
|
||||
<ST><![CDATA[_sName := sName;
|
||||
|
||||
// Set names for modules
|
||||
_fbModule1.Name := Concat(_sName, ' - Module 1');
|
||||
_fbModule2.Name := Concat(_sName, ' - Module 2');
|
||||
_fbModule3.Name := Concat(_sName, ' - Module 3');
|
||||
|
||||
// Create out of balance alarm
|
||||
_fbModulesOutOfBalanceAlarm.CreateEx(stEventEntry := TC_EVENTS.BMSEvents.StringImbalance, bWithConfirmation := TRUE, 0);
|
||||
_fbModulesOutOfBalanceAlarm.ipArguments.Clear().AddString(_sName);
|
||||
|
||||
// Create safetyinterlocks active alarm
|
||||
_fbSafetyInterlocksNotOkAlarm.CreateEx(stEventEntry := TC_EVENTS.BMSEvents.SafetyIntlksActive, bWithConfirmation := FALSE, 0);
|
||||
_fbSafetyInterlocksNotOkAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Property Name="Name" Id="{19fcb6d4-fd4b-49f9-9791-1e4c931b9e69}">
|
||||
<Declaration><![CDATA[PROPERTY Name : String]]></Declaration>
|
||||
<Get Name="Get" Id="{a4b6ba34-8ad9-46b1-939c-45cef957fd9a}">
|
||||
<Declaration><![CDATA[VAR
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[Name := _sName;]]></ST>
|
||||
</Implementation>
|
||||
</Get>
|
||||
<Set Name="Set" Id="{c32997c5-bac4-4ef0-bc87-edcbbb2e542f}">
|
||||
<Declaration><![CDATA[VAR
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[_sName := Name;
|
||||
|
||||
// Set modules names
|
||||
_fbModule1.Name := CONCAT(_sName, ' - Module 1');
|
||||
_fbModule2.Name := CONCAT(_sName, ' - Module 2');
|
||||
_fbModule3.Name := CONCAT(_sName, ' - Module 3');
|
||||
|
||||
// Create alarm messages
|
||||
_fbModulesOutOfBalanceAlarm.ipArguments.Clear().AddString(_sName);
|
||||
_fbSafetyInterlocksNotOkAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||
</Implementation>
|
||||
</Set>
|
||||
</Property>
|
||||
<LineIds Name="FB_String">
|
||||
<LineId Id="266" Count="0" />
|
||||
<LineId Id="268" Count="0" />
|
||||
<LineId Id="335" Count="0" />
|
||||
<LineId Id="334" Count="0" />
|
||||
<LineId Id="336" Count="0" />
|
||||
<LineId Id="267" Count="0" />
|
||||
<LineId Id="69" Count="0" />
|
||||
<LineId Id="67" Count="1" />
|
||||
@@ -217,14 +312,26 @@ END_VAR
|
||||
<LineId Id="66" Count="0" />
|
||||
<LineId Id="63" Count="0" />
|
||||
<LineId Id="59" Count="2" />
|
||||
<LineId Id="338" Count="0" />
|
||||
<LineId Id="337" Count="0" />
|
||||
<LineId Id="339" Count="1" />
|
||||
<LineId Id="71" Count="5" />
|
||||
<LineId Id="141" Count="0" />
|
||||
<LineId Id="77" Count="11" />
|
||||
<LineId Id="70" Count="0" />
|
||||
<LineId Id="342" Count="2" />
|
||||
<LineId Id="341" Count="0" />
|
||||
<LineId Id="90" Count="5" />
|
||||
<LineId Id="142" Count="0" />
|
||||
<LineId Id="96" Count="11" />
|
||||
<LineId Id="89" Count="0" />
|
||||
<LineId Id="346" Count="2" />
|
||||
<LineId Id="345" Count="0" />
|
||||
<LineId Id="433" Count="1" />
|
||||
<LineId Id="432" Count="0" />
|
||||
<LineId Id="435" Count="4" />
|
||||
<LineId Id="441" Count="2" />
|
||||
<LineId Id="440" Count="0" />
|
||||
<LineId Id="183" Count="5" />
|
||||
<LineId Id="245" Count="4" />
|
||||
<LineId Id="244" Count="0" />
|
||||
@@ -249,12 +356,38 @@ END_VAR
|
||||
<LineId Id="212" Count="0" />
|
||||
<LineId Id="237" Count="1" />
|
||||
<LineId Id="236" Count="0" />
|
||||
<LineId Id="215" Count="11" />
|
||||
<LineId Id="215" Count="5" />
|
||||
<LineId Id="353" Count="13" />
|
||||
<LineId Id="352" Count="0" />
|
||||
<LineId Id="221" Count="5" />
|
||||
<LineId Id="239" Count="1" />
|
||||
<LineId Id="214" Count="0" />
|
||||
</LineIds>
|
||||
<LineIds Name="FB_String.FB_init">
|
||||
<LineId Id="7" Count="0" />
|
||||
<LineId Id="33" Count="0" />
|
||||
<LineId Id="32" Count="0" />
|
||||
<LineId Id="34" Count="2" />
|
||||
<LineId Id="16" Count="0" />
|
||||
<LineId Id="15" Count="0" />
|
||||
<LineId Id="17" Count="0" />
|
||||
<LineId Id="20" Count="0" />
|
||||
<LineId Id="31" Count="0" />
|
||||
<LineId Id="29" Count="1" />
|
||||
<LineId Id="28" Count="0" />
|
||||
</LineIds>
|
||||
<LineIds Name="FB_String.Name.Get">
|
||||
<LineId Id="2" Count="0" />
|
||||
</LineIds>
|
||||
<LineIds Name="FB_String.Name.Set">
|
||||
<LineId Id="2" Count="0" />
|
||||
<LineId Id="9" Count="0" />
|
||||
<LineId Id="6" Count="2" />
|
||||
<LineId Id="5" Count="0" />
|
||||
<LineId Id="13" Count="0" />
|
||||
<LineId Id="11" Count="0" />
|
||||
<LineId Id="10" Count="0" />
|
||||
<LineId Id="12" Count="0" />
|
||||
</LineIds>
|
||||
</POU>
|
||||
</TcPlcObject>
|
||||
@@ -37,6 +37,9 @@ VAR_OUTPUT
|
||||
// Unit completely off
|
||||
xOff : BOOL := TRUE;
|
||||
|
||||
// All safetyinterlocks are ok
|
||||
xSafetyIntlksOk : BOOL;
|
||||
|
||||
// Unit can be discharged during shutdown sequence
|
||||
xShutdownDischargeAllowed : BOOL;
|
||||
|
||||
@@ -57,7 +60,7 @@ VAR_OUTPUT
|
||||
END_VAR
|
||||
VAR
|
||||
// Check unit condition after some time during startup
|
||||
_timUnitStartupWaitTime : TIME := T#20S;
|
||||
// _timUnitStartupWaitTime : TIME := T#10S;
|
||||
|
||||
// Valves posolyt
|
||||
_fbPosolytValveTankOutlet : FB_Valve('Posolyt tank outlet');
|
||||
@@ -152,6 +155,9 @@ _xErrorActive := FALSE;
|
||||
// Reset warning active
|
||||
_xWarningActive := FALSE;
|
||||
|
||||
// Reset safety interlocks flag
|
||||
xSafetyIntlksOk := TRUE;
|
||||
|
||||
// ===============================
|
||||
// Valve posolyt tank outlet
|
||||
// ===============================
|
||||
@@ -177,6 +183,11 @@ IF _fbPosolytValveTankOutlet.xError THEN
|
||||
_xErrorActive := TRUE;
|
||||
END_IF
|
||||
|
||||
// Set safety interlock flag if fb has safety interlocks active
|
||||
IF NOT stHMIInterface.stPosolytValve.stInterlock.xSafetyINTLKOk THEN
|
||||
xSafetyIntlksOk := FALSE;
|
||||
END_IF
|
||||
|
||||
|
||||
// ===============================
|
||||
// Valve negolyt tank outlet
|
||||
@@ -203,6 +214,11 @@ IF _fbNegolytValveTankOutlet.xError THEN
|
||||
_xErrorActive := TRUE;
|
||||
END_IF
|
||||
|
||||
// Set safety interlock flag if fb has safety interlocks active
|
||||
IF NOT stHMIInterface.stNegolytValve.stInterlock.xSafetyINTLKOk THEN
|
||||
xSafetyIntlksOk := FALSE;
|
||||
END_IF
|
||||
|
||||
|
||||
// ===============================
|
||||
// Pump posolyt segment inlet
|
||||
@@ -242,6 +258,11 @@ IF _fbPosolytPumpInlet.xWarning THEN
|
||||
_xWarningActive := TRUE;
|
||||
END_IF
|
||||
|
||||
// Set safety interlock flag if fb has safety interlocks active
|
||||
IF NOT stHMIInterface.stPosolytPump.stInterlock.xSafetyINTLKOk THEN
|
||||
xSafetyIntlksOk := FALSE;
|
||||
END_IF
|
||||
|
||||
|
||||
// ===============================
|
||||
// Pump negolyt segment inlet
|
||||
@@ -281,6 +302,11 @@ IF _fbNegolytPumpInlet.xWarning THEN
|
||||
_xWarningActive := TRUE;
|
||||
END_IF
|
||||
|
||||
// Set safety interlock flag if fb has safety interlocks active
|
||||
IF NOT stHMIInterface.stNegolytPump.stInterlock.xSafetyINTLKOk THEN
|
||||
xSafetyIntlksOk := FALSE;
|
||||
END_IF
|
||||
|
||||
|
||||
// ===============================
|
||||
// Pressure sensor posolyt segment inlet
|
||||
@@ -510,7 +536,7 @@ CASE _iState OF
|
||||
END_IF
|
||||
|
||||
30: // Wait some time
|
||||
_tonStartupCheck(In := TRUE, PT := _timUnitStartupWaitTime);
|
||||
_tonStartupCheck(In := TRUE, PT := GVL_CONFIG.timUnitStartupTime);
|
||||
|
||||
// After some time, check if all values are ok
|
||||
IF _tonStartupCheck.Q THEN
|
||||
@@ -534,7 +560,6 @@ CASE _iState OF
|
||||
|
||||
35: // Unit in enabled state
|
||||
IF (NOT xEnable) AND NOT _xErrorActive THEN
|
||||
_xEnableVoltageLimitChecks := FALSE;
|
||||
_iState := 40;
|
||||
END_IF
|
||||
|
||||
@@ -557,6 +582,7 @@ CASE _iState OF
|
||||
// When there is an error trying to close the valves,
|
||||
// dont try to discharge the segment
|
||||
IF _fbNegolytValveTankOutlet.xError OR _fbPosolytValveTankOutlet.xError THEN
|
||||
_xEnableVoltageLimitChecks := FALSE;
|
||||
_iState := 60;
|
||||
END_IF
|
||||
|
||||
@@ -570,6 +596,7 @@ CASE _iState OF
|
||||
xShutdownDischargeAllowed := TRUE;
|
||||
ELSE
|
||||
xShutdownDischargeAllowed := FALSE;
|
||||
_xEnableVoltageLimitChecks := FALSE;
|
||||
END_IF
|
||||
|
||||
IF (_fbVoltageSegment.rScaledValue <= GVL_CONFIG.rPumpshutoffThreshold) THEN
|
||||
@@ -648,14 +675,53 @@ END_VAR
|
||||
<Implementation>
|
||||
<ST><![CDATA[_sName := sName;
|
||||
|
||||
// Create not all components in automatic mode alarm
|
||||
_fbNotAllAutomaticAlarm.CreateEx(TC_EVENTS.General.NotAllCompInAutomatic, bWithConfirmation := FALSE, 0);
|
||||
_fbNotAllAutomaticAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Property Name="Name" Id="{a82783d4-f1f5-481b-bbb0-7ea8279de793}">
|
||||
<Declaration><![CDATA[PROPERTY Name : String]]></Declaration>
|
||||
<Get Name="Get" Id="{62ca6bce-5aa4-40f1-aa68-f3e5d22ad4a4}">
|
||||
<Declaration><![CDATA[VAR
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[Name := _sName;]]></ST>
|
||||
</Implementation>
|
||||
</Get>
|
||||
<Set Name="Set" Id="{b2e0f6da-5412-45b8-aacd-c140a5beab95}">
|
||||
<Declaration><![CDATA[VAR
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[_sName := Name;
|
||||
|
||||
// Create alarm message
|
||||
_fbNotAllAutomaticAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||
</Implementation>
|
||||
</Set>
|
||||
</Property>
|
||||
<LineIds Name="FB_Unit">
|
||||
<LineId Id="4232" Count="29" />
|
||||
<LineId Id="4232" Count="4" />
|
||||
<LineId Id="5406" Count="1" />
|
||||
<LineId Id="5405" Count="0" />
|
||||
<LineId Id="4237" Count="24" />
|
||||
<LineId Id="5408" Count="0" />
|
||||
<LineId Id="4584" Count="0" />
|
||||
<LineId Id="4263" Count="102" />
|
||||
<LineId Id="5409" Count="2" />
|
||||
<LineId Id="5418" Count="0" />
|
||||
<LineId Id="4263" Count="25" />
|
||||
<LineId Id="5412" Count="2" />
|
||||
<LineId Id="4289" Count="0" />
|
||||
<LineId Id="5416" Count="0" />
|
||||
<LineId Id="5415" Count="0" />
|
||||
<LineId Id="4290" Count="36" />
|
||||
<LineId Id="5420" Count="3" />
|
||||
<LineId Id="5419" Count="0" />
|
||||
<LineId Id="4327" Count="38" />
|
||||
<LineId Id="5425" Count="3" />
|
||||
<LineId Id="5424" Count="0" />
|
||||
<LineId Id="4619" Count="0" />
|
||||
<LineId Id="4367" Count="46" />
|
||||
<LineId Id="5099" Count="0" />
|
||||
@@ -708,7 +774,6 @@ _fbNotAllAutomaticAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||
<LineId Id="4496" Count="0" />
|
||||
<LineId Id="4794" Count="0" />
|
||||
<LineId Id="4497" Count="12" />
|
||||
<LineId Id="4795" Count="0" />
|
||||
<LineId Id="4511" Count="1" />
|
||||
<LineId Id="5078" Count="0" />
|
||||
<LineId Id="5083" Count="0" />
|
||||
@@ -717,7 +782,9 @@ _fbNotAllAutomaticAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||
<LineId Id="5081" Count="0" />
|
||||
<LineId Id="4513" Count="7" />
|
||||
<LineId Id="5239" Count="0" />
|
||||
<LineId Id="4521" Count="7" />
|
||||
<LineId Id="4521" Count="5" />
|
||||
<LineId Id="5441" Count="0" />
|
||||
<LineId Id="4527" Count="1" />
|
||||
<LineId Id="4653" Count="0" />
|
||||
<LineId Id="4655" Count="2" />
|
||||
<LineId Id="4654" Count="0" />
|
||||
@@ -725,6 +792,7 @@ _fbNotAllAutomaticAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||
<LineId Id="5220" Count="0" />
|
||||
<LineId Id="5223" Count="0" />
|
||||
<LineId Id="5225" Count="1" />
|
||||
<LineId Id="5440" Count="0" />
|
||||
<LineId Id="5224" Count="0" />
|
||||
<LineId Id="5221" Count="0" />
|
||||
<LineId Id="4531" Count="0" />
|
||||
@@ -751,7 +819,7 @@ _fbNotAllAutomaticAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||
<LineId Id="5084" Count="0" />
|
||||
<LineId Id="5086" Count="1" />
|
||||
<LineId Id="5089" Count="1" />
|
||||
<LineId Id="5093" Count="0" />
|
||||
<LineId Id="5434" Count="0" />
|
||||
<LineId Id="5227" Count="0" />
|
||||
<LineId Id="5240" Count="0" />
|
||||
<LineId Id="5092" Count="0" />
|
||||
@@ -763,8 +831,19 @@ _fbNotAllAutomaticAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||
<LineId Id="2754" Count="0" />
|
||||
</LineIds>
|
||||
<LineIds Name="FB_Unit.FB_init">
|
||||
<LineId Id="11" Count="1" />
|
||||
<LineId Id="11" Count="0" />
|
||||
<LineId Id="20" Count="0" />
|
||||
<LineId Id="12" Count="0" />
|
||||
<LineId Id="7" Count="1" />
|
||||
</LineIds>
|
||||
<LineIds Name="FB_Unit.Name.Get">
|
||||
<LineId Id="2" Count="0" />
|
||||
</LineIds>
|
||||
<LineIds Name="FB_Unit.Name.Set">
|
||||
<LineId Id="2" Count="0" />
|
||||
<LineId Id="7" Count="0" />
|
||||
<LineId Id="6" Count="0" />
|
||||
<LineId Id="5" Count="0" />
|
||||
</LineIds>
|
||||
</POU>
|
||||
</TcPlcObject>
|
||||
@@ -11,6 +11,15 @@ VAR
|
||||
_xEnableInverter : BOOL;
|
||||
_fbString : FB_String('String 1');
|
||||
_fbInverter : FB_PowerSupplySunspec;
|
||||
_stInverterData : ST_SUNSPEC_CURRENT_VALUES;
|
||||
|
||||
// Variable to detect charge status change
|
||||
_eLastChargeStatus : E_CHARGE_STATUS;
|
||||
// Variable to detect battery status change
|
||||
_eLastBatteryStatus : E_BATTERY_STATUS;
|
||||
|
||||
// Variable to detect any battery status change
|
||||
_xBatteryStatusChange : BOOL;
|
||||
|
||||
_iState : INT;
|
||||
|
||||
@@ -25,10 +34,52 @@ VAR
|
||||
|
||||
// Small delay for inverter shutdown
|
||||
_tonBeginShutdown : TON := (PT := T#10S);
|
||||
|
||||
// Not all strings in automatic mode
|
||||
_fbNoAutomaticModeAlarm : Fb_TcAlarm;
|
||||
|
||||
// First cycle tag
|
||||
_xFirstCycle : BOOL := TRUE;
|
||||
|
||||
// ADS reader for modbus server data
|
||||
_fbADSReader : ADSREAD;
|
||||
|
||||
// Timer for ADS read
|
||||
_timADSReadTimer : TON;
|
||||
|
||||
// MQTT client
|
||||
_fbMQTTClient : FB_IotMqttClient;
|
||||
|
||||
// connect to mqtt broker
|
||||
_xConnectToMQTTBrocker : BOOL;
|
||||
|
||||
// DEBUG
|
||||
_xRestart : BOOL;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[// Dely release of errors during PLC startup phase
|
||||
<ST><![CDATA[// ===============================
|
||||
// DEBUG
|
||||
IF _xRestart AND (_iState = 1010) THEN
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg12.diSetpointActivePower := 0;
|
||||
_xConfirmAlarms := TRUE;
|
||||
END_IF
|
||||
|
||||
IF _xRestart AND (_iState = 0) THEN
|
||||
_xRestart := FALSE;
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg12.diSetpointActivePower := 1000;
|
||||
END_IF
|
||||
|
||||
// DEBUG
|
||||
// ===============================
|
||||
|
||||
IF _xFirstCycle THEN
|
||||
_xFirstCycle := FALSE;
|
||||
_fbString.Name := 'String 1';
|
||||
_xConnectToMQTTBrocker := TRUE;
|
||||
END_IF
|
||||
|
||||
// Dely release of errors during PLC startup phase
|
||||
_tonStartupDelay(IN := TRUE);
|
||||
|
||||
// Call string 1
|
||||
@@ -40,7 +91,7 @@ _fbString(
|
||||
xReleaseLimitErrors:= _xReleaseLimitsErrors AND _tonStartupDelay.Q,
|
||||
xConfirmAlarms:= _xConfirmAlarms);
|
||||
|
||||
|
||||
// DEACTIVATED FOR DEBUG REASONS !!!
|
||||
// Call inverter
|
||||
//_fbInverter(
|
||||
// sInverterIPAddr:= GVL_CONFIG.sInverterIp,
|
||||
@@ -48,12 +99,32 @@ _fbString(
|
||||
// rPower:= _rPowerInverter,
|
||||
// xReset:= _xConfirmAlarms,
|
||||
// rMaxBattPower:= DINT_TO_REAL(GVL_CONFIG.diMaxStringDischargePower),
|
||||
// xCloseDCRelais=> ,
|
||||
// rActDCCurrent=> ,
|
||||
// rActDCVoltage=> ,
|
||||
// xError=> ,
|
||||
// xActive=> );
|
||||
|
||||
// stCurrentValues => _stInverterData);
|
||||
|
||||
|
||||
// ===============================
|
||||
// Read modbus request count
|
||||
// ===============================
|
||||
_timADSReadTimer(IN := NOT _fbADSReader.BUSY, PT := T#200MS);
|
||||
_fbADSReader(
|
||||
NETID:= '',
|
||||
PORT:= 10500,
|
||||
IDXGRP:= 16#2000,
|
||||
IDXOFFS:= 1,
|
||||
LEN:= 4,
|
||||
DESTADDR:= ADR(GVL_MODBUS.stModbusEMSComm.stModbusReg11.udiLifeMessage),
|
||||
READ:= _timADSReadTimer.Q,
|
||||
TMOUT:= T#1S,
|
||||
BUSY=> ,
|
||||
ERR=> ,
|
||||
ERRID=> );
|
||||
|
||||
// ===============================
|
||||
// MQTT cummunication
|
||||
// ===============================
|
||||
// Handle connection to broker
|
||||
_fbMQTTClient.Execute(_xConnectToMQTTBrocker);
|
||||
|
||||
|
||||
// ===============================
|
||||
// State machine
|
||||
@@ -61,18 +132,18 @@ _fbString(
|
||||
CASE _iState OF
|
||||
0: // Idle
|
||||
// Wait for power command
|
||||
IF ABS(GVL_MODBUS.stModbusEMSComm.diSetpointActivePower) > GVL_CONFIG.diMinimumAbsPowerForEnable THEN
|
||||
IF (ABS(GVL_MODBUS.stModbusEMSComm.stModbusReg12.diSetpointActivePower) > GVL_CONFIG.diMinimumAbsPowerForEnable) AND _fbString.xSafetyIntlksOk AND (NOT _fbString.xError) THEN
|
||||
_iState := 5;
|
||||
END_IF
|
||||
|
||||
5: // Check if power command is within limits
|
||||
IF GVL_MODBUS.stModbusEMSComm.diSetpointActivePower < GVL_CONFIG.diMaxStringDischargePower
|
||||
AND GVL_MODBUS.stModbusEMSComm.diSetpointActivePower > GVL_CONFIG.diMaxStringChargingPower THEN
|
||||
IF GVL_MODBUS.stModbusEMSComm.stModbusReg12.diSetpointActivePower < GVL_CONFIG.diMaxStringDischargePower
|
||||
AND GVL_MODBUS.stModbusEMSComm.stModbusReg12.diSetpointActivePower > GVL_CONFIG.diMaxStringChargingPower THEN
|
||||
_xEnableString := TRUE;
|
||||
_iState := 10;
|
||||
ELSE
|
||||
// Set error bitmap flag
|
||||
GVL_MODBUS.stModbusEMSComm.lwErrorBitmap.0 := 1;
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.lwErrorBitmap.0 := 1;
|
||||
|
||||
// Goto error state
|
||||
_iState := 1000;
|
||||
@@ -90,7 +161,9 @@ CASE _iState OF
|
||||
|
||||
25: // Wait for inverter to be ready
|
||||
IF _fbInverter.xActive AND (NOT _fbInverter.xError) THEN
|
||||
GVL_MODBUS.stModbusEMSComm.eBatteryStatus := E_BATTERY_STATUS.ACTIVE;
|
||||
// Set battery status for modbus
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eBatteryStatus := E_BATTERY_STATUS.ACTIVE;
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg10.uiActiveParallelMembers := 1;
|
||||
_iState := 30;
|
||||
END_IF
|
||||
|
||||
@@ -101,22 +174,23 @@ CASE _iState OF
|
||||
|
||||
30: // String and inverter enabled
|
||||
// Set inverter power to modbus requested power
|
||||
_rPowerInverter := DINT_TO_REAL(GVL_MODBUS.stModbusEMSComm.diSetpointActivePower);
|
||||
_rPowerInverter := DINT_TO_REAL(GVL_MODBUS.stModbusEMSComm.stModbusReg12.diSetpointActivePower);
|
||||
|
||||
// Check if the battery should still be active
|
||||
IF (GVL_MODBUS.stModbusEMSComm.diSetpointActivePower = 0) THEN
|
||||
IF (GVL_MODBUS.stModbusEMSComm.stModbusReg12.diSetpointActivePower = 0) THEN
|
||||
_xNoPowerRequested := TRUE;
|
||||
ELSE
|
||||
_xNoPowerRequested := FALSE;
|
||||
END_IF
|
||||
|
||||
// Set battery status
|
||||
IF GVL_MODBUS.stModbusEMSComm.diSetpointActivePower > 0 THEN
|
||||
GVL_MODBUS.stModbusEMSComm.eChargeStatus := E_CHARGE_STATUS.DISCHARGING;
|
||||
ELSIF GVL_MODBUS.stModbusEMSComm.diSetpointActivePower < 0 THEN
|
||||
GVL_MODBUS.stModbusEMSComm.eChargeStatus := E_CHARGE_STATUS.CHARGING;
|
||||
IF GVL_MODBUS.stModbusEMSComm.stModbusReg12.diSetpointActivePower > 0 THEN
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.DISCHARGING;
|
||||
ELSIF GVL_MODBUS.stModbusEMSComm.stModbusReg12.diSetpointActivePower < 0 THEN
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.CHARGING;
|
||||
|
||||
ELSE
|
||||
GVL_MODBUS.stModbusEMSComm.eChargeStatus := E_CHARGE_STATUS.UNDEFINED;
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.UNDEFINED;
|
||||
END_IF
|
||||
|
||||
// Add small delay before shutdown by EMS is detected
|
||||
@@ -131,11 +205,12 @@ CASE _iState OF
|
||||
|
||||
// Start string shutdown
|
||||
_xEnableString := FALSE;
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg10.uiActiveParallelMembers := 0;
|
||||
_iState := 35;
|
||||
END_IF
|
||||
|
||||
// Shutdown triggered by battery fully charged
|
||||
IF GVL_MODBUS.stModbusEMSComm.eChargeStatus = E_CHARGE_STATUS.CHARGING AND (_fbString.rCurrentVoltage >= GVL_CONFIG.rStringFullyChargedVoltage) THEN
|
||||
IF GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus = E_CHARGE_STATUS.CHARGING AND (_fbString.rCurrentVoltage >= GVL_CONFIG.rStringFullyChargedVoltage) THEN
|
||||
_tonBeginShutdown(In := FALSE);
|
||||
|
||||
// Set inverter to zero power
|
||||
@@ -145,13 +220,13 @@ CASE _iState OF
|
||||
_xEnableString := FALSE;
|
||||
|
||||
// Change battery status
|
||||
GVL_MODBUS.stModbusEMSComm.eChargeStatus := E_CHARGE_STATUS.FULL;
|
||||
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.FULL;
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg10.uiActiveParallelMembers := 0;
|
||||
_iState := 35;
|
||||
END_IF
|
||||
|
||||
// Shutdown triggered by battery empty
|
||||
IF GVL_MODBUS.stModbusEMSComm.eChargeStatus = E_CHARGE_STATUS.DISCHARGING AND (_fbString.rCurrentVoltage <= GVL_CONFIG.rStringEmptyVoltage) THEN
|
||||
IF GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus = E_CHARGE_STATUS.DISCHARGING AND (_fbString.rCurrentVoltage <= GVL_CONFIG.rStringEmptyVoltage) THEN
|
||||
_tonBeginShutdown(In := FALSE);
|
||||
|
||||
// Set inverter to zero power
|
||||
@@ -161,8 +236,8 @@ CASE _iState OF
|
||||
_xEnableString := FALSE;
|
||||
|
||||
// Change battery status
|
||||
GVL_MODBUS.stModbusEMSComm.eChargeStatus := E_CHARGE_STATUS.FULL;
|
||||
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.FULL;
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg10.uiActiveParallelMembers := 0;
|
||||
_iState := 35;
|
||||
END_IF
|
||||
|
||||
@@ -205,6 +280,7 @@ CASE _iState OF
|
||||
|
||||
45: // Wait for shutdown of string to be done
|
||||
IF (NOT _fbString.xInShutdownDischargeMode) AND _fbString.xOff THEN
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eBatteryStatus := E_BATTERY_STATUS.OFF;
|
||||
_iState := 0;
|
||||
END_IF
|
||||
|
||||
@@ -217,36 +293,130 @@ CASE _iState OF
|
||||
_xEnableString := FALSE;
|
||||
_xEnableInverter := FALSE;
|
||||
_rPowerInverter := 0.0;
|
||||
GVL_MODBUS.stModbusEMSComm.eBatteryStatus := E_BATTERY_STATUS.ERROR;
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eBatteryStatus := E_BATTERY_STATUS.ERROR;
|
||||
_iState := 1010;
|
||||
|
||||
1010: // Wait for reset from error state
|
||||
IF (GVL_MODBUS.stModbusEMSComm.diSetpointActivePower = 0) AND (NOT _fbString.xError) AND (NOT _fbInverter.xError) THEN
|
||||
IF (GVL_MODBUS.stModbusEMSComm.stModbusReg12.diSetpointActivePower = 0) AND (NOT _fbString.xError) AND (NOT _fbInverter.xError) THEN
|
||||
// Reset modbus error register
|
||||
GVL_MODBUS.stModbusEMSComm.lwErrorBitmap := 0;
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.lwErrorBitmap := 0;
|
||||
|
||||
// Reset modbus error flag
|
||||
GVL_MODBUS.stModbusEMSComm.eBatteryStatus := E_BATTERY_STATUS.OFF;
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eBatteryStatus := E_BATTERY_STATUS.OFF;
|
||||
|
||||
// Goto init state
|
||||
_iState := 0;
|
||||
END_IF
|
||||
|
||||
END_CASE
|
||||
|
||||
// Send MQTT battery status
|
||||
_xBatteryStatusChange := FALSE;
|
||||
|
||||
IF GVL_MODBUS.stModbusEMSComm.stModbusReg11.eBatteryStatus <> _eLastBatteryStatus THEN
|
||||
_xBatteryStatusChange := TRUE;
|
||||
END_IF
|
||||
_eLastBatteryStatus := GVL_MODBUS.stModbusEMSComm.stModbusReg11.eBatteryStatus;
|
||||
|
||||
IF GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus <> _eLastChargeStatus THEN
|
||||
_xBatteryStatusChange := TRUE;
|
||||
END_IF
|
||||
_eLastChargeStatus := GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus;
|
||||
|
||||
IF _xBatteryStatusChange THEN
|
||||
SendBatteryStatus();
|
||||
END_IF
|
||||
|
||||
// Reset alarm confirmation
|
||||
IF _xConfirmAlarms THEN
|
||||
_xConfirmAlarms := FALSE;
|
||||
END_IF]]></ST>
|
||||
</Implementation>
|
||||
<Method Name="SendBatteryStatus" Id="{d5a8daa9-6942-4419-a57d-7958e56f7e71}">
|
||||
<Declaration><![CDATA[METHOD SendBatteryStatus
|
||||
VAR
|
||||
_sJSONString : T_MaxString;
|
||||
_fbFormatString : FB_FormatString;
|
||||
_sBatteryStatus : T_MaxString;
|
||||
_sChargeStatus : T_MaxString;
|
||||
_sBMSVersion : T_MaxString;
|
||||
END_VAR
|
||||
VAR CONSTANT
|
||||
_sTemplateString : STRING := '{"batteryStatus": "%s", "chargeStatus": "%s", "bmsVersion": "%s"}';
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[// Temp strings because string format needs write access to these variables
|
||||
_sBatteryStatus := TO_STRING(GVL_MODBUS.stModbusEMSComm.stModbusReg11.eBatteryStatus);
|
||||
_sChargeStatus := TO_STRING(GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus);
|
||||
_sBMSVersion := GVL_MODBUS.stModbusEMSComm.stModbusReg10.sBMSVersion;
|
||||
|
||||
// Build JSON string
|
||||
_fbFormatString(
|
||||
sFormat:= _sTemplateString,
|
||||
arg1:= F_STRING(_sBatteryStatus),
|
||||
arg2:= F_STRING(_sChargeStatus),
|
||||
arg3:= F_STRINg(_sBMSVersion),
|
||||
sOut=> _sJSONString);
|
||||
|
||||
// Send message if connected and no formatting error occured
|
||||
IF NOT _fbFormatString.bError AND _fbMQTTClient.bConnected THEN
|
||||
_fbMQTTClient.Publish('status', ADR(_sJSONString), INT_TO_UDINT(LEN(_sJSONString)), GVL_MQTT.eMQTTQoS, FALSE, FALSE);
|
||||
END_IF]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Action Name="SetMQTTParameter" Id="{f5ef2661-7fa1-4c9b-aa13-fba0d7bff32a}">
|
||||
<Implementation>
|
||||
<ST><![CDATA[//_fbMQTTClient.sClientId:= '';
|
||||
_fbMQTTClient.sHostName:= GVL_MQTT.sMQTTBrokerAddr;
|
||||
_fbMQTTClient.nHostPort:= 1883;
|
||||
//_fbMQTTClient.sTopicPrefix := '';
|
||||
_fbMQTTClient.nKeepAlive:= GVL_MQTT.uiMQTTKeepAlive;
|
||||
// _fbMQTTClient.ipMessageQueue := ;]]></ST>
|
||||
</Implementation>
|
||||
</Action>
|
||||
<LineIds Name="MAIN">
|
||||
<LineId Id="126" Count="55" />
|
||||
<LineId Id="405" Count="0" />
|
||||
<LineId Id="395" Count="0" />
|
||||
<LineId Id="400" Count="0" />
|
||||
<LineId Id="402" Count="1" />
|
||||
<LineId Id="399" Count="0" />
|
||||
<LineId Id="407" Count="0" />
|
||||
<LineId Id="406" Count="0" />
|
||||
<LineId Id="408" Count="0" />
|
||||
<LineId Id="410" Count="0" />
|
||||
<LineId Id="409" Count="0" />
|
||||
<LineId Id="534" Count="0" />
|
||||
<LineId Id="398" Count="0" />
|
||||
<LineId Id="404" Count="0" />
|
||||
<LineId Id="475" Count="0" />
|
||||
<LineId Id="396" Count="0" />
|
||||
<LineId Id="476" Count="0" />
|
||||
<LineId Id="478" Count="0" />
|
||||
<LineId Id="624" Count="0" />
|
||||
<LineId Id="477" Count="0" />
|
||||
<LineId Id="397" Count="0" />
|
||||
<LineId Id="126" Count="19" />
|
||||
<LineId Id="147" Count="0" />
|
||||
<LineId Id="784" Count="3" />
|
||||
<LineId Id="598" Count="0" />
|
||||
<LineId Id="808" Count="0" />
|
||||
<LineId Id="793" Count="10" />
|
||||
<LineId Id="789" Count="0" />
|
||||
<LineId Id="599" Count="0" />
|
||||
<LineId Id="463" Count="0" />
|
||||
<LineId Id="601" Count="0" />
|
||||
<LineId Id="600" Count="0" />
|
||||
<LineId Id="626" Count="0" />
|
||||
<LineId Id="617" Count="0" />
|
||||
<LineId Id="724" Count="0" />
|
||||
<LineId Id="152" Count="29" />
|
||||
<LineId Id="218" Count="0" />
|
||||
<LineId Id="182" Count="0" />
|
||||
<LineId Id="304" Count="0" />
|
||||
<LineId Id="207" Count="2" />
|
||||
<LineId Id="628" Count="0" />
|
||||
<LineId Id="314" Count="0" />
|
||||
<LineId Id="782" Count="0" />
|
||||
<LineId Id="210" Count="2" />
|
||||
<LineId Id="305" Count="1" />
|
||||
<LineId Id="308" Count="0" />
|
||||
@@ -260,6 +430,7 @@ END_IF]]></ST>
|
||||
<LineId Id="236" Count="0" />
|
||||
<LineId Id="309" Count="3" />
|
||||
<LineId Id="315" Count="1" />
|
||||
<LineId Id="632" Count="0" />
|
||||
<LineId Id="360" Count="1" />
|
||||
<LineId Id="313" Count="0" />
|
||||
<LineId Id="317" Count="0" />
|
||||
@@ -274,6 +445,7 @@ END_IF]]></ST>
|
||||
<LineId Id="263" Count="0" />
|
||||
<LineId Id="265" Count="0" />
|
||||
<LineId Id="260" Count="0" />
|
||||
<LineId Id="783" Count="0" />
|
||||
<LineId Id="245" Count="0" />
|
||||
<LineId Id="244" Count="0" />
|
||||
<LineId Id="328" Count="0" />
|
||||
@@ -311,6 +483,7 @@ END_IF]]></ST>
|
||||
<LineId Id="286" Count="0" />
|
||||
<LineId Id="282" Count="1" />
|
||||
<LineId Id="300" Count="0" />
|
||||
<LineId Id="666" Count="0" />
|
||||
<LineId Id="302" Count="1" />
|
||||
<LineId Id="301" Count="0" />
|
||||
<LineId Id="297" Count="2" />
|
||||
@@ -321,8 +494,38 @@ END_IF]]></ST>
|
||||
<LineId Id="252" Count="1" />
|
||||
<LineId Id="255" Count="0" />
|
||||
<LineId Id="254" Count="0" />
|
||||
<LineId Id="193" Count="9" />
|
||||
<LineId Id="193" Count="2" />
|
||||
<LineId Id="197" Count="0" />
|
||||
<LineId Id="647" Count="0" />
|
||||
<LineId Id="646" Count="0" />
|
||||
<LineId Id="654" Count="0" />
|
||||
<LineId Id="659" Count="0" />
|
||||
<LineId Id="648" Count="2" />
|
||||
<LineId Id="664" Count="0" />
|
||||
<LineId Id="656" Count="0" />
|
||||
<LineId Id="655" Count="0" />
|
||||
<LineId Id="657" Count="1" />
|
||||
<LineId Id="665" Count="0" />
|
||||
<LineId Id="661" Count="0" />
|
||||
<LineId Id="660" Count="0" />
|
||||
<LineId Id="662" Count="1" />
|
||||
<LineId Id="199" Count="3" />
|
||||
<LineId Id="25" Count="0" />
|
||||
</LineIds>
|
||||
<LineIds Name="MAIN.SendBatteryStatus">
|
||||
<LineId Id="27" Count="0" />
|
||||
<LineId Id="29" Count="1" />
|
||||
<LineId Id="28" Count="0" />
|
||||
<LineId Id="32" Count="0" />
|
||||
<LineId Id="31" Count="0" />
|
||||
<LineId Id="14" Count="4" />
|
||||
<LineId Id="5" Count="0" />
|
||||
<LineId Id="23" Count="0" />
|
||||
<LineId Id="19" Count="3" />
|
||||
</LineIds>
|
||||
<LineIds Name="MAIN.SetMQTTParameter">
|
||||
<LineId Id="2" Count="4" />
|
||||
<LineId Id="1" Count="0" />
|
||||
</LineIds>
|
||||
</POU>
|
||||
</TcPlcObject>
|
||||
@@ -10,11 +10,17 @@ VAR_INPUT
|
||||
rMaxBattPower : REAL := 24_000; // 24kW
|
||||
END_VAR
|
||||
VAR_OUTPUT
|
||||
// Output for SCS DC-Relais
|
||||
xCloseDCRelais AT %Q*: BOOL;
|
||||
rActDCCurrent : REAL;
|
||||
rActDCVoltage : REAL;
|
||||
xError : BOOL;
|
||||
|
||||
// Inverter active
|
||||
xActive : BOOL;
|
||||
|
||||
// FB error
|
||||
xError : BOOL;
|
||||
|
||||
// Current inverter values
|
||||
stCurrentValues : ST_SUNSPEC_CURRENT_VALUES;
|
||||
END_VAR
|
||||
VAR
|
||||
// Current state
|
||||
@@ -41,6 +47,10 @@ VAR
|
||||
// Unscaled limit for converter power
|
||||
_iWMaxLimPct : INT;
|
||||
|
||||
// Reread set power limit
|
||||
_iWMaxLimPctRead : INT;
|
||||
_iWMaxLimPctReadScaled : REAL;
|
||||
|
||||
// Scaling factor for power limiting
|
||||
_iWMaxLimPctSF : INT;
|
||||
|
||||
@@ -71,8 +81,11 @@ VAR
|
||||
// Timer for polling of current values
|
||||
_tonPollingTimer : TON;
|
||||
|
||||
// Current DC values (DCA, DCA_SF, DCV, DCV_SF) in word array for efficient modbus reading
|
||||
_awCurrentDCValues : ARRAY[0..3] OF WORD;
|
||||
// Current DC values (DCA, DCA_SF, DCV, DCV_SF, DCW, DCW_SF) in word array for efficient modbus reading
|
||||
_awCurrentDCValues : ARRAY[0..5] OF WORD;
|
||||
|
||||
// Current AC values (W, W_SF, Hz, Hz_SF, VA, VA_SF, VAr, VAr_SF, PF, PF_SF) in word array for efficient modbus reading
|
||||
_awCurrentACValues : ARRAY[0..9] OF WORD;
|
||||
|
||||
// Inverter error bits
|
||||
_dwErrorBits : DWORD;
|
||||
@@ -88,7 +101,7 @@ VAR CONSTANT
|
||||
|
||||
// Throttled power register
|
||||
// Size 1, int16 (Range = -32767 .. 32767, Not implemented 0x8000)
|
||||
W_MAX_LIM_PCT_REGISTER : WORD := 40187;
|
||||
W_MAX_LIM_PCT_REGISTER : WORD := 40187;
|
||||
|
||||
// Throttled power register scaling factor
|
||||
// Size 1, sunssf (int16) (Range = -10 .. 10, Not implemented 0x8000)
|
||||
@@ -126,6 +139,10 @@ VAR CONSTANT
|
||||
// Size 4
|
||||
DC_VALUES_START_REGISTER : WORD := 40097;
|
||||
|
||||
// Start of register with the current ac values
|
||||
// SIZE 10
|
||||
AC_VALUES_START_REGISTER : WORD := 40084;
|
||||
|
||||
// Error bits register
|
||||
// Size 2
|
||||
EVT_1_REGISTER : WORD := 40110;
|
||||
@@ -143,6 +160,7 @@ END_IF
|
||||
|
||||
// State machine
|
||||
CASE _iState OF
|
||||
|
||||
0: // Off
|
||||
// If enable and INTLK Ok
|
||||
IF xEnable THEN
|
||||
@@ -172,8 +190,34 @@ CASE _iState OF
|
||||
IF NOT _fbReadRegister.bError AND _uiInverterState = 8 THEN
|
||||
_iState := 20;
|
||||
END_IF
|
||||
|
||||
// If the inverter is not ready wait some time before polling again
|
||||
IF NOT _fbReadRegister.bError AND _uiInverterState <> 8 THEN
|
||||
_iState := 15;
|
||||
END_IF
|
||||
|
||||
_fbReadRegister(bExecute := FALSE);
|
||||
END_IF
|
||||
|
||||
// If not enable, go back to idle
|
||||
IF NOT xEnable THEN
|
||||
_fbReadRegister(bExecute := FALSE);
|
||||
_iState := 0;
|
||||
END_IF
|
||||
|
||||
15: // Delay polling inverter ready
|
||||
_tonPollingTimer(IN := TRUE, PT := _timPollingDelay);
|
||||
IF _tonPollingTimer.Q THEN
|
||||
_tonPollingTimer(IN := FALSE);
|
||||
_iState := 10;
|
||||
END_IF
|
||||
|
||||
// If not enable, go back to idle
|
||||
IF NOT xEnable THEN
|
||||
_tonPollingTimer(IN := FALSE);
|
||||
_iState := 0;
|
||||
END_IF
|
||||
|
||||
|
||||
20: // Read inverter max power scaling
|
||||
_iErrorInState := _iState;
|
||||
@@ -271,7 +315,7 @@ CASE _iState OF
|
||||
_rWMax := LREAL_TO_REAL(_iWMax * EXPT(10,_iWMaxSF));
|
||||
|
||||
// Calculate power to write to register
|
||||
_iWMaxLimPct := LREAL_TO_INT(rPower * EXPT(10,_iWMaxLimPctSF) / _rWMax);
|
||||
_iWMaxLimPct := LREAL_TO_INT((rPower*100)/(_rWMax * EXPT(10,_iWMaxLimPctSF)));
|
||||
ELSE
|
||||
xError := TRUE;
|
||||
// Goto error state
|
||||
@@ -311,6 +355,32 @@ CASE _iState OF
|
||||
_fbWriteRegister(bExecute := FALSE);
|
||||
END_IF
|
||||
|
||||
// 45: // Read set power
|
||||
// _fbReadRegister(
|
||||
// sIPAddr:= sInverterIPAddr,
|
||||
// nTCPPort:= 502,
|
||||
// nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
// nQuantity:= 1,
|
||||
// nMBAddr:= W_MAX_LIM_PCT_REGISTER,
|
||||
// cbLength:= SIZEOF(_iWMaxLimPctRead),
|
||||
// pDestAddr:= ADR(_iWMaxLimPctRead),
|
||||
// bExecute:= TRUE,
|
||||
// tTimeout:= T#5S,
|
||||
// bBusy=> ,
|
||||
// bError=> ,
|
||||
// nErrId=> ,
|
||||
// cbRead=> );
|
||||
|
||||
// // Check if reading mudbus register is done
|
||||
// IF NOT _fbReadRegister.bBusy THEN
|
||||
// IF NOT _fbReadRegister.bError THEN
|
||||
// _iWMaxLimPctReadScaled := LREAL_TO_INT(_rWMax * _iWMaxLimPctRead * EXPT(10,_iWMaxLimPctSF)*0.01);
|
||||
// _iState := 50;
|
||||
// END_IF
|
||||
// _fbReadRegister(bExecute := FALSE);
|
||||
// END_IF
|
||||
|
||||
|
||||
50: // Enable Power limiting (THROTTLED)
|
||||
_iErrorInState := _iState;
|
||||
_fbWriteRegister(
|
||||
@@ -369,7 +439,7 @@ CASE _iState OF
|
||||
_fbWriteRegister(bExecute := FALSE);
|
||||
END_IF
|
||||
|
||||
65: // Wait for error polling timer
|
||||
65: // Wait for polling timer
|
||||
_tonPollingTimer(IN := TRUE, PT := _timPollingDelay);
|
||||
IF _tonPollingTimer.Q THEN
|
||||
_tonPollingTimer(IN := FALSE);
|
||||
@@ -378,6 +448,8 @@ CASE _iState OF
|
||||
_tonPollingTimer(IN := FALSE);
|
||||
// If power has ben changed, goto set power limit mode
|
||||
_iState := 40;
|
||||
// Calculate power to write to register
|
||||
_iWMaxLimPct := LREAL_TO_INT((rPower*100)/(_rWMax * EXPT(10,_iWMaxLimPctSF)));
|
||||
END_IF
|
||||
|
||||
// check if inverter should shut down
|
||||
@@ -428,7 +500,7 @@ CASE _iState OF
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nQuantity:= 4,
|
||||
nQuantity:= 6,
|
||||
nMBAddr:= DC_VALUES_START_REGISTER,
|
||||
cbLength:= SIZEOF(_awCurrentDCValues),
|
||||
pDestAddr:= ADR(_awCurrentDCValues),
|
||||
@@ -443,9 +515,45 @@ CASE _iState OF
|
||||
IF NOT _fbReadRegister.bBusy THEN
|
||||
// If there was no error and the converter has no error continue
|
||||
IF NOT _fbReadRegister.bError THEN
|
||||
_iState := 85;
|
||||
stCurrentValues.rActDCCurrent := LREAL_TO_REAL(WORD_TO_UINT(_awCurrentDCValues[0]) * EXPT(10,WORD_TO_INT(_awCurrentDCValues[1])));
|
||||
stCurrentValues.rActDCVoltage := LREAL_TO_REAL(WORD_TO_UINT(_awCurrentDCValues[2]) * EXPT(10,WORD_TO_INT(_awCurrentDCValues[3])));
|
||||
stCurrentValues.rActDCPower := LREAL_TO_REAL(WORD_TO_INT(_awCurrentDCValues[4]) * EXPT(10,WORD_TO_INT(_awCurrentDCValues[5])));
|
||||
ELSE
|
||||
// Read error register
|
||||
_iState := 1000;
|
||||
END_IF
|
||||
_fbReadRegister(bExecute := FALSE);
|
||||
END_IF
|
||||
|
||||
85: // Read current ac values
|
||||
_iErrorInState := _iState;
|
||||
_fbReadRegister(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nQuantity:= 10,
|
||||
nMBAddr:= AC_VALUES_START_REGISTER,
|
||||
cbLength:= SIZEOF(_awCurrentACValues),
|
||||
pDestAddr:= ADR(_awCurrentACValues),
|
||||
bExecute:= TRUE,
|
||||
tTimeout:= T#5S,
|
||||
bBusy=> ,
|
||||
bError=> ,
|
||||
nErrId=> ,
|
||||
cbRead=> );
|
||||
|
||||
// Check if reading mudbus register is done
|
||||
IF NOT _fbReadRegister.bBusy THEN
|
||||
// If there was no error and the converter has no error continue
|
||||
IF NOT _fbReadRegister.bError THEN
|
||||
// Go back to polling state
|
||||
_iState := 65;
|
||||
rActDCCurrent := LREAL_TO_REAL(WORD_TO_UINT(_awCurrentDCValues[0]) * EXPT(10,WORD_TO_INT(_awCurrentDCValues[1])));
|
||||
rActDCVoltage := LREAL_TO_REAL(WORD_TO_UINT(_awCurrentDCValues[2]) * EXPT(10,WORD_TO_INT(_awCurrentDCValues[3])));
|
||||
stCurrentValues.rActACPower := LREAL_TO_REAL(WORD_TO_INT(_awCurrentACValues[0]) * EXPT(10,WORD_TO_INT(_awCurrentACValues[1])));
|
||||
stCurrentValues.rActACFreq := LREAL_TO_REAL(WORD_TO_UINT(_awCurrentACValues[2]) * EXPT(10,WORD_TO_INT(_awCurrentACValues[3])));
|
||||
stCurrentValues.rActApparentPower := LREAL_TO_REAL(WORD_TO_INT(_awCurrentACValues[4]) * EXPT(10,WORD_TO_INT(_awCurrentACValues[5])));
|
||||
stCurrentValues.rActReactivePower := LREAL_TO_REAL(WORD_TO_INT(_awCurrentACValues[6]) * EXPT(10,WORD_TO_INT(_awCurrentACValues[7])));
|
||||
stCurrentValues.rActPowerFactor := LREAL_TO_REAL(WORD_TO_INT(_awCurrentACValues[8]) * EXPT(10,WORD_TO_INT(_awCurrentACValues[9])));
|
||||
ELSE
|
||||
// Read error register
|
||||
_iState := 1000;
|
||||
@@ -474,8 +582,8 @@ CASE _iState OF
|
||||
// And there is no error, then continue
|
||||
IF NOT _fbWriteRegister.bError THEN
|
||||
_iState := 210;
|
||||
rActDCCurrent := 0.0;
|
||||
rActDCVoltage := 0.0;
|
||||
stCurrentValues.rActDCCurrent := 0.0;
|
||||
stCurrentValues.rActDCVoltage := 0.0;
|
||||
ELSE
|
||||
// Goto error state
|
||||
_iState := 1000;
|
||||
@@ -572,7 +680,27 @@ CASE _iState OF
|
||||
END_CASE]]></ST>
|
||||
</Implementation>
|
||||
<LineIds Name="FB_PowerSupplySunspec">
|
||||
<LineId Id="774" Count="70" />
|
||||
<LineId Id="774" Count="10" />
|
||||
<LineId Id="1550" Count="0" />
|
||||
<LineId Id="785" Count="28" />
|
||||
<LineId Id="1701" Count="5" />
|
||||
<LineId Id="814" Count="1" />
|
||||
<LineId Id="1714" Count="0" />
|
||||
<LineId Id="1719" Count="0" />
|
||||
<LineId Id="1715" Count="0" />
|
||||
<LineId Id="1718" Count="0" />
|
||||
<LineId Id="1716" Count="1" />
|
||||
<LineId Id="1707" Count="1" />
|
||||
<LineId Id="1710" Count="2" />
|
||||
<LineId Id="1709" Count="0" />
|
||||
<LineId Id="1713" Count="0" />
|
||||
<LineId Id="1720" Count="0" />
|
||||
<LineId Id="1722" Count="1" />
|
||||
<LineId Id="1726" Count="0" />
|
||||
<LineId Id="1725" Count="0" />
|
||||
<LineId Id="1721" Count="0" />
|
||||
<LineId Id="1433" Count="0" />
|
||||
<LineId Id="816" Count="28" />
|
||||
<LineId Id="1171" Count="0" />
|
||||
<LineId Id="845" Count="33" />
|
||||
<LineId Id="1172" Count="0" />
|
||||
@@ -580,9 +708,19 @@ END_CASE]]></ST>
|
||||
<LineId Id="1173" Count="0" />
|
||||
<LineId Id="913" Count="29" />
|
||||
<LineId Id="1174" Count="0" />
|
||||
<LineId Id="943" Count="28" />
|
||||
<LineId Id="943" Count="4" />
|
||||
<LineId Id="1520" Count="0" />
|
||||
<LineId Id="1522" Count="17" />
|
||||
<LineId Id="1541" Count="0" />
|
||||
<LineId Id="1548" Count="0" />
|
||||
<LineId Id="1542" Count="2" />
|
||||
<LineId Id="1521" Count="0" />
|
||||
<LineId Id="1493" Count="0" />
|
||||
<LineId Id="948" Count="23" />
|
||||
<LineId Id="1175" Count="0" />
|
||||
<LineId Id="972" Count="46" />
|
||||
<LineId Id="972" Count="42" />
|
||||
<LineId Id="1560" Count="1" />
|
||||
<LineId Id="1015" Count="3" />
|
||||
<LineId Id="1127" Count="0" />
|
||||
<LineId Id="1019" Count="25" />
|
||||
<LineId Id="1097" Count="1" />
|
||||
@@ -594,8 +732,17 @@ END_CASE]]></ST>
|
||||
<LineId Id="1063" Count="20" />
|
||||
<LineId Id="1090" Count="0" />
|
||||
<LineId Id="1092" Count="0" />
|
||||
<LineId Id="1775" Count="0" />
|
||||
<LineId Id="1084" Count="4" />
|
||||
<LineId Id="1062" Count="0" />
|
||||
<LineId Id="1736" Count="1" />
|
||||
<LineId Id="1739" Count="19" />
|
||||
<LineId Id="1781" Count="0" />
|
||||
<LineId Id="1759" Count="2" />
|
||||
<LineId Id="1774" Count="0" />
|
||||
<LineId Id="1776" Count="1" />
|
||||
<LineId Id="1762" Count="4" />
|
||||
<LineId Id="1738" Count="0" />
|
||||
<LineId Id="1093" Count="1" />
|
||||
<LineId Id="1102" Count="19" />
|
||||
<LineId Id="1166" Count="1" />
|
||||
|
||||
33
PLC/POUs/Sunspec/ST_SUNSPEC_CURRENT_VALUES.TcDUT
Normal file
33
PLC/POUs/Sunspec/ST_SUNSPEC_CURRENT_VALUES.TcDUT
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.12">
|
||||
<DUT Name="ST_SUNSPEC_CURRENT_VALUES" Id="{429ce2f6-f580-460c-8eb4-3ddb289effd4}">
|
||||
<Declaration><![CDATA[TYPE ST_SUNSPEC_CURRENT_VALUES :
|
||||
STRUCT
|
||||
// Current DC current (A)
|
||||
rActDCCurrent : REAL;
|
||||
|
||||
// Current DC voltage (V)
|
||||
rActDCVoltage : REAL;
|
||||
|
||||
// Current DC power (W)
|
||||
rActDCPower : REAL;
|
||||
|
||||
// Current AC power (W)
|
||||
rActACPower : REAL;
|
||||
|
||||
// Current AC frequency (Hz)
|
||||
rActACFreq : REAL;
|
||||
|
||||
// Current AC apparent power (VA)
|
||||
rActApparentPower : REAL;
|
||||
|
||||
// Current AC reactive power (VAr)
|
||||
rActReactivePower : REAL;
|
||||
|
||||
// Current AC power factor
|
||||
rActPowerFactor : REAL;
|
||||
END_STRUCT
|
||||
END_TYPE
|
||||
]]></Declaration>
|
||||
</DUT>
|
||||
</TcPlcObject>
|
||||
Reference in New Issue
Block a user