| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 | using System;using System.Xml;using Aitex.Core.RT.Device;using Aitex.Core.RT.Event;using Aitex.Core.RT.IOCore;using Aitex.Core.Util;namespace VirgoRT.Devices.IODevices{    /// <summary>    /// 心跳包机制    ///    /// 功能:    /// 1.C#送出给PLC,如果PLC检测到C#心跳信号停止,则判定C#程序运行异常,从而触发安全逻辑动作。    /// 2.C#检测PLC返回的心跳包信号,如果检测到PLC心跳信号停止,则判定PLC程序运行异常,从而进行报警处理。    /// </summary>    public class IoHeartbeat : BaseDevice, IDevice    {        private readonly int PLC_Heart_Beat_Timeout_ms = 1000 * 120;        private readonly AIAccessor _ai;        private readonly AOAccessor _ao;        private readonly DeviceTimer _updateTimer = new DeviceTimer();  //更新 AO信号 给PLC        private readonly int MAX = 0x7FFF;        private float _prevAiValue;        private readonly DeviceTimer _connectTimer = new DeviceTimer();        private readonly R_TRIG _trigConnectionLost = new R_TRIG();        // --------------------------Constructor-----------------------        //         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);        }        public bool Initialize()        {            _updateTimer.Start(500);            _connectTimer.Start(PLC_Heart_Beat_Timeout_ms);            return true;        }        public void Monitor()        {            if (Math.Abs(_prevAiValue - _GetRealFloat(_ai)) > 0.01)            {                _connectTimer.Start(PLC_Heart_Beat_Timeout_ms);            }            _trigConnectionLost.CLK = _connectTimer.IsTimeout();            if (_trigConnectionLost.Q)            {                EV.PostMessage(Module, EventEnum.PlcHeartBeatFail, Module, Display);            }            _prevAiValue = _GetRealFloat(_ai);            //如果计时到达,则翻转心跳信号            if (_updateTimer.IsTimeout())            {                float beat_val = _GetRealFloat(_ao);                beat_val++;                if (beat_val >= MAX)                {                    beat_val = 0;                }                _SetRealFloat(_ao, beat_val);                _updateTimer.Start(3000);       //500 ms            }        }        public void Terminate() {  }        public void Reset()        {            _connectTimer.Start(PLC_Heart_Beat_Timeout_ms);            _trigConnectionLost.RST = true;        }    }}
 |