我正在使用.NET SerialPort类与仪表进行通信。每次按下仪表上的按钮时,都会通过端口发送读数值。
我遇到的问题是,如果在程序关闭时按下仪表按钮,则程序启动时会触发该现有数据的数据接收事件。我不想要这种行为 - 我只想收集端口打开后的读数。
我目前有使用Thread.Sleep的解决方法,但它看起来很hacky,我想知道是否有人知道更好的解决方案。
port = New SerialPort("COM1", 9600, Parity.None, 8, StopBits.One)
port.Open()
port.DtrEnable = True
System.Threading.Thread.Sleep(100)
port.ReadExisting()
AddHandler port.DataReceived, AddressOf PortDataReceived
如果我没有Thread.Sleep,则会针对先前的仪表数据触发DataReceived事件。我猜这是因为ReadExisting没有阻塞,所以当它在打开后立即调用时它就什么都不读。
由于
因此,如果在打开零后立即调用'port.BytesToRead()'。如果在打开非零值后100ms调用它。我想这是有道理的 - 打开后读取现有数据需要一些时间。
另一种选择是调用read并设置读取超时,但这似乎与Thread.Sleep没有什么不同,除非你必须捕获异常......
答案 0 :(得分:1)
port.DtrEnable = True
这可能会产生副作用。仪表可能会上下跳跃,渴望发送读数。毕竟,有人按下按钮告诉它可以发送。但它的传输例程是观察握手协议,数据终端就绪没有开启。跳,跳啊!它在。发送。这需要一段时间,取决于波特率。
那么,即使计算机还没有准备好,为什么有人按下按钮?为什么总是准备好了?回答那个问题,然后就可以删除Sleep()了。还要了解当计算机准备好之前有人按下按钮一百次时会发生什么。你的睡眠()可能太短了。
答案 1 :(得分:0)
如果您不需要收集在串口的out缓冲区中等待的内容,请尝试调用 serialPort.DiscardWriteBuffer() serialPort.DiscardOutBuffer(),它应该清除那里收集的内容。感谢Chad纠正我的错误。