我正在尝试构建一个 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;
}
}));
}
有人可以帮我吗?
干杯
我想我已经弄清楚了。谢谢大家帮助。起初,克莱门斯,我以为你的意思是 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;
}
}));
}