I am making a GUI to communicate with a UART device. For that, I need to show a part of the string received by UART in a rich text box continuously. String Format is like: "$abc,csd,frvt,v,00000,erty,9,gtyu*" (just for reference). Out of this string, I need to show the data in place of the five zeroes in rtb. I am doing the following in code.
Any help is much appreciated.
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);
}
It should write the five zeroes every time into the rtb. It does so the first time but after that, gives the error: "startIndex cannot be larger than length of string"
There are a couple details to keep in mind. Like many people have mentioned the serialport data received event won't necessarily be raised with a complete line of your string everytime. It could be a single character, or even multiple complete lines ("$abc,csd,frvt,v,00000,erty,9,gtyu*$abc,csd,frvt,v,00000,erty,9,gtyu*").
Your update:
if (receiveddata.length>startIndex)
{
substring = receiveddata.Substring(startIndex,length);
}
this.Invoke(new EventHandler(displayText));
Gets a little closer to handling the details, but there are still some issues with it. For example: if receiveddata = "$abc,csd,frvt,v,000", it will try to grab the substring but it won't all be there, causing an exception. Or what if receiveddata = "$abc,csd,frvt,v,00000,erty,9,gtyu*$abc,csd,frvt", now you'll be off next time because the leftover string isn't kept.
The solution I came up with waits for an entire "line" to be received before parsing it. Then it keeps anything extra to add to the next data we receive.
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);
}