EMS-BMS heartbeat and modbus fixes

added ledge and error state when modbus communication is lost, seperated register 13004 (confirm) from registers 13000-13001 (BMS/String warning/error messages) for modbus mapping, added Heartbeat error message to bmsErrors
This commit is contained in:
Markus Neukirch
2025-07-14 18:02:33 +02:00
parent e6802b87b4
commit ee3367eaec
6 changed files with 54 additions and 34 deletions

View File

@@ -3,11 +3,12 @@
<DUT Name="ST_WORD_BMS_ERROR_BITMAP" Id="{33fc17c1-ae64-4c44-aa8c-117a09c656ef}">
<Declaration><![CDATA[TYPE ST_WORD_BMS_ERROR_BITMAP :
STRUCT
bEStop : BIT; // Bit 0
bEthercat : BIT; // Bit 1
bDCSwitchS1 : BIT; // Bit 2
bDCSwitchS2 : BIT; // Bit 3
bError : BIT; // Bit 4
bEStop : BIT; // Bit 0
bEthercat : BIT; // Bit 1
bDCSwitchS1 : BIT; // Bit 2
bDCSwitchS2 : BIT; // Bit 3
bError : BIT; // Bit 4
bEMSHeartbeatError : BIT; // Bit 5
END_STRUCT
END_TYPE
]]></Declaration>

View File

@@ -21,10 +21,6 @@ STRUCT
// (Bit 0 -> Error in string 1 active, Bit 1 -> String 2, etc.)
// Addr: 13.003
wStringErrorActive : WORD;
// Confirm alarms through modbus
// Addr: 13.004
wConfirmAlarms : WORD;
END_STRUCT
END_TYPE
]]></Declaration>

View File

@@ -20,6 +20,10 @@ VAR_GLOBAL
// Addr: 13.000
stBMSErrorReg : ST_MODBUS_REG_13;
// Confirm alarms through modbus
// Addr: 13.004
wConfirmAlarms : WORD;
// Addr: 14.000 -> 14.047
// Index 0 -> Unit 1, Index 1 -> Unit 2 etc.
awWarningsUnitsActive : ARRAY [0..(GVL_CONFIG.uiNumberOfUnits-1)] OF U_UNIT_WARNING_REGISTER;

File diff suppressed because one or more lines are too long

View File

@@ -81,6 +81,8 @@ VAR
// EMS heartbeat not ok signal
_xEMSHeartbeatNotOK : BOOL;
_xEMSHeartbeatNotOKLedge : BOOL;
_rtrigEMSHeartbeakNotOK : R_TRIG;
// Error signal for no EMS Heartbeat
_fbEMSHeartbeatTimeout : FB_ReleaseSignal;
@@ -216,8 +218,8 @@ IF GVL_SCADA.stAckAlarmsButton.xRequest THEN
END_IF
// Ack alarms through modbus
IF GVL_MODBUS.stBMSErrorReg.wConfirmAlarms > 0 THEN
GVL_MODBUS.stBMSErrorReg.wConfirmAlarms := 0;
IF GVL_MODBUS.wConfirmAlarms > 0 THEN
GVL_MODBUS.wConfirmAlarms := 0;
_xConfirmAlarms := TRUE;
END_IF
@@ -560,10 +562,22 @@ END_IF
IF _xConfirmAlarms AND _fbEMSHeartbeatAlarm.eConfirmationState = TcEventConfirmationState.WaitForConfirmation THEN
_fbEMSHeartbeatAlarm.Confirm(0);
END_IF
// Ledge heartbeatNOK
_rtrigEMSHeartbeakNotOK(CLK := _xEMSHeartbeatNotOK);
IF _rtrigEMSHeartbeakNotOK.Q THEN
_xEMSHeartbeatNotOKLedge := TRUE;
END_IF
IF NOT _xEMSHeartbeatNotOK AND _xConfirmAlarms THEN
_xEMSHeartbeatNotOKLedge := FALSE;
END_IF
// ===============================
// Copy data to modbus registers
// ===============================
// heartbeat
GVL_MODBUS.stBMSErrorReg.wBMSErrorActive.stBitmap.bEMSHeartbeatError := _xEMSHeartbeatNotOKLedge;
// Modbus current inverter values
GVL_MODBUS.stModbusEMSComm.stModbusReg11.diCurrentActivePower := 0;
GVL_MODBUS.stModbusEMSComm.stModbusReg11.diCurrentReactivePower := 0;
@@ -596,10 +610,14 @@ CASE _eBMSControlMode OF
// Only set power to EMS requested power if the EMS heartbeat is ok
// Otherwise shutdown battery
IF (NOT _xEMSHeartbeatNotOK) THEN
IF (NOT _xEMSHeartbeatNotOKLedge) AND _iState <> 1010 THEN
_rAutoPowerRequest := DINT_TO_REAL(GVL_MODBUS.stModbusEMSComm.stModbusReg12.diSetpointActivePower);
ELSIF _iState = 1010 THEN
_rAutoPowerRequest := 0;
ELSE
_rAutoPowerRequest := 0;
_xErrorShutdown := TRUE;
_iState := 1000;
END_IF
IF (GVL_SCADA.eRequestedControlMode <> _eBMSControlMode) AND (GVL_SCADA.xCanChangeControlMode) THEN

