HongHuVce.cs 11 KB

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