Why do I keep getting this error: "startIndex cannot be larger than length of string" while communicationg with UART

Why do I keep getting this error: "startIndex cannot be larger than length of string" while communicationg with UART

我正在制作一个 GUI 来与 UART 设备通信。为此,我需要在富文本框中连续显示 UART 接收到的字符串的一部分。字符串格式如:"$abc,csd,frvt,v,00000,erty,9,gtyu*"(仅供参考)。在这个字符串之外,我需要显示数据来代替 rtb 中的五个零。 我在代码中执行以下操作。

非常感谢任何帮助。

    private string receiveddata;
    private string substring;
    int startIndex = 17;
    int length = 5;

    private void serialPort1_DataReceived(object sender, 
            System.IO.Ports.SerialDataReceivedEventArgs e)
    {  
        receiveddata = serialPort1.ReadExisting();     
        substring = receiveddata.Substring(startIndex,length);
        this.Invoke(new EventHandler(displayText));
    }


    private void displayText(object o, EventArgs e)
    {
        richTextBox2.AppendText(receiveddata);
        richTextBox3.AppendText(substring);    
    }

应该每次都将五个零写入rtb。它第一次这样做,但之后,给出错误:"startIndex cannot be larger than length of string"

有几个细节需要牢记。就像很多人提到的那样,串行端口数据接收事件不一定每次都用完整的字符串行引发。它可以是单个字符,甚至是多个完整的行(“$abc,csd,frvt,v,00000,erty,9,gtyu*$abc,csd,frvt,v,00000,erty,9,gtyu*”) .

您的更新:

if (receiveddata.length>startIndex)
{
  substring = receiveddata.Substring(startIndex,length);
}
this.Invoke(new EventHandler(displayText));

在处理细节上更接近一些,但仍然存在一些问题。例如:如果receiveddata = "$abc,csd,frvt,v,000",它会尝试抓取子串但不会全部到位,导致异常。或者,如果 receiveddata = "$abc,csd,frvt,v,00000,erty,9,gtyu*$abc,csd,frvt",现在你下次会离开,因为没有保留剩余的字符串。

我想出的解决方案是在解析之前等待整个 "line" 被接收。然后它会保留任何额外的内容以添加到我们收到的下一个数据中。

private string receiveddata = string.Empty;
private const int startIndex = 17;  // I had to change this from 16 based on the example string you gave.
private const int length = 5;
private const int totalLength = 34;  // The total length of the "line" of text we're expecting ("$abc,csd,frvt,v,00000,erty,9,gtyu*").


private void serialPort1_DataReceived(object sender,            
  System.IO.Ports.SerialDataReceivedEventArgs e)
{
  string receivedThisTime = serialPort1.ReadExisting();

  // Update the richTextBox that displays everything received.
  Invoke(new Action(() => displayAllReceivedText(receivedThisTime)));

  // Add what was just received to the string we're currently working on.
  receiveddata += receivedThisTime;

  // If we've received all of the characters in the complete line:
  // "$abc,csd,frvt,v,00000,erty,9,gtyu*", then we're ready to parse the
  // values we need from it.  This is a while in-case receiveddata contains
  // multiple complete lines - we want to parse them all.
  while (receiveddata.Length >= totalLength)
  {
    // Parse what we need from the string.
    string substring = receiveddata.Substring(startIndex, length);

    // Update the richtextbox that shows the parsed values.
    Invoke(new Action(() => displaySubText(substring)));

    // Now update our string to contain anything that comes after this
    // complete line.  i.e.
    // if receiveddata = "$abc,csd,frvt,v,00000,erty,9,gtyu*$abc,csd,"
    // it should now   = "$abc,csd,"
    receiveddata = receiveddata.Substring(totalLength);
  }
}

private void displayAllReceivedText(string text)
{
  richTextBox2.AppendText(text);
}

private void displaySubText(string text)
{
  richTextBox3.AppendText(text);
}