using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace YG.Device { public class DeviceSerial : DeviceList { public override event RunMessage Msg; public override event RunState rState; System.IO.Ports.SerialPort serialPort; private SendState sendState; int SendCount = 0; int leng = 0; byte[] bt; private bool _ison = false; /// /// 串口超时时间 /// public override bool IsOn { get { return _ison; } set { if (_ison != value) { if (rState != null) { rState.Invoke(this.DeviceName, value); _ison = value; } } } } public override void DeviceState() { Task.Factory.StartNew(() => { while (true) { System.Threading.Thread.Sleep(1000); try { if (serialPort.IsOpen) { IsOn = true; } else { IsOn = false; serialPort.Open(); } } catch { IsOn = false; serialPort.Open(); } finally { } } }); } /// /// /// /// 串口名称 /// 波特率 public DeviceSerial(string portname, int buard, int outtime = 2500) { serialPort = new System.IO.Ports.SerialPort(portname, buard); serialPort.DataReceived += SerialPort_DataReceived; serialPort.ReadTimeout = 100; serialPort.WriteTimeout = 100; timeout = outtime; this.DeviceName = portname; } public override void DeviceCheck() { System.Threading.Thread.Sleep(timeout); while (sendState == SendState.SendNoReceive) { serialPort.Write(SendValue.ToString()); base.DeviceSend(SendValue); //一般情况下在延迟一段时间之后, 如果没有收到串口反馈的指令,那么下次发送也很难再接受到反馈, 所以下边默认延迟1500毫秒 System.Threading.Thread.Sleep(1500); SendCount++; if (SendCount > 3) { if (Msg != null) { Msg.Invoke(this.DeviceName, SendValue.Replace("\r", "").Replace("\n", ""), "连续发送三次数据没有得到回应"); sendState = SendState.StartSend; } } } } public override void DeviceClose() { if (serialPort.IsOpen) serialPort.Close(); base.DeviceClose(); } public override void DeviceInit() { sendState = SendState.StartSend; IsOn = true; IsOn = false; } public override void DeviceOpen() { try { if (!serialPort.IsOpen) serialPort.Open(); } catch { YG.Log.Instance.WriteLogAdd(serialPort.PortName + "打开失败"); System.Windows.Forms.MessageBox.Show(serialPort.PortName + "打开失败"); } base.DeviceOpen(); } public override void DeviceSend(object ob) { try { SendCount = 0; SendValue = ob.ToString(); serialPort.Write(ob.ToString()); base.DeviceSend(ob); sendState = SendState.SendNoReceive; Task.Factory.StartNew(() => { if (timeout > 0) { // DeviceCheck(); } }); } catch (Exception ex) { Log.Instance.WriteLogAdd("串口打开失败:" + ex.Message); } } private void SerialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { System.Threading.Thread.Sleep(50); sendState = SendState.Received; if (Msg != null) { sendState = SendState.Received; // if (Msg != null) { leng = serialPort.BytesToRead; bt = new byte[leng]; serialPort.Read(bt, 0, bt.Length); Task.Factory.StartNew(() => { Msg?.Invoke(this.DeviceName, SendValue.Replace("\r", "").Replace("\n", ""), Encoding.Default.GetString(bt)); }); YG.Log.Instance.WriteLogAdd(string.Format("{0}:接受到信息{1}", serialPort.PortName, Encoding.Default.GetString(bt))); } // Msg.Invoke(this.DeviceName, serialPort.ReadLine()); } } } }