我是C#开发的新手。我正在通过阅读我的串行端口使用以下代码:
var mySerialPort = new SerialPort("Com3");
mySerialPort.BaudRate = 9600;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.Open();
mySerialPort.DataReceived += new
SerialDataReceivedEventHandler(DataReceivedHandler);
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string tmp = sp.ReadLine();
}
问题在于,tmp始终为空。可能是它试图找到CR LF。 我的串行端口设备发送了以下行:
STX( 0.000CRETX
我是否可以更改尝试读取readline的最后一个字符的选项? 因此,每次读取ETX都返回我的字符串。
答案 0 :(得分:0)
ReadLine的行为非常严格。
例如,当我从Arduino串行端口读取时,我倾向于使用它:
byte[] buffer = new byte[sp.BytesToRead];
sp.Read(buffer, 0, buffer.Length);
您还可以将读数拆分到其自己的线程中,该线程仅读取字节,直到其具有完整的行为止,然后将其排队以供主线程处理。最有可能对您的应用程序造成过大杀伤力。
答案 1 :(得分:0)
我不建议这样做,但是您应该可以使用此属性进行设置。
获取或设置用于解释对ReadLine()和WriteLine(String)方法的调用结束的值。
相反,最好使用Read()
读取字节数组,并将数据格式检查为@omglolbah的答案。
这是您的决定,因此请您自担风险。
答案 2 :(得分:0)
ReadLine和.NET SerialPort的其他部分一样都损坏。 请查看下面的链接以获取正确的实现:
https://www.sparxeng.com/blog/software/must-use-net-system-io-ports-serialport#comment-9986 https://www.sparxeng.com/blog/software/reading-lines-serial-port
基本上可以归结为:
byte[] buffer = new byte[blockLimit];
Action kickoffRead = null;
kickoffRead = delegate {
port.BaseStream.BeginRead(buffer, 0, buffer.Length, delegate (IAsyncResult ar) {
try {
int actualLength = port.BaseStream.EndRead(ar);
byte[] received = new byte[actualLength];
Buffer.BlockCopy(buffer, 0, received, 0, actualLength);
raiseAppSerialDataEvent(received);
}
catch (IOException exc) {
handleAppSerialError(exc);
}
kickoffRead();
}, null);
};
kickoffRead();
答案 3 :(得分:0)
我认为您很亲近,您只需要意识到DataReceived
事件在某种程度上随机触发。它可能在消息中间触发,而您只能得到消息的一半。因此,您必须构建自己的字符串,并使用ETX字符表示您已收到整个消息。请勿混淆NewLine
属性,在下面的示例中使用ReadExisting
时就不需要这样做。
char ETX = (char)4;
StringBuilder sb = new StringBuilder();
string currentLine = string.Empty;
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string Data = serialPort1.ReadExisting();
foreach (char c in Data)
{
if (c == ETX)
{
sb.Append(c);
CurrentLine = sb.ToString();
sb.Clear();
//parse CurrentLine here or print it to textbox
//note you might have to invoke because this event is on its own thread
}
else
{
sb.Append(c);
}
}
}
此外,在打开端口之前,请创建您的DataReceived
事件。使用完配置后对它进行更改是不好的。
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
mySerialPort.Open();