我有一个程序设置,其中 MCU 通过 USART 将传感器数据发送到 C# windows 窗体应用程序。该应用程序在通过 serialdatareceived 事件接收数据后,使用匿名管道将其发送到托管 c++ 应用程序。一旦收到数据,它就会在 OpenGL 3d 环境中绘制。
我的问题是 3D 应用程序每秒只刷新几次,而且动画很慢而且不够流畅。我尽了最大努力提高 USART 速度,但结果是一样的。我相信动画速度受到匿名管道速度的限制。我想知道是否有其他人以前遇到过这个问题,并且可能找到了加快匿名管道数据传输的方法。
所以我的问题是两个应用程序之间的低数据传输速度。理想情况下,我希望每秒 20 多条消息,但至少数据传输的瓶颈应该是 USART 接口而不是匿名管道。我正在运行 19200 的波特率,并且正在传输命令“get_angle”并以相当快的速度接收数据(在 MCU 上计算数据约为 20 毫秒),接收到的数据约为 12 个字符。
我在托管 C++ 中的匿名管道客户端(在 WinMain 中):
try
{
String^ args = gcnew String(lpCmdLine);
PipeStream^ pipeClient = gcnew AnonymousPipeClientStream(PipeDirection::In, args);
StreamReader^ sr = gcnew StreamReader(pipeClient);
String^ temp;
fullscreen = FALSE;
if (!CreateGLWindow("OpenGL Test", 640, 480, 16, fullscreen))
{
return 0; // Quit If Window Was Not Created
}
while (!done) // Loop That Runs While done=FALSE
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) // Is There A Message Waiting?
{
if (msg.message == WM_QUIT) // Was the message a quit message?
{
done = TRUE; // Set Flag to execute program
}
else // If Not, Deal With Window Messages
{
TranslateMessage(&msg); // Translate The Message
DispatchMessage(&msg); // Dispatch The Message
}
}
temp = sr->ReadLine(); // Read text from pipeline
if (temp != "") // Make sure message is not empty/New message has been received
{
try
{
x_an = FLOAT::Parse(temp->Substring(0, 5)); // Parse X value from string to float
y_an = FLOAT::Parse(temp->Substring(7, 12)); // Parse Y value from string to float
}
catch (Exception^)
{
MessageBox(NULL, "Error parsing string to float", "Fatal error", MB_OK);
}
}
if ((!done)&& (1))
{
// Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene()
if ((active && !DrawGLScene()) || keys[VK_ESCAPE]) // Active? Was There A Quit Received?
{
done = TRUE; // ESC or DrawGLScene Signalled A Quit
}
else // Not Time To Quit, Update Screen
{
SwapBuffers(hDC); // Swap Buffers (Double Buffering)
}
}
}
// Shutdown
sr->Close();
pipeClient->Close();
KillGLWindow(); // Kill The Window
return (msg.wParam); // Exit The Program
}
catch (Exception^)
{
MessageBox(NULL, "Pipe connection error", "Fatal error", MB_OK);
return 0x01;
}
我的 C# 匿名管道服务器部分的代码:
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (Ready_To_Receive)
{
if (Setup_Pipe)
{
try
{
pipeClient.StartInfo.FileName = "client.exe";
pipeClient.StartInfo.Arguments =
pipeServer.GetClientHandleAsString();
pipeClient.StartInfo.UseShellExecute = false;
pipeClient.Start();
pipeServer.DisposeLocalCopyOfClientHandle();
sw = new System.IO.StreamWriter(pipeServer);
sw.AutoFlush = true;
Setup_Pipe = false;
}
catch
{
MessageBox.Show("Error setting up pipeserver.");
button2_Click(this, null); // Resets application
}
}
Debug_String = serialPort1.ReadExisting();
Debug_String = Debug_String.Replace(serialPort1.NewLine, ""); // Delete newline character so all that remains are numbers
if (!(Debug_String == "")) // String is not empty
{
DataReceived = true;
try
{
sw.WriteLine(Debug_String);
}
catch (Exception)
{
MessageBox.Show("Connection to Pipe Client lost.");
button2_Click(this, null);
}
}
}
else if (Shutting_Down)
{
pipeClient.Close();
}
else
{
serialPort1.ReadExisting(); // Flush the data buffer
DataReceived = true;
}
}