从库中的串口获取 return 值的最佳方法
Best way to return value from serial port within a library
我正在尝试通过串口发送和接收数据,我可以正常从DataReceived事件中获取数据。
现在,我做了一个库,它被开发用于通过串口发送和接收数据。我不知道如何通过两种不同的方法发送命令和检索值。
这让我很困惑,请帮助我!
static void Main(string[] args)
{
FXReader reader = new FXReader();
reader.ComPort = port;
reader.Connect();
Console.WriteLine(reader.SetPortPower(1));
Console.ReadLine();
Console.WriteLine(reader.GetPortStatus(1));
Console.ReadLine();
}
public class FXReader : IDisposable
{
private SerialPort rs232 = null;
public string ComPort
{
get { return rs232.PortName; }
set { rs232.PortName = value; }
}
public bool IsConnected
{
get { return rs232.IsOpen; }
}
public F520Reader()
{
rs232 = new SerialPort();
rs232.BaudRate = 115200;
rs232.Parity = Parity.None;
rs232.DataBits = 8;
rs232.StopBits = StopBits.One;
rs232.DataReceived += new SerialDataReceivedEventHandler(rs232_DataReceived);
}
public void Connect()
{
rs232.Open();
}
public void Disconnect()
{
rs232.Close();
}
public int GetPortPower(int port)
{
if (rs232.IsOpen)
{
byte[] command = { 0x5A, 0x00, 0x19, 0x00, 0x01, 0xFF, 0xFF, 0x7E };
rs232.Write(command, 0, command.Length);
//How can i get value from the event of "rs232_DataReceived"
return powervalue;
}
}
public int GetPortStatus(int port)
{
if (rs232.IsOpen)
{
byte[] command = { 0x5A, 0x00, 0x19, 0x00, 0x01, 0xFF, 0xFF, 0x7E };
rs232.Write(command, 0, command.Length);
//How can i get value from the event of "rs232_DataReceived"
return statusvalue;
}
}
void rs232_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
System.Threading.Thread.Sleep(50);
if (rs232.BytesToRead > 0)
{
byte[] recvBuffer = new byte[1024];
int recvLength = rs232.Read(recvBuffer, 0, recvBuffer.Length);
Array.Resize(ref recvBuffer, recvLength);
PharseResponse(recvBuffer);
}
}
private void PharseResponse(byte[] buffer)
{
if (buffer[0] == 0x5A && buffer[buffer.Length - 1] == 0x7E)
{
#region Response for Get Port Power
if (buffer[1] == 0x01 && buffer[2] == 0x13)
{
//How can I return value by the method of "GetPortPower"
return buffer[7];
}
#endregion
#region Response for Get Port Status
if (buffer[1] == 0x01 && buffer[2] == 0x14)
{
//How can I return value by the method of "GetPortStatus"
return buffer[7];
}
#endregion
}
}
#region IDisposable Members
public void Dispose()
{
if (rs232.IsOpen)
rs232.Close();
rs232.Dispose();
}
#endregion
}
这肯定不是"best way"。您不会从使用 DataReceived 事件中获得任何好处。它在事件驱动的应用程序中很有用,例如 GUI 应用程序。但不是在这样的应用程序中,您必须先得到响应才能继续您的程序。
所以根本不要使用它,而是直接调用 Read() 方法。您的程序将阻塞,直到设备发回某些内容。
这也将帮助您编写正确的代码,目前还不正确。从串行端口读取通常只产生一两个字节。 Read() 的 return 值告诉您得到了多少。在获得 complete 之前,您无法解析响应。从您当前的代码中,"complete" 的样子不是很明显,但您需要至少接收 8 个字节,然后 PharseResponse() 方法才会因 IndexOutOfRangeException 而停止崩溃。串行协议通常使用特定的字节值来指示响应的结束。
我正在尝试通过串口发送和接收数据,我可以正常从DataReceived事件中获取数据。
现在,我做了一个库,它被开发用于通过串口发送和接收数据。我不知道如何通过两种不同的方法发送命令和检索值。
这让我很困惑,请帮助我!
static void Main(string[] args)
{
FXReader reader = new FXReader();
reader.ComPort = port;
reader.Connect();
Console.WriteLine(reader.SetPortPower(1));
Console.ReadLine();
Console.WriteLine(reader.GetPortStatus(1));
Console.ReadLine();
}
public class FXReader : IDisposable
{
private SerialPort rs232 = null;
public string ComPort
{
get { return rs232.PortName; }
set { rs232.PortName = value; }
}
public bool IsConnected
{
get { return rs232.IsOpen; }
}
public F520Reader()
{
rs232 = new SerialPort();
rs232.BaudRate = 115200;
rs232.Parity = Parity.None;
rs232.DataBits = 8;
rs232.StopBits = StopBits.One;
rs232.DataReceived += new SerialDataReceivedEventHandler(rs232_DataReceived);
}
public void Connect()
{
rs232.Open();
}
public void Disconnect()
{
rs232.Close();
}
public int GetPortPower(int port)
{
if (rs232.IsOpen)
{
byte[] command = { 0x5A, 0x00, 0x19, 0x00, 0x01, 0xFF, 0xFF, 0x7E };
rs232.Write(command, 0, command.Length);
//How can i get value from the event of "rs232_DataReceived"
return powervalue;
}
}
public int GetPortStatus(int port)
{
if (rs232.IsOpen)
{
byte[] command = { 0x5A, 0x00, 0x19, 0x00, 0x01, 0xFF, 0xFF, 0x7E };
rs232.Write(command, 0, command.Length);
//How can i get value from the event of "rs232_DataReceived"
return statusvalue;
}
}
void rs232_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
System.Threading.Thread.Sleep(50);
if (rs232.BytesToRead > 0)
{
byte[] recvBuffer = new byte[1024];
int recvLength = rs232.Read(recvBuffer, 0, recvBuffer.Length);
Array.Resize(ref recvBuffer, recvLength);
PharseResponse(recvBuffer);
}
}
private void PharseResponse(byte[] buffer)
{
if (buffer[0] == 0x5A && buffer[buffer.Length - 1] == 0x7E)
{
#region Response for Get Port Power
if (buffer[1] == 0x01 && buffer[2] == 0x13)
{
//How can I return value by the method of "GetPortPower"
return buffer[7];
}
#endregion
#region Response for Get Port Status
if (buffer[1] == 0x01 && buffer[2] == 0x14)
{
//How can I return value by the method of "GetPortStatus"
return buffer[7];
}
#endregion
}
}
#region IDisposable Members
public void Dispose()
{
if (rs232.IsOpen)
rs232.Close();
rs232.Dispose();
}
#endregion
}
这肯定不是"best way"。您不会从使用 DataReceived 事件中获得任何好处。它在事件驱动的应用程序中很有用,例如 GUI 应用程序。但不是在这样的应用程序中,您必须先得到响应才能继续您的程序。
所以根本不要使用它,而是直接调用 Read() 方法。您的程序将阻塞,直到设备发回某些内容。
这也将帮助您编写正确的代码,目前还不正确。从串行端口读取通常只产生一两个字节。 Read() 的 return 值告诉您得到了多少。在获得 complete 之前,您无法解析响应。从您当前的代码中,"complete" 的样子不是很明显,但您需要至少接收 8 个字节,然后 PharseResponse() 方法才会因 IndexOutOfRangeException 而停止崩溃。串行协议通常使用特定的字节值来指示响应的结束。