SerialPortEntity.cs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO.Ports;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8. using Core.ONH.Collection.Send;
  9. namespace Core.ONH.Collection.comm
  10. {
  11. public delegate void ReceiveDataHandler(object sender, ONHData data, string Message);
  12. public class SerialPortEntity : SerialPort
  13. {
  14. private CancellationTokenSource ct = new CancellationTokenSource();
  15. private Task task;
  16. public string StrBaudRate
  17. {
  18. get { return BaudRate.ToString(); }
  19. set
  20. {
  21. var iBaudRate = 0;
  22. if (!int.TryParse(value, out iBaudRate))
  23. iBaudRate = 2400;
  24. BaudRate = iBaudRate;
  25. }
  26. }
  27. public string StrDataBits
  28. {
  29. get { return DataBits.ToString(); }
  30. set
  31. {
  32. var iDataBits = 0;
  33. if (!int.TryParse(value, out iDataBits))
  34. iDataBits = 8;
  35. DataBits = iDataBits;
  36. }
  37. }
  38. public string StrParity
  39. {
  40. get
  41. {
  42. switch (Parity)
  43. {
  44. case Parity.None:
  45. return "NONE";
  46. case Parity.Even:
  47. return "EVEN";
  48. case Parity.Mark:
  49. return "MARK";
  50. case Parity.Odd:
  51. return "ODD";
  52. case Parity.Space:
  53. return "SPACE";
  54. default:
  55. return "EVEN";
  56. ;
  57. }
  58. }
  59. set
  60. {
  61. switch (value)
  62. {
  63. case "EVEN":
  64. Parity = Parity.Even;
  65. break;
  66. case "MARK":
  67. Parity = Parity.Mark;
  68. break;
  69. case "NONE":
  70. Parity = Parity.None;
  71. break;
  72. case "ODD":
  73. Parity = Parity.Odd;
  74. break;
  75. case "SPACE":
  76. Parity = Parity.Space;
  77. break;
  78. default:
  79. Parity = Parity.Even;
  80. break;
  81. }
  82. }
  83. }
  84. public string StrStopBits
  85. {
  86. get
  87. {
  88. switch (StopBits)
  89. {
  90. case StopBits.None:
  91. return "NONE";
  92. case StopBits.One:
  93. return "ONE";
  94. case StopBits.OnePointFive:
  95. return "ONEPOINTFIVE";
  96. case StopBits.Two:
  97. return "TWO";
  98. default:
  99. return "ONE";
  100. ;
  101. }
  102. }
  103. set
  104. {
  105. switch (value)
  106. {
  107. case "NONE":
  108. StopBits = StopBits.None;
  109. break;
  110. case "ONE":
  111. StopBits = StopBits.One;
  112. break;
  113. case "ONEPOINTFIVE":
  114. StopBits = StopBits.OnePointFive;
  115. break;
  116. case "TWO":
  117. StopBits = StopBits.Two;
  118. break;
  119. default:
  120. StopBits = StopBits.One;
  121. break;
  122. }
  123. }
  124. }
  125. public string DeviceName { get; set; }
  126. public event ReceiveDataHandler ReceiveData;
  127. /// <summary>
  128. /// 触发试样编号值改变事件
  129. /// </summary>
  130. /// <param name="e"></param>
  131. protected virtual void OnReceiveData(ONHData data, string message)
  132. {
  133. var handler = ReceiveData;
  134. if (handler != null)
  135. new Task(() => { handler(this, data, DeviceName + " " + message); }).Start();
  136. // handler(this, data, DeviceName + " " + message);
  137. }
  138. public void SendDataWithReplay(string data)
  139. {
  140. var byteArray = Encoding.Default.GetBytes(data);
  141. //组成特定帧
  142. var fullyByte = CoreProtocol.Framing(byteArray); // 组成符合自定义协议的数据帧
  143. Open();
  144. Thread.Sleep(200);
  145. try
  146. {
  147. Write(fullyByte, 0, fullyByte.Length);
  148. var ts1 = new TimeSpan(DateTime.Now.Ticks);
  149. var ReadData = new List<byte>();
  150. var OverTime = false;
  151. var RightReplay = false;
  152. List<byte> Data = null;
  153. while (!OverTime && !RightReplay)
  154. if (BytesToRead > 0)
  155. {
  156. var Datas = new byte[BytesToRead];
  157. Read(Datas, 0, Datas.Length);
  158. ReadData = ReadData.Concat(Datas).ToList();
  159. if (AnalaysData(ReadData, out Data) == DeframeType.RightFrame)
  160. RightReplay = true;
  161. }
  162. else
  163. {
  164. var ts2 = new TimeSpan(DateTime.Now.Ticks);
  165. var ts3 = ts1.Subtract(ts2).Duration();
  166. if (ts3.TotalSeconds > 10) OverTime = true;
  167. }
  168. if (OverTime)
  169. throw new Exception("发送超时");
  170. if (Data!=null && Data.Count>0 && Data[0] == 0x00)
  171. {
  172. }
  173. else
  174. {
  175. throw new Exception("通讯异常, 请重新发送");
  176. }
  177. }
  178. finally
  179. {
  180. if (IsOpen)
  181. Close();
  182. }
  183. }
  184. public void Start()
  185. {
  186. try
  187. {
  188. Open();
  189. OnReceiveData(null,
  190. string.Format("打开串口[{0}--{1} {2} {3} {4}]成功!", PortName, StrBaudRate, StrParity, StrDataBits,
  191. StrStopBits));
  192. ct = new CancellationTokenSource();
  193. task = new Task(ReceiveTask, ct.Token);
  194. task.Start();
  195. OnReceiveData(null, "开始监听数据");
  196. }
  197. catch (Exception ex)
  198. {
  199. OnReceiveData(null, ex.Message);
  200. }
  201. }
  202. public void ReceiveTask()
  203. {
  204. var ReceiveData = new List<byte>();
  205. while (!ct.IsCancellationRequested)
  206. try
  207. {
  208. if (!IsOpen) continue;
  209. if (BytesToRead > 0)
  210. {
  211. //等待100毫秒 等足够帧过来
  212. Thread.Sleep(100);
  213. var Datas = new byte[BytesToRead];
  214. Read(Datas, 0, Datas.Length);
  215. ReceiveData = ReceiveData.Concat(Datas).ToList();
  216. List<byte> Data;
  217. DeframeType Result = AnalaysData(ReceiveData, out Data);
  218. if(Result!= DeframeType.LengthLess) ReceiveData.Clear();
  219. if (Result == DeframeType.RightFrame)
  220. {
  221. //回应0x00 收到正确数据
  222. var replay = CoreProtocol.Framing(new byte[] { 0x00 });
  223. Write(replay, 0, replay.Length);
  224. ONHData ONHData = new ONHData();
  225. String StrData = Encoding.Default.GetString(Data.ToArray());
  226. ONHDataHelper.AnalysisString(StrData, out ONHData);
  227. ONHData.DeviceName = DeviceName;
  228. OnReceiveData(ONHData, "成功接受数据:" + StrData);
  229. }
  230. if (Result == DeframeType.WrongFrame)
  231. {
  232. //回应0x01 收到数据异常
  233. var replay1 = CoreProtocol.Framing(new byte[] { 0x01 });
  234. Write(replay1, 0, replay1.Length);
  235. OnReceiveData(null, "数据丢失,请重新发送 ");
  236. }
  237. }
  238. }
  239. catch (Exception)
  240. {
  241. }
  242. OnReceiveData(null, "停止监听数据");
  243. }
  244. private DeframeType AnalaysData(List<byte> ReceiveData, out List<byte> Data)
  245. {
  246. ReceiveData = ReceiveData.SkipWhile(p => p != 0x68).ToList();
  247. DeframeType Result = CoreProtocol.Deframe(ReceiveData, out Data);
  248. if (Result == DeframeType.WrongHead)
  249. {
  250. //帧头 不正确 去掉第一字节 递归
  251. ReceiveData.RemoveAt(0);
  252. return AnalaysData(ReceiveData, out Data);
  253. }
  254. return Result;
  255. }
  256. public void Stop()
  257. {
  258. try
  259. {
  260. ct.Cancel();
  261. task.Wait();
  262. }
  263. catch (Exception ex)
  264. {
  265. // ignored
  266. }
  267. Thread.Sleep(100);
  268. if (IsOpen)
  269. {
  270. Close();
  271. OnReceiveData(null, string.Format("关闭串口[{0}]成功!", PortName));
  272. }
  273. }
  274. }
  275. }