我对与硬件进行交互非常陌生。我目前正在使用Windows窗体在C#中构建GUI。我正在使用串行端口/USB与硬件设备进行交互。我想要实现的是让多个线程在不同时间轮询设备。应该定期(至少每秒)检索一些数据,例如温度,电流,功率等,并在GUI上进行更新,以供用户查看。而其他数据仅在用户按下表单上的按钮时才被检索。多线程是解决此问题的正确方法吗?如果没有,什么是更好的解决方案?示例将不胜感激。谢谢您的宝贵时间!

更新:我正尝试使用许多人建议的SerialPort.DataReceived事件和终止符'\r'来解析来自串行端口的单个答复。然后,我调用一个名为DisplayText的方法来处理该字符串。我现在的问题是我不知道如何弄清楚字符串代表什么。它代表温度,电流等吗?

private char terminator = '\r';
private void SerialPorts_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        try
        {
            output += serialPort1.ReadExisting();
            if (output.IndexOf((char)this.terminator) > -1)
            {
                string workingString = output.Substring(0, output.IndexOf(terminator));

                output = output.Substring(output.IndexOf(terminator) + 1);

                this.Invoke(new EventHandler((s, a)=>DisplayText(s, a, workingString)));
            }

        }

        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    private void DisplayText(object sender, EventArgs e, string s)
    {
        Console.WriteLine(s); // for testing only
        richTextBox1.AppendText(s); // for testing only
    }

最佳答案

您可以使用互斥锁保护所有串行端口访问功能,并设计您的应用程序,以便在每次离散操作(例如读取温度)后关闭串行端口。实现此目的的一种可能方法是编写一个包装API,该API可以:

  • 检查互斥锁是否已解锁(如果已锁定,则返回错误代码),
  • 打开串口
  • 读取所需的值
  • 关闭串行端口并清除互斥锁
  • 返回读取的值

  • 但是,您正在使用此解决方案打开各种僵局,并且您将必须实现其他应用程序级别检查来防止这种情况。

    如上所述,更好的解决方案是让一个线程定期轮询串行端口并不断更新您选择的数据结构中的所有值。

    对于仅在用户输入后才需要读取的值,您将必须实现MessageQueue以请求此数据。

    更新以响应OP编辑

    我建议采用以下两种方式之一来处理设备中的通信:
  • 实现请求/响应机制,在其中发送对
    通过串行端口到您设备的特定数据值(例如当前),
    设备解析该请求并返回相应的值
  • 让您的设备在“框架”中返回所有值,例如
    [SOF] [D0 ... Dn] [EOF],其中“D0 ... Dn”是您在
    预定的顺序; SOF和EOF可以是您的任何值
    选择(您也可以选择完全跳过这些内容并依靠
    要定界帧的字节数)。

  • 如果您无法选择更改设备中的代码,则设备必须按照某种顺序报告值,因此维护接收到的数据的序列号将是一种方法。但是,如果不了解有关设备运行状况的更多详细信息,将很难提出解决方案。

    10-07 18:56
    查看更多