| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 | using System;using System.Xml;using Aitex.Core.RT.Device;using Aitex.Core.RT.Event;using Aitex.Core.RT.IOCore;using Aitex.Core.Util;using Aitex.Core.RT.Log;using MECF.Framework.Common.Equipment;namespace Venus_RT.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)            {                LOG.Write(eEvent.ERR_PLC_HEARTBEAT_FAIL, ModuleHelper.Converter(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;        }    }}
 |