title: c# - SerialPort RS-485 and communication limits
body: <p>I'm trying to communicate to a device using RS-485 through the serial port. Everything works fine, until we're trying to boost the communication to test the speed limit of the card then weird problem seem to occur. We are basically sending a first command with an image as arguments, and then another command to display this image. After every command, the card answers saying that the command was well received. But we are reaching limits too soon and the card is supposed to handle much more.</p>
  
  <p>So I'm wondering since the transmission and the reception are going through the same wire, if there is some sort of collision of data? And should I wait to receive all the data? Is the SerialDataReceivedEventHandler too slow of this situation and should I keep reading the bytes in a while true loop in seperate thread and signal other thread once a complete message is arrived?</p>
  
  <p>Other information :</p>
  
  <ul>
  <li>We already have a protocol for communication : startdelimiter, data,
  CRC16, enddelimiter</li>
  <li>Sending in 2 commands is the way we do it and cannot be changed.</li>
  <li>BaudRate is defined at 115200</li>
  <li>The engineer is still working on the program in the card so problem    might also be on his end.</li>
  <li>English is not my first language so feel free to ask if I was not    clear... :)</li>
  </ul>
  
  <p>I recognize SerialPort programming is not my strength, and I've been trying to find some sort of wrapper but I haven't found any that would fit my needs. If someone has one to propose to me that'd be great or maybe someone has an idea of what could be wrong.
  Anyway here is a bit of coding :</p>
  
  <p>Thread sending frames :</p>
  
  <pre><code>    public void SendOne()
          {
              timerLast = Stopwatch.GetTimestamp();
  
              while (!Paused &amp;&amp; conn.ClientConnState == Connexion.ConnectionState.Connected)
              {
                  timerNow = Stopwatch.GetTimestamp();
  
                  if ((timerNow - timerLast) / (double)Stopwatch.Frequency &gt;= 1 / (double)fps)
                  {
                      averageFPS.Add((int)((double)Stopwatch.Frequency / (timerNow - timerLast)) + 1);
                      if (averageFPS.Count &gt; 10) averageFPS.RemoveAt(0);
  
                      timerLast = Stopwatch.GetTimestamp();
  
                      if (atFrame &gt;= toSend.Count - 1)
                      {
                          atFrame = 0;
                          if (!isLoop)
                              Paused = true;
                      }
  
  
                      SendColorImage();
                  }
  }
  
  
  
    public void SendColorImage()
      {
          conn.Write(VIP16.bytesToVIP16(0x70C1, VIP16.Request.SendImage, toSend[++atFrame]));
          WaitForResponse();
          conn.Write(VIP16.bytesToVIP16(0x70C1, VIP16.Request.DisplayImage, VIP16.DisplayOnArg));
          WaitForResponse();
      }
  
      private void WaitForResponse()
      {
          Thread.Sleep(25);
      }
  </code></pre>
  
  <p>So the WaitForResponse() is crucial because if I send another command before the card answered it would go nuts. Although I hate to use Thread.Sleep() because it is not very accurate plus it'd limit my speed to 20fps, and if I use something lower than 25ms, risks of crash is much more likely to occur. So I was about to change the Thread.Sleep to "Read bytes until whole message is received" and ignore the DataReceivedEvent... just wondering if I'm completely off track here?</p>
  
  <p>Tx a lot!</p>
  
  <p><strong>UPDATE 1</strong></p>
  
  <p>First Thank you Brad and 500 - Internal Server Error! But I've decide to stick with the .NET Serial Port for now and improve the Thread.Sleep accuracy (with timebeginperiod). I've decided to wait for the full response to be received and I synchronized my threads like so using ManualResetEventSlim (for speed) :</p>
  
  <pre><code>public static ManualResetEventSlim _waitHandle = new ManualResetEventSlim(false);
  </code></pre>
  
  <p>Then I changed SendColorIMage to : </p>
  
  <pre><code>   public void SendColorImage()
      {
          conn.Write(VIP16.bytesToVIP16(0x70C1, VIP16.Requetes.SendImage, toSend[++atFrame]));
          WaitForResponse();
          conn.Write(VIP16.bytesToVIP16(0x70C1, VIP16.Requetes.DisplayImage, VIP16.DisplayOnArg));
          WaitForResponse2();
      }
  
      private void WaitForResponse()
      {
          Connexion._waitHandle.Wait(100);
          Thread.Sleep(20);
      }
  
      private void WaitForResponse2()
      {
          Connexion._waitHandle.Wait(100);
          //Thread.Sleep(5);
      }
  </code></pre>
  
  <p>With SerialDataReceivedEventHandler calling :</p>
  
  <pre><code>    public void Recevoir(object sender, SerialDataReceivedEventArgs e)
      {
          if (!msg.IsIncomplete)
              msg = new Vip16Message();
  
          lock (locker)
          {
              if (sp.BytesToRead &gt; 0)
              {
                  byte[] byteMsg = new byte[sp.BytesToRead];
                  sp.Read(byteMsg, 0, byteMsg.Length);
                  msg.Insert(byteMsg);
              }
          }
  
          if (!msg.IsIncomplete)
          {
              _waitHandle.Set();
              if (MessageRecu != null)
                  MessageRecu(msg.toByte());
          }
      }
  </code></pre>
  
  <p>So I found out that after the second command I didn't need to call Thread.Sleep at all... and after the first one I needed to sleep for at least 20ms for the card not to crash. So I guess it's the time the card needs to receive/process the whole image to it's pixel. AND collision of data shouldn't really occur since I wait until whole message has arrived which means the problem is  not  on  my  end! YES! :p </p>