| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 | using Aitex.Core.RT.Log;using Aitex.Core.RT.SCCore;using Aitex.Core.Util;using MECF.Framework.Common.Communications;using MECF.Framework.Common.Equipment;using MECF.Framework.Common.SubstrateTrackings;using MECF.Framework.RT.ModuleLibrary.VceModules;using System;using System.Collections.Generic;using System.IO.Ports;using System.Linq;using System.Text;using System.Text.RegularExpressions;using System.Threading.Tasks;using Venus_Core;namespace Venus_RT.Devices.PreAligner{    public class HongHuVPA : IPreAlign    {        private AsyncSerialPort _serialport;//串口        private string _newLine = "\r";//结束符号        private object _locker = new object();//锁变量        private bool _IsAsciiMode = true;        private PeriodicJob _thread;        //private string _CurrentMsg;        private RState _state;        private Regex _catchErrorCode = new Regex(@"(?<=_ERR )(.*)");        private LinkedList<string> _lstMessage = new LinkedList<string>();        private ModuleName _module;        private enum VPAAction        {            Home,            Align,            AlignWithAngle,            Reset,            Scan,        }        private Dictionary<int, string> _ErrorCode2Msg = new Dictionary<int, string>()        {            { 16 , "" },        };        private Dictionary<VPAAction, string> _Command2Msg = new Dictionary<VPAAction, string>()        {            //Action            { VPAAction.Align         , "ALGN" },//旋转到预设的站点方向            { VPAAction.AlignWithAngle, "MOVT REL" },//旋转到指定的角度            { VPAAction.Home          , "HOME" },//Home 初始化时 error时用            { VPAAction.Reset         , "RSET" },//重置 error时用            { VPAAction.Scan          , "SCAN" },//扫描整个Wafer参数            //Read            //{ "" , "RQCD" },            //{ "" , "RQCCDPOS" },            //{ "" , "RQID" },            //{ "" , "RQPS" },            //Set            //{ "" , "" },            //Welding            //{ "" , "SVCD" },        };        public ModuleName Module => _module;        public bool IsConnect => _serialport.IsOpen();        public RState Status => _state;//状态        public bool IsError => _state == RState.Failed || _state == RState.Timeout;        public HongHuVPA(ModuleName module)        {            _module = module;            string port = "COM160";            _serialport = new AsyncSerialPort(port, 9600, 8, Parity.None, StopBits.One, _newLine, _IsAsciiMode);            WaferManager.Instance.SubscribeLocation(_module, 1);            _serialport.Open();            _serialport.OnDataChanged += OnReceiveData;            _state = RState.Init;            _thread = new PeriodicJob(50, OnTimer, "OnTimer->VPA");            _thread.Start();        }        //收到新消息时的处理        private void OnReceiveData(string obj)        {            lock (_locker)            {                if (string.IsNullOrEmpty(_newLine))//没有CR                {                    _lstMessage.AddLast(obj);//将消息添加到最后                    return;                }                string[] array = obj.Split(_newLine.ToCharArray());//按照cr分开通讯数据                foreach (string text in array)                {                    if (!string.IsNullOrEmpty(text))                    {                        _lstMessage.AddLast(text + _newLine);//存进list中等待处理                    }                }            }        }        //定时器处理新信息为状态        private bool OnTimer()        {            //线程锁            lock (_locker)            {                //采用ascii码模式处理                if (_IsAsciiMode)                {                    //存在尚未处理的信息                    while (_lstMessage.Count > 0)                    {                        //获取头上的数据                        string handlemsg = _lstMessage.First.Value;                        Handlemessage(handlemsg);                        _lstMessage.RemoveFirst();                    }                }                //采用binary模式处理                else                {                }            }            return true;        }        //处理单条信息        private void Handlemessage(string handlemsg)        {            //需要按类型进行处理 Action需要将其error            bool IsAction = true;            handlemsg = handlemsg.Trim();            if (IsAction)            {                switch (handlemsg)                {                    //正确执行                    case "_RDY":                        _state = RState.End;                        break;                    //返回                    default:                        _state = RState.Failed;                        //分两种 1、不按格式的未知错误 2、有错误码的                        if (_catchErrorCode.IsMatch(handlemsg))                        {                            int errorcode = Convert.ToInt32(_catchErrorCode.Match(handlemsg).Value);                            if (_ErrorCode2Msg.ContainsKey(errorcode))                            {                                LOG.Write(eEvent.ERR_DEVICE_INFO, Module, _ErrorCode2Msg[errorcode]);                            }                            else                            {                                LOG.Write(eEvent.ERR_DEVICE_INFO, Module, $"未知错误码{errorcode}");                            }                        }                        else                        {                            LOG.Write(eEvent.ERR_DEVICE_INFO, Module, "未收录相关错误");                        }                        break;                }            }        }        //发送消息        private bool SendMessage(string msg, params string[] args)        {            _state = RState.Running;            if (args.Length > 0)//含参            {                foreach (string arg in args)                    msg = msg + " " + arg;                LOG.WriteSingeLine(eEvent.EV_DEVICE_INFO, _module, $"Send Command to HongHu VPA: {msg}");                return _serialport.Write(msg + _newLine);            }            else//空参            {                LOG.WriteSingeLine(eEvent.EV_DEVICE_INFO, _module, $"Send Command to HongHu VPA: {msg}");                return _serialport.Write(msg + _newLine);            }        }        public bool Home()        {            return SendMessage(_Command2Msg[VPAAction.Home]);        }        public bool Align()        {            if (!CanSendCommand())                return false;            return SendMessage(_Command2Msg[VPAAction.Align]);        }        public bool AlignWithAngle(float angle)        {            if (!CanSendCommand())                return false;            int ang = (int)Math.Floor(angle);//不能用Convert.toInt32("angle") 其遵守四舍五入 此处需向上取整            return SendMessage(_Command2Msg[VPAAction.AlignWithAngle], ang.ToString());        }        public bool ReSet()        {            if (!IsError)                return false;            return SendMessage(_Command2Msg[VPAAction.Reset]);        }        public bool SCAN()        {            if (!CanSendCommand())                return false;            return SendMessage(_Command2Msg[VPAAction.Scan]);        }        public bool CanSendCommand()        {            if (Status == RState.Init)            {                LOG.Write(eEvent.ERR_DEVICE_INFO, _module, "VPA is not homed, please home first.");                return false;            }            else if (Status == RState.Running)            {                LOG.Write(eEvent.ERR_DEVICE_INFO, _module, "VPA is busy, please wait a minute");                return false;            }            else if (Status == RState.Failed || Status == RState.Timeout)            {                LOG.Write(eEvent.ERR_DEVICE_INFO, _module, "VPA has a error, please check and fix the hardware issue and home it");                return false;            }            return true;        }    }}
 |