| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 |
- using System;
- using System.Collections.Generic;
- using System.IO.Ports;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- using Core.ONH.Collection.Send;
- namespace Core.ONH.Collection.comm
- {
- public delegate void ReceiveDataHandler(object sender, ONHData data, string Message);
- public class SerialPortEntity : SerialPort
- {
- private CancellationTokenSource ct = new CancellationTokenSource();
- private Task task;
- public string StrBaudRate
- {
- get { return BaudRate.ToString(); }
- set
- {
- var iBaudRate = 0;
- if (!int.TryParse(value, out iBaudRate))
- iBaudRate = 2400;
- BaudRate = iBaudRate;
- }
- }
- public string StrDataBits
- {
- get { return DataBits.ToString(); }
- set
- {
- var iDataBits = 0;
- if (!int.TryParse(value, out iDataBits))
- iDataBits = 8;
- DataBits = iDataBits;
- }
- }
- public string StrParity
- {
- get
- {
- switch (Parity)
- {
- case Parity.None:
- return "NONE";
- case Parity.Even:
- return "EVEN";
- case Parity.Mark:
- return "MARK";
- case Parity.Odd:
- return "ODD";
- case Parity.Space:
- return "SPACE";
- default:
- return "EVEN";
- ;
- }
- }
- set
- {
- switch (value)
- {
- case "EVEN":
- Parity = Parity.Even;
- break;
- case "MARK":
- Parity = Parity.Mark;
- break;
- case "NONE":
- Parity = Parity.None;
- break;
- case "ODD":
- Parity = Parity.Odd;
- break;
- case "SPACE":
- Parity = Parity.Space;
- break;
- default:
- Parity = Parity.Even;
- break;
- }
- }
- }
- public string StrStopBits
- {
- get
- {
- switch (StopBits)
- {
- case StopBits.None:
- return "NONE";
- case StopBits.One:
- return "ONE";
- case StopBits.OnePointFive:
- return "ONEPOINTFIVE";
- case StopBits.Two:
- return "TWO";
- default:
- return "ONE";
- ;
- }
- }
- set
- {
- switch (value)
- {
- case "NONE":
- StopBits = StopBits.None;
- break;
- case "ONE":
- StopBits = StopBits.One;
- break;
- case "ONEPOINTFIVE":
- StopBits = StopBits.OnePointFive;
- break;
- case "TWO":
- StopBits = StopBits.Two;
- break;
- default:
- StopBits = StopBits.One;
- break;
- }
- }
- }
- public string DeviceName { get; set; }
- public event ReceiveDataHandler ReceiveData;
- /// <summary>
- /// 触发试样编号值改变事件
- /// </summary>
- /// <param name="e"></param>
- protected virtual void OnReceiveData(ONHData data, string message)
- {
- var handler = ReceiveData;
- if (handler != null)
- new Task(() => { handler(this, data, DeviceName + " " + message); }).Start();
- // handler(this, data, DeviceName + " " + message);
- }
- public void SendDataWithReplay(string data)
- {
- var byteArray = Encoding.Default.GetBytes(data);
- //组成特定帧
- var fullyByte = CoreProtocol.Framing(byteArray); // 组成符合自定义协议的数据帧
- Open();
- Thread.Sleep(200);
- try
- {
- Write(fullyByte, 0, fullyByte.Length);
- var ts1 = new TimeSpan(DateTime.Now.Ticks);
- var ReadData = new List<byte>();
- var OverTime = false;
- var RightReplay = false;
- List<byte> Data = null;
- while (!OverTime && !RightReplay)
- if (BytesToRead > 0)
- {
- var Datas = new byte[BytesToRead];
- Read(Datas, 0, Datas.Length);
- ReadData = ReadData.Concat(Datas).ToList();
- if (AnalaysData(ReadData, out Data) == DeframeType.RightFrame)
- RightReplay = true;
- }
- else
- {
- var ts2 = new TimeSpan(DateTime.Now.Ticks);
- var ts3 = ts1.Subtract(ts2).Duration();
- if (ts3.TotalSeconds > 10) OverTime = true;
- }
- if (OverTime)
- throw new Exception("发送超时");
- if (Data!=null && Data.Count>0 && Data[0] == 0x00)
- {
- }
- else
- {
- throw new Exception("通讯异常, 请重新发送");
- }
- }
- finally
- {
- if (IsOpen)
- Close();
- }
- }
- public void Start()
- {
- try
- {
- Open();
- OnReceiveData(null,
- string.Format("打开串口[{0}--{1} {2} {3} {4}]成功!", PortName, StrBaudRate, StrParity, StrDataBits,
- StrStopBits));
- ct = new CancellationTokenSource();
- task = new Task(ReceiveTask, ct.Token);
- task.Start();
- OnReceiveData(null, "开始监听数据");
- }
- catch (Exception ex)
- {
- OnReceiveData(null, ex.Message);
- }
- }
- public void ReceiveTask()
- {
- var ReceiveData = new List<byte>();
- while (!ct.IsCancellationRequested)
- try
- {
- if (!IsOpen) continue;
- if (BytesToRead > 0)
- {
- //等待100毫秒 等足够帧过来
- Thread.Sleep(100);
- var Datas = new byte[BytesToRead];
- Read(Datas, 0, Datas.Length);
- ReceiveData = ReceiveData.Concat(Datas).ToList();
- List<byte> Data;
- DeframeType Result = AnalaysData(ReceiveData, out Data);
- if(Result!= DeframeType.LengthLess) ReceiveData.Clear();
- if (Result == DeframeType.RightFrame)
- {
- //回应0x00 收到正确数据
- var replay = CoreProtocol.Framing(new byte[] { 0x00 });
- Write(replay, 0, replay.Length);
- ONHData ONHData = new ONHData();
- String StrData = Encoding.Default.GetString(Data.ToArray());
- ONHDataHelper.AnalysisString(StrData, out ONHData);
- ONHData.DeviceName = DeviceName;
- OnReceiveData(ONHData, "成功接受数据:" + StrData);
- }
- if (Result == DeframeType.WrongFrame)
- {
- //回应0x01 收到数据异常
- var replay1 = CoreProtocol.Framing(new byte[] { 0x01 });
- Write(replay1, 0, replay1.Length);
- OnReceiveData(null, "数据丢失,请重新发送 ");
- }
- }
- }
- catch (Exception)
- {
- }
- OnReceiveData(null, "停止监听数据");
- }
- private DeframeType AnalaysData(List<byte> ReceiveData, out List<byte> Data)
- {
- ReceiveData = ReceiveData.SkipWhile(p => p != 0x68).ToList();
- DeframeType Result = CoreProtocol.Deframe(ReceiveData, out Data);
- if (Result == DeframeType.WrongHead)
- {
- //帧头 不正确 去掉第一字节 递归
- ReceiveData.RemoveAt(0);
- return AnalaysData(ReceiveData, out Data);
- }
- return Result;
- }
- public void Stop()
- {
- try
- {
- ct.Cancel();
- task.Wait();
- }
- catch (Exception ex)
- {
- // ignored
- }
- Thread.Sleep(100);
- if (IsOpen)
- {
- Close();
- OnReceiveData(null, string.Format("关闭串口[{0}]成功!", PortName));
- }
- }
- }
- }
|