Почему я продолжаю получать эту ошибку: "startIndex не может быть больше, чем длина строки", пока осуществляется связь с UART - PullRequest
0 голосов
/ 24 января 2019

Я создаю графический интерфейс для связи с устройством 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 не может быть больше длины строки»

1 Ответ

0 голосов
/ 24 января 2019

Есть пара деталей, о которых нужно помнить.Как и многие люди упоминали, что полученное в результате последовательного порта событие не обязательно будет каждый раз вызываться с полной строкой вашей строки.Это может быть один символ или даже несколько полных строк («$ 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));

Становится немного ближе к обработке деталей, но все еще есть некоторые проблемы с ним.Например: если receivedata = "$ abc, csd, frvt, v, 000", он попытается захватить подстроку, но не все будет там, вызывая исключение.Или что, если receivedata = "$ abc, csd, frvt, v, 00000, erty, 9, gtyu * $ abc, csd, frvt", теперь вы будете отключены в следующий раз, потому что оставшаяся строка не сохраняется.

Решение, которое я придумал, ждет получения всей "строки", прежде чем ее анализировать.Затем он сохраняет что-то дополнительное для добавления к следующим полученным нами данным.

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);
}
...