C# WPF串口可视化程序:串口数据读取格式异常排查
解决方法
1. 核心问题分析
- 串口
SerialDataReceived事件触发时,不一定能拿到完整一行数据,分段接收会导致Split后元素数量不足4,触发无效格式提示。 - 原代码用
float.Parse解析HH:MM:SS:mmm格式的时间字符串,必然抛出异常,导致错误提示。 - 反向换行符
\n\r可能干扰行分割逻辑。
2. 具体修复步骤
步骤1:缓存串口数据,按完整行处理
添加全局缓存变量,累计接收数据,直到遇到换行符再处理整行:
// 定义全局缓存,用于累计未处理的串口数据 private string _serialBuffer = string.Empty; private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) { Application.Current.Dispatcher.Invoke(new Action(() => { try { if (serialPort.BytesToRead > 0) { byte[] buffer = new byte[serialPort.BytesToRead]; int bytesRead = serialPort.Read(buffer, 0, buffer.Length); string newData = Encoding.ASCII.GetString(buffer, 0, bytesRead); // 将新接收的数据追加到缓存 _serialBuffer += newData; // 循环处理所有完整的行数据 while (_serialBuffer.Contains("\r\n")) { int lineEnd = _serialBuffer.IndexOf("\r\n"); string fullLine = _serialBuffer.Substring(0, lineEnd).Trim(); // 移除已处理的行,保留剩余未处理数据 _serialBuffer = _serialBuffer.Substring(lineEnd + 2); // 单独处理一行数据 ProcessSingleLine(fullLine); } } } catch (Exception ex) { txtOutput.Text = "串口数据处理错误: " + ex.Message; } })); } // 单独封装行数据处理逻辑 private void ProcessSingleLine(string line) { string[] items = line.Split(','); // 校验分割后的元素数量是否符合预期(时间、Pitch、Roll、温度) if (items.Length == 4) { string timeStr = items[0].Trim(); // 使用TryParse替代Parse,避免解析失败抛出异常 if (float.TryParse(items[1].Trim(), out float pitch) && float.TryParse(items[2].Trim(), out float roll) && float.TryParse(items[3].Trim(), out float temperature)) { txtPitchValue.Content = pitch.ToString("0.00"); txtRollValue.Content = roll.ToString("0.00"); txtOutput.Text = "数据接收正常"; // 清除错误提示 // 可选:显示时间和温度 // txtTime.Content = timeStr; // txtTemperature.Content = temperature.ToString("0.00"); } else { txtOutput.Text = "数值格式无效"; } } else { txtOutput.Text = $"数据格式错误: {line}"; } }
步骤2:修正mbed端的换行符
将mbed代码中的\n\r改为标准串口换行符\r\n,避免行分割异常:
"%02d:%02d:%02d:%03d, %.2f, %.2f, %.2f\r\n"
步骤3:移除错误的时间解析逻辑
原代码中尝试将时间字符串转为float的操作完全错误,直接用字符串存储或显示即可。
内容的提问来源于stack exchange,提问作者LeonidasEng
相关产品推荐
相关产品推荐

