【问题标题】:Using read data from multiple serial ports within Main()在 Main() 中使用从多个串行端口读取数据
【发布时间】:2014-03-31 01:22:20
【问题描述】:

我是 C# 编程的新手,对串行端口知之甚少。我正在关注微软提供的this method,不断读取进入多个串口的信息。总的来说,我的应用程序是从多个 COM 端口引入数据并对结果数据执行计算任务。

1) 我想使用多个串口。不幸的是,我目前没有足够的 USB-RS232 适配器来测试多个端口。我不确定创建第二个 DataReceivedHandler 方法是否是正确的方法。这是我目前拥有的:

// Receive data on COM Port A
private static void DataReceivedHandlerA(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    string inDataA = sp.ReadExisting();
}

// Receive data on COM Port B
private static void DataReceivedHandlerB(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort spB = (SerialPort)sender;
    string inDataB = spB.ReadExisting();
}

2) 在 Main() 循环的其他地方使用从 DataReceivedHandler 方法中接收到的数据。由于该方法是私有的,因此我无法在 Main() 循环中使用 inDataA。每当我公开此方法时,它似乎都失败了。我希望能够返回字符串 inDataB。这可能吗,还是有其他更好的方法来做到这一点。

【问题讨论】:

    标签: c# serial-port


    【解决方案1】:

    有什么理由不能将这两个变量作为 main 之外的全局变量,以便它们可用于所有函数?

    Static String inDataA, inDataB;
    
    // Receive data on COM Port A
    private static void DataReceivedHandlerA(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPort sp = (SerialPort)sender;
        inDataA = sp.ReadExisting();
        Console.Write(inDataA);
    }
    
    // Receive data on COM Port B
    private static void DataReceivedHandlerB(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPort spB = (SerialPort)sender;
        inDataB = spB.ReadExisting();
        Console.Write(inDataB);
    }
    
    
    //use those variables here as well in some other functions
    

    【讨论】:

    • 我试过了,但是在 DataReceivedHandlerA 方法中,在 inDataA 旁边收到错误“当前上下文中不存在名称 'inDataA'”。我相信它不喜欢该方法是静态的,如果我将其设为非静态,该方法将失败。
    • 这停止了调试过程中的所有错误。但是,在 Main() 循环中运行以下内容不会导致任何内容写入控制台:code Console.Write(inDataA); code
    【解决方案2】:

    当您从 main 调用 Console.Write(inDataxx) 时,inDataxx 为 null 或空,因为事件处理程序很可能尚未被触发。由于您尚未创建通知事件或轮询循环,因此此打印命令执行一次且仅执行一次。

    在您提供的示例的主循环中,有三个部分。 COM 端口设置、控制台设置和 COM 拆除。这一切都是按顺序执行的,没有逻辑可以继续打印您的公共(现在是静态变量)。此示例旨在直接从事件处理程序打印。为了使您的设计工作,您需要修改主循环以轮询或使用事件来打印数据。试试这样的投票:

    int keyIn = 0;
    do
    {
        // Check if any key pressed, read it into while-controlling variable
        if (Console.KeyAvailable)
            keyIn = Console.Read();
        // Poll our channel A data
        if (!string.IsNullOrEmpty(inDataA))
        {
            Console.WriteLine(String.Format("Received data {0} on channel A", inDataA));
            inDataA = "";
        }
        // Poll our channel B data
        if (!string.IsNullOrEmpty(inDataB))
        {
            Console.WriteLine(String.Format("Received data {0} on channel B", inDataB));
            inDataB = "";
        }
        // Stop looping when keyIn is no longer 0
    }while (keyIn == 0);
    

    请注意,如果您打算使用这是生产代码,请不要使用轮询。轮询效率很低。

    【讨论】:

    • 我有一个更大的应用程序,我正在使用它。我希望能够在我的应用程序的其他部分(计算等)中使用 inDataA 中的数据。即使它是一个流,我也开发了缓冲和解析它的方法。没有有效的方法来做到这一点吗?我会试试你的方法。
    • 这是所有控制台基础还是有 UI?如果您在其他地方使用数据,请考虑构建一个描述此数据的对象。它可以包含您的所有方法,并且可以通过有效引用随时用于任何计算。例如MyDataA.parse().DoMaths(); gist.github.com/corytodd/9876275#file-serial-polling
    • 这将是一个控制台(目前),因为我没有表单编程的能力。如何开发可以使用 inDataA 变量的类对象?抱歉,这些可能是基本问题,对于 C# 来说是全新的。
    • 查看更新的要点以获得想法。有很多方法可以解决这个问题。有些人对过度使用单例表示异议,但我认为在这种情况下这没什么大不了的。
    猜你喜欢
    • 2011-06-14
    • 2018-02-12
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    • 2017-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多