寻找编写串行设备通信应用程序的最佳实践

时间:2010-05-24 05:33:32

标签: c# .net serial-port

我对串口通信很陌生,但我想建议如何最好地实现一个能够说话和收听串行设备的强大应用程序。

我已成功使用System.IO.SerialPort,并成功连接到我的设备并向其发送数据。事情的运作方式就是这样。

我的应用程序连接到Com端口并打开端口....然后我将我的设备连接到com端口,它检测到与PC的连接,因此发送一些文本。它实际上只是版权信息,以及固件的版本。我不做任何事情,除了在我的“活动”窗口中显示它。

然后设备等待。

然后我可以查询信息,但发送命令,例如'QUERY PARAMETER1'。然后它会回复:

'QUERY PARAMETER1 \ r \ n \ r \ n76767 \ r \ n \ r \ n'

然后我处理它。然后我可以通过发送'SET PARAMETER1 12345'来更新它,它将回复'QUERY PARAMETER1 \ r \ n \ r \ n12345 \ r \ n \ r \ n'。

一切都非常基本。

所以,我所做的是创建了一个通信类。这个调用在它自己的线程中调用,并将数据发送回主表单...并且还允许我向它发送消息。

发送数据很简单。接收有点棘手。我已经使用了datarecieved事件,当有数据进入时,我回复到我的屏幕。我的问题是:

当我发出命令时,我觉得我的处理非常狡猾。我正在做的是,让我说我发送'QUERY PARAMETER1'。我将命令发送到设备,然后我将'PARAMETER1'放入一个全局变量,然后我做一个Thread.Sleep(100)。

在收到的数据上,我有一些逻辑检查传入的数据,并查看字符串是否包含全局变量中的值。由于回复可能是'QUERY PARAMETER1 \ r \ n \ r \ n76767 \ r \ n \ r \ n',它会看到它包含我的参数,解析字符串,并返回我要查找的值,但放置它进入另一个全局变量。

我的发送方法是睡了100ms。然后它会唤醒,并检查返回的全局变量。如果它有数据...那么我很高兴,我处理数据。问题是......如果睡眠太短......它会失败。而且我觉得它很脆弱......把东西放进变量......等等......

另一个选择是使用ReadLine代替,但这非常阻塞。所以我删除了收到的数据方法,而只是...发送数据...然后调用ReadLine()。这可能会给我更好的结果。没有时间,除非我们最初连接,数据来自设备,没有我请求它。那么,也许ReadLine会更简单,更安全吗?这被称为'阻止'读取?另外,我可以设置超时吗?

希望有人可以指导我。

3 个答案:

答案 0 :(得分:1)

好吧,Thread.Sleep()也是阻塞的。更糟糕的是,实际上,因为你必须指定一个总是安全的睡眠时间,即使机器负载很重。使用ReadLine()总是更好,它会更快,也不会失败。

请注意,您的示例不要求客户端代码等待响应。它可以简单地假设命令有效。您只需要一个错误事件来表示出现问题。

如果有一个命令需要客户端代码获取响应,您应该提供等待以及异步获取结果的选项。这给了客户端代码选项:等待很慢但很容易,异步很难编程。它是.NET框架中非常常见的模式,异步方法名称以“Begin”开头。查看关于它的MSDN Library article

您还应该考虑在客户端代码更喜欢的线程上提供异步通知。 SynchronizingObject属性为a good pattern

答案 1 :(得分:0)

如果您在后台线程上执行了所有读操作,那么我在使用ReadLine时看不到任何问题。这是最简单,最强大的解决方案。

您可以使用ReadTimeout属性设置读取操作的超时时间。

答案 2 :(得分:0)

您可能需要阅读此Serial Port