Different values when using char and string in Serial Communication

In Robin2’s Serial Input Basics Example 3, we’re sending in characters and the program reads each character at a time after receiving the starting marker; and it continues until the end marker is reached. I tried to do the same but using a String, but my echoed data isn’t always correct, sometimes until the 4th iteration or so. When I tried running the String version into the character version, somehow it reads the String and returns the strings perfectly!!! I’m not sure why this is happening, I would have thought that if I sent a String, it would read each character at a time.

In C++ a string is just an array of characters but I’m still confused on the interchangeability of the two. When I change the type from char to String, I don’t get the same data echoed back. I’m not sure why so I went back and tested the char version. I’m not sure if it has something to do with the type, since the code is basically the same, but I’m going back to the example to make sure I’m understanding what’s happening.

I’m using UNO and Visual Studio 2017 with a Arduino extension for this example. For my debugging, I’m reading the data as a String, and then writing the String to a text box. When I loaded the example, opened the serial monitor, and sent in the following:

readplease

“read” and “please” will be ignored, whereas “this” will be displayed. This is expected since the program is only going to read characters within the markers. So what’s read is each character starting after the start marker, therefore

receivedChars[ndx] //ndx = 0

and would read ‘t’ into 0, h:‘1’, ‘i’:2, ‘s’:3. Therefore receivedChars[ndx] is a 4 element array.

If I apply what I said above then for the following examples:

Input: 0000<,,,,,,,>abc
Output: ,,,,,,,
//This is just a 7 element array, except it's just ',' being stored 

Input: thedate<10,28,is,during,>thefall
Output:10,28,is,during,
//since the array is just reading chars, it doesn't care if you're inputting numbers or alphabetic characters since they're all ASCII Characters

Input: thedate<10,28,is,during,10,28,is,during,10,28,is,during,>thefall
Output: 10,28,is,during,10,28,is,during
//As long as the number of characters doesn't exceed the size of the array, it will store said characters

From what I understand, in all these examples above, when using the example program as a standalone with it’s serial monitor, it just fills the array with characters. Accessing an element is the same as accessing 1 character in the array.

Here’s where I’m having issues:

When I use a my GUI, I’m sending in strings instead of characters. Since the Serial monitors read ASCII Characters, these examples using serial communication will be different from using the serial monitor.

The way the String array is set up is

String[] dataout = new string[] { "<", b1, b2, b3, b4, b5, b6, ">" };

where each element is just a string of numbers, for example: a String of a number betweent 0-999.

On my debugging send/receive area I have the program print the data being sent over printed, with semicolons between each String element in the array and when I receive data, I print each element followed by a semicolon as well:

Input:<:0:6:0050:0255:0500:5:>:

Output: :0:6:0050:0255:0500:5::
//I decided to use padded 0's in order to keep some controls the same size, this is only necessary if my array is a character array and is really just a setup for future use.

Input: <:0:5:0100:0200:0200:5:>:
Output: :0:5:0100:0200:0200:5::
//The code displays each element followed by :, which is why there are : between each element, and since the start and endmarkers didn't alter any value in the array, I guess they stayed null?

Now I’m not sure if there’s a way to check what type of data is being returned, but I’m fairly confident when I say that the output from the GUI to the UNO is a String. I think the data being read into the UNO is a character, but the data being echoed back is a String. I think it’s a String because if it were a character array, there would be a semicolon between each character.
Is there some sort of implicit conversion occurring when it gets sent back and forth? Why I say that is since there are no semicolons between the characters on the UNO, since there’s only a character array declared in the UNO. Unless the strings are stored in a multidimensional character array, which I don’t think is possible since we didn’t declare one, there shouldn’t be a way to access the data by element. In the case of the last input, the third element of the array being sent to the UNO is 0200, but I think the third element in the UNO would technically be just a ‘1’?

Robin2’s Example 3:

// The setup() function runs once each time the micro-controller starts

// Example 3 - Receive with start- and end-markers

const byte numChars = 32;
char receivedChars[numChars];

boolean newData = false;

void setup() {
 Serial.begin(9600);
 Serial.println("<Arduino is ready>");
}

void loop() {
 recvWithStartEndMarkers();
 showNewData();
}

