| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 | 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;using Aitex.Core.RT.SCCore;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 * 10;        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();        private bool _isSimulatorMode;        //public bool IsUnConnect;        // --------------------------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);            _isSimulatorMode = SC.GetConfigItem("System.IsSimulatorMode").BoolValue;        }        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)            {                //IsUnConnect = true;                //LOG.Write(eEvent.ERR_PLC_HEARTBEAT_FAIL, ModuleHelper.Converter(Module), Display);                if (!_isSimulatorMode)                {                    if (Module == "TM")                    {                        LOG.Write(eEvent.ERR_TM_PLC_HEARTBEAT_FAIL, Module, Display);                    }                    else                    {                        LOG.Write(eEvent.ERR_PM_PLC_HEARTBEAT_FAIL, 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;            //IsUnConnect = false;        }    }}
 |