Data display in visual studio

I have a visual studio app sending commands to the Arduino and displaying the serial data but is there a way to display my data in different text boxes instead of everything in one and having to read through everything

Yes.

Receive the data, split it after you've received a complete message and place each part in a textbox.

So your saying to parse all the data together then send out to the PC and then separate

I did not say that you have to send everything in one go. But you have to receive a complete set of data so the receiving side can know when to process.

Let's say you have two temperature/humidity sensors.

You can send messages with identifiers; e.g. <T1:25.0, H1:65> could indicate a temperature of 25 degrees and a humidity of 65% of the first sensor. The receiving side can split on the comma to get the different fields and next split on the colon to get the values and put them in the relevant text boxes. If only the humidity changed, you can send H1:65. Again split on the comma first (there is none, I know) and next on the colon.

The format is based on the 3rd example in Robin's Serial Input Basics. Although it was written for receiving data with an Arduino, the principles also apply to receiving data on a PC.

You can define your own format. In Robin's example, the '<' indicates the beginning of a message, the '>' the end of a message. If you have a need to use those characters in your messages, you can pick other ones; if you want to be able to use any character in the alphabet and any digit, you can use STX (0x02) and ETX (0x03) that were basically defined for that purpose.

this is just a test code i done to see id my display numbers was right but im getting a System.IndexOutOfRangeException
HResult=0x80131508
Message=Index was outside the bounds of the array.
Source=Drag Tree Control 1
StackTrace:
at Drag_Tree_Control_1.Form1.SerialPort1_DataReceived(Object sender, SerialDataReceivedEventArgs e) in C:\Users\Michael\source\repos\Drag Tree Control 1\Drag Tree Control 1\Form1.vb:line 31
at System.IO.Ports.SerialPort.CatchReceivedEvents(Object src, SerialDataReceivedEventArgs e)
at System.IO.Ports.SerialStream.EventLoopRunner.CallReceiveEvents(Object state)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

arduino

 The setup() function runs once each time the micro-controller starts
unsigned int rl;
unsigned int rr;
unsigned int sl;
unsigned int sr;
unsigned int ml;
unsigned int mr;
unsigned int el;
unsigned int er;
String timeData;
void setup()
{
Serial.begin(9600);


rl = 0;
rr = 1;
sl = 2;
sr = 3;
ml = 4;
mr = 5;
el = 6;
er = 7;


}

// Add the main program code into the continuous loop() function
void loop()
{
timeData = timeData + rl + "," + sl + "," + ml + "," + el + "," + rr + "," + sr + "," + mr + "," + er + ",";
Serial.print(timeData);
timeData = ("");
delay(6000);


{rl++;
sl++;
ml++;
el++;
rr++;
sr++;
mr++;
er++; }

}

vb

Imports System.IO.Ports

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        SerialPort1.Open()

        Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False
    End Sub
    Private Sub BtnStart_Click(sender As Object, e As EventArgs)
        If BtnIG.Checked = True Then
            SerialPort1.Write("I")
        ElseIf BtnPT.Checked = True Then
            SerialPort1.Write("P")
        ElseIf BtnST.Checked = True Then
            SerialPort1.Write("S")
        End If
    End Sub

    Private Sub SerialPort1_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        Dim myData As String

        myData = SerialPort1.ReadExisting()

        Dim timeString() As String

        timeString = myData.Split(New Char() {","c})
        reacL.Text = timeString(0)
        sixtyL.Text = timeString(1)
        mphL.Text = timeString(2)
        etL.Text = timeString(3)
        reacR.Text = timeString(4)
        sixtyR.Text = timeString(5)
        mphR.Text = timeString(6)
        etR.Text = timeString(7)

    End Sub

    Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs)
        If ldisp.Checked Then
            SerialPort1.Write("ld")
        Else
            SerialPort1.Write("LD")
        End If

    End Sub

    Private Sub rdisp_CheckedChanged(sender As Object, e As EventArgs)
        If rdisp.Checked Then
            SerialPort1.Write("rd")
        Else
            SerialPort1.Write("RD")
        End If

    End Sub
End Class

I'm not a VB person.

Your problem probably is that you expect all the data to be received when you split it. If your VB code only has received a,b,c,d , timeString only contains 4 elements; trying to access the 5th element will cause the exception.

Place a breakpoint on the line Dim timeString() As String and inspect the myData string to see what it contains.
Or add a debug textbox in your vb code and everytime you receive data, clear the box and show the data in there.

Everything looks to be displaing right I think it is throwing the error when the Arduino sends the new data it displays till my delay runs out

Thanks for fixing the code tags in your previous post.

Make the delay in the Arduino longer for debugging purposes (minute or so).

Visual Studio should indicate where the exception occurred. IndexOutOfRange indicates a problem with array indices.

Put a breakpoint as I indicated; next single step through your code and inspect the variables.

PS
this vb line does not look correct (but I might be wrong); if it compiles, it should be OK. As said, I'm not a vb person but what does the c do there at the end?

timeString = myData.Split(New Char() {","c})

I think it is throwing the error when the Arduino sends the new data it displays till my delay runs out

The error is happening when you try to access some element of the array that myData.Split() returns, WITHOUT bothering to check that that element exists. Print the size of the array BEFORE you access any element of the array. I think that you'll find that there are less than 8 items in the array some times.

The serial monitor shows all 8 every time and if I make the delay longer it takes longer to get the error so the problem is in my VB code somewhere it's always the same error but moves around the elements

The serial monitor shows all 8 every time

The Serial Monitor application is NOT your VB app.

Can someone help me with my visual studio code I'm am am unsure what to do I added a text box to see the incoming and it's not showing up the same every time but is showing correct Everytime in the serial monitor

Mikeh23:
it's not showing up the same every time

That's exactly the problem that we suspected. Your serial data arrives in bits and pieces. Serial Monitor just displays them in sequence that it arrives. So does your extra textbox, but it's cleared every time (I guess, you did not show the updated version of your VB code).

You will have to collect a full message.

With your current Arduino code, that is not possible. The simplest is to use

Serial.println(timeData);

That will append a CR/LF at the end of the message that you can detect in your VB code.

Next, in your VB code, use the ReadLine method instead of ReadExisting.

There is a chance that your message is corrupted because the Arduino can be halfway sending a message when your application starts and you only receive e.g. 3 fields. As @PaulS indicated, check if you have the 8 fields. After

timeString = myData.Split(New Char() {","c})

check the number of elements in the array; I think VB has the Length property to determine the number elements. If it's not 8, you did not receive the full message. You should discard it and wait for the next message to come in. If you indeed have 8 fields, you can populate the textboxes.

Hi, your arduino sketch in post #4 deals only with transmitting so I am posting a VS example that polls the serialport to receive the transmitted data.

I personally don't think using SerialPort.ReadExisting is a very good idea and much prefer the method mentioned by sterretje SerialPort.ReadLine.

This VB example is a Form that has just one RichTextbox and one Timer.

As it is now the VB app will freeze waiting for data, adjust the time values in the app and arduino to reduce the wait time. This is only for example, when you have got the basics you can move on to getting something a little faster/smoother.

Imports System.IO.Ports

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        SerialPort1.Open()
        Timer1.Enabled = True
        Timer1.Interval = 100
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick

        Dim incomingData As String = SerialPort1.ReadLine

        Dim splitString() As String

        splitString = Split(incomingData, ",")

        For Each character As String In splitString
            RichTextBox1.AppendText("Split element " & character & vbCr)
        Next

    End Sub

End Class

P.S. you can remove the last comma from the timedata string and be sure to use Serial.println and not Serial.print

Ok thanks I have it working now