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());
}
}
}
}