0

I've trying to communicate with an Arduino Due in C#. The communikation works quite well, but my DataReceived handler needs about 1 second to react. This is my problem because I have to send up to 1 billion (1*10E9) commands.

If I activate a DEBUG Setting in the Arduino, it tells me that it's need 64 Milliseconds for a command. I think the C# the App should get it no later than 80 Milliseconds after sending it.

Here is a Part of the Code:

StopWatch s1 = new StopWatch();
private void Open_Port()
{
    string port = null;
    int baud = 0;
    bool ERR = false;
    if ((COM_cb.SelectedItem != null) | (BAUD_cb.SelectedItem != null))
    {
        port = this.COM_cb.GetItemText(this.COM_cb.SelectedItem);
        baud = Convert.ToInt32(this.BAUD_cb.GetItemText(this.BAUD_cb.SelectedItem));
        ERR = false;
    }
    else
    {
        ERR = true;
        System.Windows.Forms.MessageBox.Show("Error Msg"); 
    }

    if (ERR == false)
    {
        serialPort1.PortName = port;
        serialPort1.BaudRate = baud;
        serialPort1.Open();
    }
    if (serialPort1.IsOpen)//Kalibrieren der Buttons
    {
       OPEN_btn.Enabled = false;
        CLOSE_btn.Enabled = true;
        textBox1.ReadOnly = false;
        ERR = true;

    }
}


private void Print_Click(object sender, EventArgs e) // start 
{
    Thread t = new Thread(transmit_pic);
    t.Start();
}

private void DataReceivedHandler(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
    s1.Stop();
    //Till this line it take 1 Second  after sending
    //string t = "";
    int byt = serialPort1.BytesToRead;
     byte[] buffer = new byte[1];

    for (int i = 0; i < byt; i++)
    {
        serialPort1.Read(buffer, 0, 1);
        if(buffer[0] == '0') {
            got_answer = true;
        }
        //t += (char)buffer[0];
    }
    //RxString= t;
    //this.Invoke(new EventHandler(DisplayText));
}

private void sendAktion(int[,] data)
{
    string s = int_to_string(data, false);
    Console.Write("Send->");
    serialPort1.Write(s);
    s1.Start();
    got_answer = false;
    int i = 0;
    while (!got_answer) { i++;  } //wait for answer

    i = 0;
    Console.WriteLine("back again ");
}
private void transmit_pic()
{
    stop = false;
    Bitmap bm = new Bitmap(img);
    if (!serialPort1.IsOpen)
    {
        MessageBox.Show("Open the Serial Port first!");
    }
    else
    {
        int size_X = bm.Width;
        int size_Y = bm.Height;


        for (int h = 0; h < size_Y; h++)
        {
            for (int w = 0; w < size_X; w++)
            {
                if(/*somthing happend*/){
                  //get data...
                  sendAktion(data)


                }
            }
        }
        Console.WriteLine("DONE");
    }
}

Does anyone an Idea why c# needs so long to call the datahandler?

Sincere regards, Fabian Harmsen

UPDATE
- Added comment to DataHandler (24.02.2016 16:30 Europa/Berlin)

user9964422
  • 119
  • 3
  • 15
LFS96
  • 856
  • 1
  • 12
  • 23
  • What is your package size from adruino? How many bytes are sent in 64 ms? – Ian Feb 24 '16 at 15:19
  • @Ian I send about 20 chars and back 1 char only, – LFS96 Feb 24 '16 at 15:24
  • ok, then it should have no issue. It probably your `Invoke` that makes it slow, as HansPassant suggest. Consider of putting your data received in `Queue` every time it is received and only processed to display the text once in a while (say once in 5 seconds). Then your program should run a lot faster. – Ian Feb 24 '16 at 15:26
  • @Ian I have changed the Datahandler but with out success, See it in the Question – LFS96 Feb 24 '16 at 15:31
  • also spinning your while (!got_answer) loop will be maxing out whichever cpu core the thread is running on - consider using another mechanism to block the thread (manualresetevent for example). Console.Writeline can also add delays (i've seen up to 10ms), but that doesn't explain delays as large as you are seeing – Andy P Feb 24 '16 at 15:34
  • @FabianHarmsen you are right, the issue might be more complex than that: http://stackoverflow.com/questions/25391923/serial-port-data-received-handled-too-slowly, http://www.cageman.net/?tag=net-serialport-serial-port-datareceived-delay-fires-slow, https://social.msdn.microsoft.com/Forums/vstudio/en-US/206dd038-ce73-4e98-bff4-25ca9116bbeb/serialport-datareceived-response-time?forum=netfxbcl, http://stackoverflow.com/questions/2947813/c-sharp-net-serial-datareceived-event-response-too-slow-for-high-rate-data – Ian Feb 24 '16 at 15:35

1 Answers1

5

The problem lies in the serialPort1_DataReceived received data handler.

I ran a separate thread with a while(true) loop and serial.ReadLine(), all works perfectly.

Hope someone else doesn't need to spend 3 hours fixing this.

using System.Threading;

public void main()
{
    setup();
    Thread readThread = new Thread(Read);
    readThread.Start();
}

public void Read()
{
    while(true)
    {
    try
    {
        string message = serialPort1.ReadLine();
    }
    catch (Exception)
    { }
}
Victor
  • 86
  • 1
  • 3