3

I have a program setup where a MCU sends me sensor data via USART to a C# windows forms application. That application upon receiving the data via the serialdatareceived event sends it to a managed c++ application using anonymous pipes. As soon as the data is received it is plotted in an OpenGL 3d enviroment.

My problem is that the 3D application only refreshes a few times per second and the animation is quite slow and not smooth enough. I did my best to improve the USART speed but the result is the same. I believe the animations speed is bottlenecked by the anonymous pipes speed. I was wondering if anyone else encountered this problem before and possibly found ways to speed upthe anonymous pipes data transfer.

So my problem is the low data transfer speed between the two applications. Ideally I would want 20+ messages a second but at the very least the bottleneck of the data transfer should be the USART interface and not the anonymous pipes. I am running a BAUD-rate of 19200 and am transferring the command "get_angle" and receiving data back fairly fast (~20 ms for calculation of data on the MCU), the data received is ~12 chars.

My anonymous pipe client in managed c++ (in 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;
}

My code for the C# anonymous pipes server part:

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;
        }
    }
user46794
  • 51
  • 6

0 Answers0