IoHeartbeat.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. using System;
  2. using System.Xml;
  3. using Aitex.Core.RT.Event;
  4. using Aitex.Core.RT.IOCore;
  5. using Aitex.Core.Util;
  6. namespace Aitex.Core.RT.Device.Unit
  7. {
  8. /// <summary>
  9. /// 心跳包机制
  10. ///
  11. /// 功能:
  12. /// 1.C#送出给PLC,如果PLC检测到C#心跳信号停止,则判定C#程序运行异常,从而触发安全逻辑动作.
  13. /// 2.C#检测PLC返回的心跳包信号,如果检测到PLC心跳信号停止,则判定PLC程序运行异常,从而进行报警处理.
  14. /// </summary>
  15. public class IoHeartbeat : BaseDevice, IDevice
  16. {
  17. public float Feedback
  18. {
  19. get
  20. {
  21. return _isFloatAioType ? _ai.FloatValue : _ai.Value;
  22. }
  23. }
  24. public float SetPoint
  25. {
  26. get
  27. {
  28. return _isFloatAioType ? _ao.FloatValue : _ao.Value;
  29. }
  30. set
  31. {
  32. if (_isFloatAioType)
  33. _ao.FloatValue = value;
  34. else
  35. {
  36. _ao.Value = (short)value;
  37. }
  38. }
  39. }
  40. private int PLC_Heart_Beat_Timeout_ms = 1000* 120;
  41. //IO
  42. private AIAccessor _ai = null;
  43. private AOAccessor _ao = null;
  44. private DeviceTimer _updateTimer = new DeviceTimer(); //更新 AO信号 给PLC
  45. private int MAX = 0x7FFF;
  46. private float _prevAiValue = 0;
  47. private DeviceTimer _connectTimer = new DeviceTimer();
  48. private R_TRIG _trigConnectionLost = new R_TRIG();
  49. private bool _isFloatAioType = false;
  50. public IoHeartbeat(string module, XmlElement node, string ioModule = "")
  51. {
  52. base.Module = module;
  53. base.Name = node.GetAttribute("id");
  54. base.Display = node.GetAttribute("display");
  55. base.DeviceID = node.GetAttribute("schematicId");
  56. _ai = ParseAiNode("ai", node, ioModule);
  57. _ao = ParseAoNode("ao", node, ioModule);
  58. _isFloatAioType = !string.IsNullOrEmpty(node.GetAttribute("aioType")) && (node.GetAttribute("aioType") == "float");
  59. }
  60. public bool Initialize()
  61. {
  62. _updateTimer.Start(500);
  63. _connectTimer.Start(PLC_Heart_Beat_Timeout_ms);
  64. return true;
  65. }
  66. public void Terminate()
  67. {
  68. }
  69. public void Monitor()
  70. {
  71. if (Math.Abs(_prevAiValue - Feedback) > 0.01)
  72. {
  73. _connectTimer.Start(PLC_Heart_Beat_Timeout_ms);
  74. }
  75. _trigConnectionLost.CLK = _connectTimer.IsTimeout();
  76. if (_trigConnectionLost.Q)
  77. {
  78. EV.PostAlarmLog(Module, $"PLC heartbeat check failed");
  79. }
  80. _prevAiValue = Feedback;
  81. //如果计时到达,则翻转心跳信号
  82. if (_updateTimer.IsTimeout())
  83. {
  84. int value = (int)SetPoint;
  85. value++;
  86. if (value >= MAX)
  87. {
  88. value = 0;
  89. }
  90. SetPoint = value;
  91. _updateTimer.Start(500); //500 ms
  92. }
  93. }
  94. public void Reset()
  95. {
  96. _connectTimer.Start(PLC_Heart_Beat_Timeout_ms);
  97. _trigConnectionLost.RST = true;
  98. }
  99. }
  100. }