| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534 | using Aitex.Common.Util;using Aitex.Core.RT.Log;using Aitex.Core.Util;using MECF.Framework.Common.Device.TemperatureController;using MECF.Framework.Simulator.Core.Driver;using System;using System.Collections.Generic;using System.Diagnostics;using System.IO;using System.Linq;using System.Text;using System.Threading.Tasks;namespace MECF.Framework.Simulator.Core.Commons{    public class TemperatureControllerSerialPortDevice : BaseSerialSimulator    {        #region 常量        private const string PORT_NAME = "com12";        private const byte ADD_FLAG = 0x30;        #endregion        #region 内部变量        /// <summary>        /// 控制字字典        /// </summary>        private Dictionary<byte, string> dic = new Dictionary<byte, string>()         {            { 0x05,"ENQ" },            { 0x02,"STX" },            { 0x03,"ETX" },            { 0x06,"ACK" },            { 0x0D,"CR" },            { 0x01,"SOH" }        };        /// <summary>        /// 命令字典        /// </summary>        private Dictionary<byte, string> comdic = new Dictionary<byte, string>()        {            { 0x31,"Target Temp" },            { 0x32,"Internal" },            { 0x33,"External" },            { 0x34,"Alarm" },            { 0x35,"Average" },            { 0x36,"offset" },            { 0x39,"control" },            { 0x41,"PB" },            { 0x42,"ARW" },            { 0x43,"IConstant" },            { 0x44,"DConstant" },            { 0x45,"OutPutRatio" },            { 0x46,"HeatingLimit" },            { 0x47,"CoolingLimit" },            { 0x48,"Saved" }        };        private double[] _reserviorValues = new double[10];        private double[] _heatValues = new double[10];        private double[] _targetValues = new double[10];        private int _controlOperation = 0;        //private byte[] alarm = new byte[12] { 0,0,0,0,1,0,0,0,0,0,0,0};        private byte[] alarm = new byte[3] {0x30,0x33,0x30};        System.Timers.Timer[] _timers;        private int _tcCount = 1;        #endregion        /// <summary>        /// 构造函数        /// </summary>        /// <param name="portName"></param>        /// <param name="type"></param>        public TemperatureControllerSerialPortDevice(string port) : base(port, SerialType.BUFFER)        {            Init(port);                   }        /// <summary>        /// 初始化        /// </summary>        /// <param name="port"></param>        private void Init(string port)        {            //加载TC配置            try            {                string oldXmlPath = PathManager.GetCfgDir();                string newXmlPath = oldXmlPath.Replace("CyberX8_Simulator", "CyberX8_RT") + "Devices\\SMCCfg.xml";                TemperatureConfig cfg = CustomXmlSerializer.Deserialize<TemperatureConfig>(new FileInfo(newXmlPath));                if (cfg != null)                {                    foreach (TemperatureDeviceConfig config in cfg.TemperatureDeviceConfigs)                    {                        if (int.TryParse(config.Port.Substring(3,2), out int result1) && int.TryParse(port.Substring(3, 2), out int result2))                        {                            if(result1 + 1 == result2) _tcCount = config.TemperatureDevices.Count;                        }                    }                }            }            catch (Exception ex)             {            }            //            _timers = new System.Timers.Timer[_tcCount];            for(int i = 0; i < _tcCount; i++)            {                _heatValues[i] = 16.5;                _targetValues[i] = 0;                _reserviorValues[i] = 16.6;                _timers[i] = new System.Timers.Timer(50);                switch (i)                {                       case 0:                        _timers[0].Elapsed += Timer_Elapsed0;                        break;                    case 1:                        _timers[1].Elapsed += Timer_Elapsed1;                        break;                    case 2:                        _timers[2].Elapsed += Timer_Elapsed2;                        break;                    case 3:                        _timers[3].Elapsed += Timer_Elapsed3;                        break;                    case 4:                        _timers[4].Elapsed += Timer_Elapsed4;                        break;                    default:                        break;                }                           }                               }        /// <summary>        /// TC1-1的调温        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void Timer_Elapsed0(object sender, System.Timers.ElapsedEventArgs e)        {            if (Math.Abs(_heatValues[0] - _targetValues[0]) >= 0.2)            {                //内部调温                if (_heatValues[0] < _targetValues[0])                {                    _heatValues[0] += 0.1;                }                else                {                    _heatValues[0] -= 0.1;                }                //外部调温                if (_reserviorValues[0] < _targetValues[0])                {                    _reserviorValues[0] += 0.1;                }                else                {                    _reserviorValues[0] -= 0.1;                }            }            else            {                _timers[0].Stop();            }        }        /// <summary>        /// TC1-2的调温        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void Timer_Elapsed1(object sender, System.Timers.ElapsedEventArgs e)        {            if (Math.Abs(_heatValues[1] - _targetValues[1]) >= 0.2)            {                //内部调温                if (_heatValues[1] < _targetValues[1])                {                    _heatValues[1] += 0.1;                }                else                {                    _heatValues[1] -= 0.1;                }                //外部调温                if (_reserviorValues[1] < _targetValues[1])                {                    _reserviorValues[1] += 0.1;                }                else                {                    _reserviorValues[1] -= 0.1;                }            }            else            {                _timers[1].Stop();            }        }        /// <summary>        /// TC1-3的调温        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void Timer_Elapsed2(object sender, System.Timers.ElapsedEventArgs e)        {            if (Math.Abs(_heatValues[2] - _targetValues[2]) >= 0.2)            {                //内部调温                if (_heatValues[2] < _targetValues[2])                {                    _heatValues[2] += 0.1;                }                else                {                    _heatValues[2] -= 0.1;                }                //外部调温                if (_reserviorValues[2] < _targetValues[2])                {                    _reserviorValues[2] += 0.1;                }                else                {                    _reserviorValues[2] -= 0.1;                }            }            else            {                _timers[2].Stop();            }        }        /// <summary>        /// TC1-4的调温        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void Timer_Elapsed3(object sender, System.Timers.ElapsedEventArgs e)        {            if (Math.Abs(_heatValues[3] - _targetValues[3]) >= 0.2)            {                //内部调温                if (_heatValues[3] < _targetValues[3])                {                    _heatValues[3] += 0.1;                }                else                {                    _heatValues[3] -= 0.1;                }                //外部调温                if (_reserviorValues[3] < _targetValues[3])                {                    _reserviorValues[3] += 0.1;                }                else                {                    _reserviorValues[3] -= 0.1;                }            }            else            {                _timers[3].Stop();            }        }        /// <summary>        /// TC1-5的调温        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void Timer_Elapsed4(object sender, System.Timers.ElapsedEventArgs e)        {            if (Math.Abs(_heatValues[4] - _targetValues[4]) >= 0.2)            {                //内部调温                if (_heatValues[4] < _targetValues[4])                {                    _heatValues[4] += 0.1;                }                else                {                    _heatValues[4] -= 0.1;                }                //外部调温                if (_reserviorValues[4] < _targetValues[4])                {                    _reserviorValues[4] += 0.1;                }                else                {                    _reserviorValues[4] -= 0.1;                }            }            else            {                _timers[4].Stop();            }        }        protected override string MessageConvert(byte[] byt)        {            string str = "";            for(int i=0;i<byt.Length;i++)            {                byte item = byt[i];                if(dic.ContainsKey(item))                {                    str += dic[item];                }                else if(i==1)                {                    str += (item - 0x30).ToString("D2");                }                else if(i==3&&comdic.ContainsKey(item))                {                    str += comdic[item];                }                else                {                    str += item.ToString("X2");                }                str += " ";            }            return str;        }        protected override void ProcessMessageBuffer(byte[] data)        {            if (data[0] == 0x06 && data[2]==0x0D&&data.Length>7)            {                byte[] byt = new byte[data.Length - 3];                Array.Copy(data, 3, byt, 0, byt.Length);                ProcessNormalCommand(byt);            }            else if (data[0] == 0x01)            {                ProcessNormalCommand(data);            }        }        private void ProcessNormalCommand(byte[] data)        {            if (data[0] == 0x01 && data[data.Length-1]==0x0D)            {                if (data.Length == 7)                {                    ProcessReadCommand(data);                }                else if (data.Length > 7)                {                    ProcessSetCommand(data);                }            }        }        private void ProcessReadCommand(byte[] data)        {            switch(data[3])            {                case 0x31:                    ReadTargetValue(data);                     break;                case 0x32:                    ReadReserviorValue(data);                    break;                case 0x33:                    ReadHeatValue(data);                     break;                case 0x34:                    ReadAlarmValue(data);                    break;                case 0x39:                    ReadControlOperationValue(data);                    break;            }        }        private void ProcessSetCommand(byte[] data)        {            switch(data[3])            {                case 0x31:                    _targetValues[data[1] - ADD_FLAG - 1] = (data[4] - ADD_FLAG) * 10 + (data[5] - ADD_FLAG) + (data[6]-ADD_FLAG)*0.1;                    _timers[data[1] - ADD_FLAG -1].Start();                    break;                case 0x39:                    _controlOperation = data[7] - ADD_FLAG;                    if(_controlOperation == 0)                    {                        //停止调温                        _timers[data[1] - ADD_FLAG - 1].Stop();                    }                    else                    {                        //继续调温                        _timers[data[1] - ADD_FLAG - 1].Start();                    }                    break;            }            WriteConfirmData(data[1]);        }        /// <summary>        /// 回复确认        /// </summary>        /// <param name="id"></param>        private void WriteConfirmData(byte id)        {            byte[] confirm = new byte[3];            confirm[0] = 0x06;            confirm[1] = id;            confirm[2] = 0x0d;            WriteBuffer(confirm);        }        private void ReadTargetValue(byte[] data)        {            byte[] byt = new byte[12];            byt[0] = data[0];            byt[1] = data[1];            byt[2] = 0x02;            byt[3] = data[3];            byte[] decadeByte = GetDecadeBytes(_targetValues[data[1] - ADD_FLAG - 1]);            Array.Copy(decadeByte, 0, byt, 4, decadeByte.Length);            byt[5 + decadeByte.Length] = 0;            byt[6 + decadeByte.Length] = 0;            byt[11] = 0x0D;            WriteBuffer(byt);        }        private void ReadReserviorValue(byte[] data)        {             byte[] byt = new byte[12];            byt[0] = data[0];            byt[1] = data[1];            byt[2] = 0x02;            byt[3] = data[3];            byte[] decadeByte = GetDecadeBytes(_reserviorValues[data[1] - ADD_FLAG - 1]);            Array.Copy(decadeByte, 0, byt, 4, decadeByte.Length);            byt[5 + decadeByte.Length] = 0;            byt[6 + decadeByte.Length] = 0;            byt[11] = 0x0D;            WriteBuffer(byt);        }        private void ReadHeatValue(byte[] data)        {            byte[] byt = new byte[12];            byt[0] = data[0];            byt[1] = data[1];            byt[2] = 0x02;            byt[3] = data[3];            byte[] decadeByte = GetDecadeBytes(_heatValues[data[1] - ADD_FLAG - 1]);            Array.Copy(decadeByte, 0, byt, 4, decadeByte.Length);            byt[5 + decadeByte.Length] = 0;            byt[6 + decadeByte.Length] = 0;            byt[11] = 0x0D;            WriteBuffer(byt);        }        private void ReadControlOperationValue(byte[] data)        {            byte[] byt = new byte[12];            byt[0] = data[0];            byt[1] = data[1];            byt[2] = 0x02;            byt[3] = data[3];            byte[] decadeByte = GetKilloBytes(_controlOperation);            Array.Copy(decadeByte, 0, byt, 4, decadeByte.Length);            byt[5 + decadeByte.Length] = 0;            byt[6 + decadeByte.Length] = 0;            byt[11] = 0x0D;            WriteBuffer(byt);        }        private void ReadAlarmValue(byte[] data)        {            byte[] byt = new byte[8+alarm.Length];            byt[0] = data[0];            byt[1] = data[1];            byt[2] = 0x02;            byt[3] = data[3];            Array.Copy(alarm, 0, byt, 4, alarm.Length);            byt[5 + alarm.Length] = 0;            byt[6 + alarm.Length] = 0;            byt[7+alarm.Length] = 0x0D;            WriteBuffer(byt);        }        /// <summary>        /// 获取温度数组(10|1|0.1|0.01)        /// </summary>        /// <param name="temperature"></param>        /// <returns></returns>        private byte[] GetDecadeBytes(double temperature)        {            byte decade = GetSendByteData((byte)Math.Floor(temperature / 10));            byte unit = GetSendByteData((byte)Math.Floor(temperature % 10));            byte digital = GetSendByteData((byte)Math.Floor(temperature * 10 % 10));            return new byte[4] { decade, unit, digital, ADD_FLAG };        }        /// <summary>        /// 获取千级数组(1000|100|10|1)        /// </summary>        /// <param name="temperature"></param>        /// <returns></returns>        private byte[] GetKilloBytes(double temperature)        {            byte kilo = GetSendByteData((byte)Math.Floor(temperature / 1000));            byte hundred = GetSendByteData((byte)Math.Floor(temperature % 1000/100));            byte decade = GetSendByteData((byte)Math.Floor(temperature % 100 / 10));            byte unit = GetSendByteData((byte)Math.Floor(temperature % 10));            return new byte[4] { kilo, hundred, decade, unit };        }        /// <summary>        /// 获取发送位数据        /// </summary>        /// <param name="originalData"></param>        /// <returns></returns>        private byte GetSendByteData(byte originalData)        {            return (byte)(ADD_FLAG + originalData);        }                    }}
 |