void recvWithStartEndMarkers() {
 static boolean recvInProgress = false;
 static byte ndx = 0;
 char startMarker = '<';
 char endMarker = '>';
 char rc;

 while (Serial.available() > 0 && newData == false) {
 rc = Serial.read();

 if (recvInProgress == true) {
 if (rc != endMarker) {
 receivedChars[ndx] = rc;
 ndx++;
 if (ndx >= numChars) {
 ndx = numChars - 1;
 }
 }
 else {
 receivedChars[ndx] = '\0'; // terminate the string
 recvInProgress = false;
 ndx = 0;
 newData = true;
 }
 }

 else if (rc == startMarker) {
 recvInProgress = true;
 }
 }
}

void showNewData() {
 if (newData == true) {
 //Serial.print("This just in ... ");
 Serial.println(receivedChars);
 newData = false;
     }
}

Windows Form:

How I send the data:

String[] dataout = new string[] { "<", b1, b2, b3, b4, b5, b6, ">" };
            String[] userinput = new string[] { "<", comboBox1.SelectedItem.ToString(), comboBox2.SelectedItem.ToString(), b3, b4, b5, b6, ">" };
            //Print Out Array into the text box
            for (int p = 0; p <= 7; p++)
            {
                textBox1.AppendText(userinput[p]);
                textBox1.AppendText(":");
            }
            textBox1.AppendText("\n");
            //Serial COM
            port = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
            port.Open();
            Thread.Sleep(200);
            //Send Data Out to the Arduino
            for (int a = 0; a <= 7; a++)
            {
                port.WriteLine(dataout[a]);
                Thread.Sleep(10);
            }
            Thread.Sleep(400);            //Wait

            //RX DATA from Arduino
            //Create Data In
            String[] datain = new string[8];
            //Get Data
            for (int b = 0; b <= 7; b++)
            {
                datain[b] = port.ReadLine();
                Thread.Sleep(10);
            }
            //Print In Array onto second text box
            for (int c = 0; c <= 7; c++)
            {
                textBox2.AppendText(datain[c]);
                textBox2.AppendText(":");
            }
            
            textBox2.AppendText("\n");
            port.Close();
        }

You seem to use the words string and String interchangeably even though you are seemingly aware of the difference. This makes your post very difficult to follow.

Sorry about that, wasn't really paying attention to that and just using capital letters for the end of sentences and for proper nouns. I think I fixed all the ones I mean.
Also I'm can't say for certain I'm very aware of the difference between the two, but I know that String is the class whereas string is a reference and for objects.

but I know that String is the class whereas string is a reference and for objects.

Yes, String is a class, but a string is a null-terminated char array.

jim-yang:
In Robin2's Serial Input Basics Example 3, we're sending in characters and the program reads each character at a time after receiving the starting marker; and it continues until the end marker is reached. I tried to do the same but using a String,

Don't.

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

...R

AWOL:
Yes, String is a class, but a string is a null-terminated char array.

So technically, when I said

jim-yang:
In C++ a String is just an array of characters

it should technically be "a string is just an array of characters?

jim-yang:
So technically, when I saidit should technically be "a string is just an array of characters?

A string is a null-terminated array of characters.
This has already been mentioned.

Robin2:
Don't.

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

...R

Is memory corruption a common issue or just a class issue? I don't think I'm using a lot of the memory since when I run the program, When I run the program the IDE says I'm only using 19% of the Program size and 13% of the Minimum Memory usage. So it's basically like the stuff in here

Yeah, that's what I noticed. One day the program was running perfectly, and then the next day it took 2 attempts to run, and now it takes 3 or 4 occasionally.

AWOL:
A string is a null-terminated array of characters.
This has already been mentioned.

Yes it was mentioned but I was just hoping to clarify since when I originally wrote the post, I typed"string" occasionally when I meant "String" and I went back to fix the post. When I was editing the post I shouldn't have changed the statement into a false one. Thanks for the clarification.

jim-yang:
Is memory corruption a common issue or just a class issue?

It arises because of the the way the underlying code for the String class handles memory. Every reference to a String probably results is a new piece of memory being required and the vacated pieces of memory are not always fully used or usable.

On a PC with lots of memory and an operating system there is less of a problem and there is probably a garbage-collection process to re-capture the vacated memory for further use.

...R