View File

@@ -194,7 +194,7 @@
</SubItem>
</DataType>
<DataType>
<Name GUID="{18071995-0000-0000-0000-002000000003}" IecBaseType="true" BitType="true" AutoDeleteType="true" HideSubItems="true">ARRAY [0..2] OF BIT</Name>
<Name GUID="{18071995-0000-0000-0000-002000000003}" IecBaseType="true" AutoDeleteType="true" HideSubItems="true">ARRAY [0..2] OF BIT</Name>
<BitSize>3</BitSize>
<BaseType GUID="{18071995-0000-0000-0000-000000000010}">BIT</BaseType>
<ArrayInfo>
@@ -203,7 +203,7 @@
</ArrayInfo>
</DataType>
<DataType>
<Name GUID="{18071995-0000-0000-0000-002000000002}" IecBaseType="true" BitType="true" AutoDeleteType="true" HideSubItems="true">ARRAY [0..1] OF BIT</Name>
<Name GUID="{18071995-0000-0000-0000-002000000002}" IecBaseType="true" AutoDeleteType="true" HideSubItems="true">ARRAY [0..1] OF BIT</Name>
<BitSize>2</BitSize>
<BaseType GUID="{18071995-0000-0000-0000-000000000010}">BIT</BaseType>
<ArrayInfo>
@@ -269,7 +269,7 @@
</System>
<Plc>
<Project GUID="{9AE64910-5EB2-4866-93FD-EFE059C38C36}" Name="PLC" PrjFilePath="PLC\PLC.plcproj" TmcFilePath="PLC\PLC.tmc" ReloadTmc="true" AmsPort="851" FileArchiveSettings="#x000e" CopyTmcToTarget="true" CopyTpyToTarget="false" SymbolicMapping="true">
<Instance Id="#x08502000" TcSmClass="TComPlcObjDef" KeepUnrestoredLinks="2" TmcHash="{DB0C6B7B-135C-3497-0B32-96858A1635E6}" TmcPath="PLC\PLC.tmc">
<Instance Id="#x08502000" TcSmClass="TComPlcObjDef" KeepUnrestoredLinks="2" TmcHash="{A0F2628C-48EB-9D12-8507-F5C9CD4F0746}" TmcPath="PLC\PLC.tmc">
<Name>PLC Instance</Name>
<CLSID ClassFactory="TcPlc30">{08500001-0000-0000-F000-000000000064}</CLSID>
<Vars VarGrpType="2" AreaNo="1">