Sic01/FrameworkLocal/RTEquipmentLibrary/Unit/IoHeartbeat.cs

121 lines
3.3 KiB
C#
Raw Normal View History

2023-01-16 11:14:35 +08:00
using System;
using System.Xml;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.IOCore;
using Aitex.Core.Util;
namespace Aitex.Core.RT.Device.Unit
{
/// <summary>
/// 心跳包机制
///
/// 功能:
/// 1.C#送出给PLC如果PLC检测到C#心跳信号停止则判定C#程序运行异常,从而触发安全逻辑动作.
/// 2.C#检测PLC返回的心跳包信号如果检测到PLC心跳信号停止则判定PLC程序运行异常从而进行报警处理.
/// </summary>
public class IoHeartbeat : BaseDevice, IDevice
{
public float Feedback
{
get
{
return _isFloatAioType ? _ai.FloatValue : _ai.Value;
}
}
public float SetPoint
{
get
{
return _isFloatAioType ? _ao.FloatValue : _ao.Value;
}
set
{
if (_isFloatAioType)
_ao.FloatValue = value;
else
{
_ao.Value = (short)value;
}
}
}
private int PLC_Heart_Beat_Timeout_ms = 1000* 120;
//IO
private AIAccessor _ai = null;
private AOAccessor _ao = null;
private DeviceTimer _updateTimer = new DeviceTimer(); //更新 AO信号 给PLC
private int MAX = 0x7FFF;
private float _prevAiValue = 0;
private DeviceTimer _connectTimer = new DeviceTimer();
private R_TRIG _trigConnectionLost = new R_TRIG();
private bool _isFloatAioType = false;
public IoHeartbeat(string module, XmlElement node, string ioModule = "")
{
base.Module = module;
base.Name = node.GetAttribute("id");
base.Display = node.GetAttribute("display");
base.DeviceID = node.GetAttribute("schematicId");
_ai = ParseAiNode("ai", node, ioModule);
_ao = ParseAoNode("ao", node, ioModule);
_isFloatAioType = !string.IsNullOrEmpty(node.GetAttribute("aioType")) && (node.GetAttribute("aioType") == "float");
}
public bool Initialize()
{
_updateTimer.Start(500);
_connectTimer.Start(PLC_Heart_Beat_Timeout_ms);
return true;
}
public void Terminate()
{
}
public void Monitor()
{
if (Math.Abs(_prevAiValue - Feedback) > 0.01)
{
_connectTimer.Start(PLC_Heart_Beat_Timeout_ms);
}
_trigConnectionLost.CLK = _connectTimer.IsTimeout();
if (_trigConnectionLost.Q)
{
EV.PostAlarmLog(Module, $"PLC heartbeat check failed");
}
_prevAiValue = Feedback;
//如果计时到达,则翻转心跳信号
if (_updateTimer.IsTimeout())
{
int value = (int)SetPoint;
value++;
if (value >= MAX)
{
value = 0;
}
SetPoint = value;
_updateTimer.Start(500); //500 ms
}
}
public void Reset()
{
_connectTimer.Start(PLC_Heart_Beat_Timeout_ms);
_trigConnectionLost.RST = true;
}
}
}