HongHuVce.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. using Aitex.Core.Common;
  2. using Aitex.Core.RT.Log;
  3. using Aitex.Core.RT.SCCore;
  4. using Aitex.Core.Util;
  5. using MECF.Framework.Common.Communications;
  6. using MECF.Framework.Common.Equipment;
  7. using MECF.Framework.Common.SubstrateTrackings;
  8. using MECF.Framework.RT.ModuleLibrary.VceModules;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.IO.Ports;
  12. using System.Linq;
  13. using System.Text;
  14. using System.Text.RegularExpressions;
  15. using System.Threading.Tasks;
  16. using Venus_Core;
  17. namespace Venus_RT.Devices.VCE
  18. {
  19. //定义Vce动作
  20. public enum VceCommand
  21. {
  22. Home,
  23. DoorClose,
  24. DoorOpen,
  25. Goto,
  26. Load,
  27. UnLoad,
  28. Map,
  29. ReadMap,
  30. }
  31. public enum VceMessageHead
  32. {
  33. Action,
  34. Read,
  35. Set,
  36. Petrify
  37. }
  38. /// <summary>
  39. /// 泓浒Vce驱动 下发指令等
  40. /// </summary>
  41. public class HongHuVce : VceModuleBase
  42. {
  43. #region 私有变量
  44. private AsyncSerialPort _serialport;
  45. private string _portname;
  46. private string _newline = "\n\r";//终止符 0A 0D
  47. private object _locker = new object();
  48. private bool _IsAsciiMode;
  49. private LinkedList<string> _lstAsciiMsgs = new LinkedList<string>();
  50. private PeriodicJob _thread;
  51. private Regex _matchErrorCode = new Regex(@"(?<=_BKGERR )(.*)");
  52. private ModuleName _moduleName;
  53. private RState _status;
  54. private string _currentMsg;
  55. //后期补充
  56. private Dictionary<string, string> _ErrorCode2Reason = new Dictionary<string, string>()
  57. {
  58. {"A6","设备动作,但是发生异常" },
  59. {"A8","设备检查互锁,发现无法执行" },
  60. };
  61. //
  62. private Dictionary<VceCommand, string> _Command2Msg = new Dictionary<VceCommand, string>()
  63. {
  64. //Action
  65. {VceCommand.Home, "HM" },
  66. {VceCommand.Load, "LOAD" },
  67. {VceCommand.UnLoad, "UNLOAD"},
  68. {VceCommand.Map, "MP" },
  69. {VceCommand.Goto, "GC" },
  70. //Read
  71. {VceCommand.ReadMap, "MI" },
  72. //Set
  73. };
  74. private Dictionary<VceMessageHead, string> _Type2Head = new Dictionary<VceMessageHead, string>()
  75. {
  76. {VceMessageHead.Action, "A"},
  77. {VceMessageHead.Read, "R"},
  78. {VceMessageHead.Set, "S"},
  79. {VceMessageHead.Petrify, "P"},
  80. };
  81. #endregion
  82. #region 暴露变量
  83. public override bool IsConnected => _serialport.IsOpen();
  84. public override RState Status => _status;
  85. public override bool IsReady => _status == RState.Init || _status == RState.End;
  86. public override bool IsError => _status == RState.Failed || _status == RState.Timeout;
  87. public override bool IsInit => _status == RState.Init;
  88. private string[] _slotMap = new string[25];
  89. public string SlotMap
  90. {
  91. get
  92. {
  93. if (_slotMap == null)
  94. {
  95. _slotMap = new string[25];
  96. }
  97. for (int i = 0; i < _slotMap.Length; i++)
  98. {
  99. _slotMap[i] = ((int)WaferManager.Instance.GetWafer(_moduleName, i).Status).ToString();
  100. }
  101. return string.Join("", _slotMap);
  102. }
  103. }
  104. #endregion
  105. //传入slot数量
  106. public HongHuVce(int slot, ModuleName moduleName) : base(slot, moduleName)
  107. {
  108. _moduleName = moduleName;
  109. _IsAsciiMode = true;
  110. _portname = SC.GetStringValue("VCE.Port");
  111. _serialport = new AsyncSerialPort(_portname, 9600, 8, Parity.None, StopBits.One, _newline, _IsAsciiMode);
  112. _serialport.Open();
  113. _status = RState.Init;
  114. _serialport.OnDataChanged += onDataChange;
  115. _thread = new PeriodicJob(50, fnTimer, "VCE", true);
  116. }
  117. /// <summary>
  118. /// 对处理过的数据list进行处理
  119. /// 将每条数据进行解析
  120. /// </summary>
  121. /// <returns></returns>
  122. private bool fnTimer()
  123. {
  124. lock (_locker)
  125. {
  126. //采用ascii传输
  127. if (_IsAsciiMode)
  128. {
  129. //有数据尚未处理
  130. while (_lstAsciiMsgs.Count > 0)
  131. {
  132. string _needHandle = _lstAsciiMsgs.First.Value;
  133. HandleSingleMsg(_needHandle);
  134. _lstAsciiMsgs.RemoveFirst();
  135. }
  136. }
  137. //采用binary
  138. else
  139. {
  140. }
  141. }
  142. return true;
  143. }
  144. /// <summary>
  145. /// 处理单条信息的函数
  146. /// 1、判断结束 2、判断错误
  147. /// </summary>
  148. /// <param name="msg">需要处理的单条回复</param>
  149. private void HandleSingleMsg(string msg)
  150. {
  151. //
  152. if (!string.IsNullOrEmpty(msg))
  153. {
  154. //动作
  155. if (_currentMsg.Contains(",A,"))
  156. {
  157. switch (msg)
  158. {
  159. //设备收到 开始运行 目前状态在下发
  160. case "_RDY":
  161. break;
  162. //设备执行完毕
  163. case "_BKGRDY":
  164. _status = RState.End;
  165. break;
  166. //异常处理
  167. default:
  168. _status = RState.Failed;
  169. string reason = string.Empty;
  170. if (_matchErrorCode.IsMatch(msg))
  171. {
  172. //若是匹配
  173. //包含原因
  174. string errorcode = _matchErrorCode.Match(msg).Value;
  175. if (_ErrorCode2Reason.ContainsKey(errorcode))
  176. {
  177. reason = _ErrorCode2Reason[errorcode];
  178. }
  179. else
  180. {
  181. reason = "未找到相关Error Code";
  182. }
  183. }
  184. else
  185. {
  186. //若不匹配
  187. reason = "回复消息不符合标准格式";
  188. }
  189. LOG.Write(eEvent.ERR_DEVICE_INFO, _moduleName, reason);
  190. break;
  191. }
  192. }
  193. //读取
  194. if (_currentMsg.Contains(",R,") && msg.Contains(",X,"))
  195. {
  196. string readtype = msg.Split(',')[2];
  197. switch (readtype)
  198. {
  199. //处理wafer 信息为map数据
  200. case "MI":
  201. string waferinfo = "";
  202. string[] waferitems = msg.Split(',');
  203. for (int i = 3; i < waferitems.Length - 1; i++)
  204. {
  205. //从16进制字符转义回二进制
  206. string wafersingleinfo = Convert.ToString(Convert.ToInt32(waferitems[i], 16), 2);
  207. if (wafersingleinfo.Length < 4)
  208. wafersingleinfo = '0' * (4 - wafersingleinfo.Length) + wafersingleinfo;//补位
  209. waferinfo = wafersingleinfo + waferinfo;//添加到数据中
  210. }
  211. //请将数据按照反向槽位进行解析存入到wafermanager中
  212. for (int i= waferinfo.Length - 1; i > 0; i--)
  213. {
  214. if (waferinfo[i] == '1')
  215. {
  216. WaferManager.Instance.CreateWafer(_moduleName, waferinfo.Length - i, WaferStatus.Normal);
  217. }
  218. else
  219. {
  220. WaferManager.Instance.CreateWafer(_moduleName, waferinfo.Length - i, WaferStatus.Empty);
  221. }
  222. }
  223. break;
  224. }
  225. }
  226. }
  227. }
  228. /// <summary>
  229. /// 处理新到的数据
  230. /// 利用linkedlist处理拆包 粘包情况
  231. /// </summary>
  232. /// <param name="newline">新到数据</param>
  233. private void onDataChange(string oneLineMessage)
  234. {
  235. lock (_locker)
  236. {
  237. if (string.IsNullOrEmpty(_newline))//没有CR
  238. {
  239. _lstAsciiMsgs.AddLast(oneLineMessage);//将消息添加到最后
  240. return;
  241. }
  242. string[] array = oneLineMessage.Split(_newline.ToCharArray());//按照cr分开通讯数据
  243. foreach (string text in array)
  244. {
  245. if (!string.IsNullOrEmpty(text))
  246. {
  247. _lstAsciiMsgs.AddLast(text + _newline);//存进list中等待处理
  248. }
  249. }
  250. }
  251. }
  252. public string Option2Message(VceMessageHead msgtype, VceCommand name, string param = "")
  253. {
  254. if (string.IsNullOrEmpty(param))//含尾参
  255. return $"00,{_Type2Head[msgtype]},{_Command2Msg[name]}{_newline}";
  256. else//不含尾参 目前只允许一个
  257. return $"00,{_Type2Head[msgtype]},{_Command2Msg[name]},{param},{_newline}";
  258. }
  259. public override bool CloseDoor()
  260. {
  261. if (!CheckVceStatus())
  262. return false;
  263. _currentMsg = Option2Message(VceMessageHead.Action, VceCommand.DoorClose);
  264. _status = RState.Running;
  265. return _serialport.Write(_currentMsg);
  266. }
  267. public override bool HomeALL()
  268. {
  269. _currentMsg = Option2Message(VceMessageHead.Action, VceCommand.Home, "ALL");
  270. _status = RState.Running;
  271. return _serialport.Write(_currentMsg);
  272. }
  273. public override bool Home(string axis)
  274. {
  275. _currentMsg = Option2Message(VceMessageHead.Action, VceCommand.Home, axis);
  276. _status = RState.Running;
  277. return _serialport.Write(_currentMsg);
  278. }
  279. public override bool OpenDoor()
  280. {
  281. if (!CheckVceStatus())
  282. return false;
  283. _currentMsg = Option2Message(VceMessageHead.Action, VceCommand.DoorOpen);
  284. _status = RState.Running;
  285. return _serialport.Write(_currentMsg);
  286. }
  287. public override bool Load()
  288. {
  289. if (!CheckVceStatus())
  290. return false;
  291. _currentMsg = Option2Message(VceMessageHead.Action, VceCommand.Load);
  292. _status = RState.Running;
  293. return _serialport.Write(_currentMsg);
  294. }
  295. public override bool UnLoad()
  296. {
  297. if (!CheckVceStatus())
  298. return false;
  299. _currentMsg = Option2Message(VceMessageHead.Action, VceCommand.UnLoad);
  300. _status = RState.Running;
  301. return _serialport.Write(_currentMsg);
  302. }
  303. public override bool Map()
  304. {
  305. if (!CheckVceStatus())
  306. return false;
  307. _currentMsg = Option2Message(VceMessageHead.Action, VceCommand.Map);
  308. _status = RState.Running;
  309. return _serialport.Write(_currentMsg);
  310. }
  311. public override bool ReadMap()
  312. {
  313. if (!CheckVceStatus())
  314. return false;
  315. _currentMsg = Option2Message(VceMessageHead.Read, VceCommand.ReadMap);
  316. _status = RState.Running;
  317. return _serialport.Write(_currentMsg);
  318. }
  319. public override bool Goto(int Targetslot)
  320. {
  321. if (!CheckVceStatus())
  322. return false;
  323. _currentMsg = Option2Message(VceMessageHead.Action, VceCommand.Goto, Targetslot.ToString());
  324. _status = RState.Running;
  325. return _serialport.Write(_currentMsg);
  326. }
  327. }
  328. }