【发布时间】:2018-03-22 20:25:25
【问题描述】:
我有一个 UART 设备,我正在向它写入一个命令(通过 System.IO.Ports.SerialPort),然后设备会立即响应。
所以基本上我的方法是:
->写入 SerialPort->等待 Task.Delay->从端口读取。
//The port is open all the time.
public async byte[] WriteAndRead(byte[] message){
port.Write(command, 0, command.Length);
await Task.Delay(timeout);
var msglen = port.BytesToRead;
if (msglen > 0)
{
byte[] message = new byte[msglen];
int readbytes = 0;
while (port.Read(message, readbytes, msglen - readbytes) <= 0)
;
return message;
}
这在我的电脑上运行良好。但是,例如,如果我在另一台计算机上尝试它,则 bytesToRead 属性有时不匹配。其中有空字节或答案未完成。 (例如,我得到两个字节,如果我期望一个字节:0xBB、0x00 或 0x00、0xBB)
我还研究了 SerialPort.DataReceived 事件,但它触发得太频繁并且(据我所知)对于这种读写方法并不是很有用。 (正如我期望设备立即给出的答案)。
有没有更好的读写方式?
【问题讨论】:
-
int readbytes = 0; while (port.Read(message, readbytes, msglen - readbytes) <= 0);那么你在哪里更新readbytes呢? -
永远不要丢失 Read() 的返回值。并确保删除 Task.Delay() 调用,它只是隐藏代码中的错误。它完全无法修复它们。
-
我在这里概述了一种处理传入数据的方法stackoverflow.com/questions/15124132/…您只需要构建另一个抽象来将其转换为序列或使用类似反应扩展的东西
-
@HansPassant:问题是,设备有延迟(在 150-700 毫秒之间)。通常这意味着 - 无需等待 - SerialPort.BytesToRead 为 0。(表示没有数据)。不知何故,我不得不等待数据。
-
Read() 已经在等待数据,您可以保证它至少会返回 1 个字节。因此,自己拖延并不能完成任何有用的事情。您根本不需要 BytesToRead,只需传递 msglen - totalbytes。按 Read() 返回值增加总字节数。
标签: c# .net serial-port