C# WPF Visualiser:从串行端口读取数据

问题描述 投票:0回答:1

我正在尝试构建一个 WPF 应用程序,该应用程序可以从串行端口读取数据,该串行端口正在从连接到 ARM NUCLEO-F303K8 的 MPU6050 读取数据。我已经设法使代码达到现在在 GUI 中显示俯仰和横滚值的程度,但是,它仍然在输出框中显示无效数据。我认为可能的罪魁祸首是我正在使用“ThisThread::sleepfor”和“ “并且它导致 WPF 程序如何从串行读取问题。

这是相关的mbed代码:

// Print values to serial console - Now includes Time
        snprintf(buffer, sizeof(buffer), 
             
             // Seperated by comma for CSV and C# visualiser
            "%02d:%02d:%02d:%03d, %.2f, %.2f, %.2f\n\r",
            int (elapsed_time / 1h), int((elapsed_time % 1h) / 1min), int((elapsed_time % 1min) / 1s), int((elapsed_time % 1s) / 1ms),
            pitch, roll, temperature);

        printf("%s", buffer);

        ThisThread::sleep_for(100ms); // Delay to read data

在我的 WPF xaml.cs 文件中,我有以下用于在 GUI 中显示数据的代码:

  private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
  { 
    Application.Current.Dispatcher.Invoke(new Action(() =>
    {
        try
    {
        // Ensure there's data to read
        if (serialPort.BytesToRead > 0)
        {
            byte[] buffer = new byte[serialPort.BytesToRead];
            serialPort.Read(buffer, 0, buffer.Length);
            string data = Encoding.ASCII.GetString(buffer);
            data = data.Trim();

            string[] items = data.Split(','); // Split to comma separated
            if (items.Length == 4) // Check for 4 items
            {
                op_time = float.Parse(items[0]);
                roll = float.Parse(items[1]);
                pitch = float.Parse(items[2]);
                temperature = float.Parse(items[3]);

                txtPitchValue.Content = pitch.ToString("0.00");
                txtRollValue.Content = roll.ToString("0.00");
            }
            else
            {
                txtOutput.Text = "Invalid data format";
            }
        }
    }
    catch (Exception ex)
    {
        txtOutput.Text = "Error processing data from serial port: " + ex.Message;
    }
}));


}

有人可以帮我吗?

干杯

c# wpf arm
1个回答
0
投票

我想我已经弄清楚了。谢谢大家帮助。起初,克莱门斯,我以为你的意思是 Parse 是错误的,然后就像“哦,这就是为什么”谢谢。

JonasH,感谢您的解释,它有助于理解 BytesToRead,我现在使用 ReadExisting() 来查找可用数据。

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) // sender is SerialPort and related data event
{
                                                                            // Dispatcher needs to be run in current Application 
Application.Current.Dispatcher.Invoke(new Action(() =>                      // WPF requires we use UI thread for updates to UI elements
{
try
{
string receivedData = serialPort.ReadExisting(); // Instead of using BytesToRead we use ReadExisting to read available data
receivedDataBuffer.Append(receivedData);         // Using StringBuilder instead of Read() to gather new data with incomplete data
                                                 // Partial monitoring to avoid "invalid data format" error.


string buffer = receivedDataBuffer.ToString();
if (buffer.Contains("\n"))
{
    
    string[] lines = buffer.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); 
    foreach (string line in lines)
    {
        if (!string.IsNullOrWhiteSpace(line) && line.Contains(",")) // Ignores empty and lines containing commas
        {
            string[] items = line.Split(','); // split line string into items based on comma
            if (items.Length == 4) // Must be 4 items
            {
                timestamp = items[0]; // Keep as string 
                pitch = float.Parse(items[1]); // Switched to pitch
                roll = float.Parse(items[2]);  // Switched to roll
                temperature = float.Parse(items[3]);
                if (txtPitchValue != null && txtRollValue != null)
                {
                    txtPitchValue.Content = pitch.ToString("0.00");
                    txtRollValue.Content = roll.ToString("0.00");
                }
                receivedDataBuffer.Clear(); // Clears buffer
            } else
              {
                txtOutput.Text = "Invalid data format";
              }
        } 
    }
}
} catch (Exception ex)
    {
        txtOutput.Text = "Error processing data from serial port: " + ex.Message;
    }
}));
}
© www.soinside.com 2019 - 2024. All rights reserved.