Storing Array through serial monitor

Hi,
You have great day
I want required results like the output attached but don't know where is the problem.
Here is the code

const byte numChars =999;
char receivedChars[numChars];
char receivedCharsB[numChars];
char receivedCharsC[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 boolean recvInProgressB = false;
    static boolean recvInProgressC = false;
    static byte ndx = 0;
    char startMarker1 = '<';
    char startMarker2 = '(';
    char startMarker3 = '[';
    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 ==startMarker1) {  //start condition for array 1
            recvInProgress = true;
        }
// For Array 2
else if (recvInProgressB == true) {
            if (rc != endMarker) {
                receivedCharsB[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedCharsB[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }
        else if (rc == startMarker2) {  //start condition for array 2
            recvInProgressB = true;
        }
// For array 3
else if (recvInProgressC == true) {
            if (rc != endMarker) {
                receivedCharsC[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedCharsC[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }


       
        
        else if (rc == startMarker3) {   //start condition for array 3
            recvInProgressC = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("in array 1  ");
        Serial.println(receivedChars);

        Serial.print("in array 2  ");
        Serial.println(receivedCharsB);

        Serial.print("in array 3  ");
        Serial.println(receivedCharsC);
        newData = false;
    }
}

the output attached

Moinh:

const byte numChars =999;

char receivedChars[numChars];
char receivedCharsB[numChars];
char receivedCharsC[numChars];
...

Is your board capable of storing more than 3000 bytes?

you only set "recvInProgress" to false for each case instead of "recvInProgressB/C"

You have entered the following string from the InputBox of the Serial Monitor; where, '<' is the "Start Mark" and '>' is the "End Mark". There are three symbols like this: '>'; so, which one is the "End Mark"?

<123>(456>[789>

Please correct your string, limit your array dimensions to (say 20) reasonable values as @Coding Badly has suggested, and state your requirements:

Do you want to save 123 into this array: char receivedcharsA[20];?
Do you want to save 456 into this array: char receivedcharsB[20];?
Do you want to save 789 into this array: char receivedcharsC[20];?

If you like, you can use "comma separated" style for your data items like the following:
<123,456,789>

are you saying that you possibly have 3 start markers and depending on which one is used (<, ( or [), the value is for A, B or C? sending A123> or B456> or C789> would probably be easier to remember / read

are you in charge of defining that protocol? are you always sending the 3 values? if so, as @golamMostafa suggests, <123,456,789> would probably be easier to parse.

And if you end with '\n' then you probably don't need the start and end markers - just read a line 123,456,789 (drop the '\n') and extract the data separated by the commas.

If you follow what @J-M-L has said in his Post-4 (sending comma separated string/data items with '\n' (the Newline character) as terminating character, and no "Start/End Marks"), then you may exercise the following tested codes (blocking) to extract your substrings (data items as well if the input string contains only numerals: 0 - 9) coming from the InputBox of the Serial Monitor.

Please, remember to select "Newline" option for the "Line ending tab" of Serial Monitor (Fig-1).


Figure-1:

Codes to Practice:

char myData[20];
char receivedcharsA[10];
char receivedcharsB[10];
char receivedcharsC[10];

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  byte y = Serial.available();  //chacke that a data item is in Serial Buffer
  if (y != 0) //there is at least one data item in Serial Buffer
  {
    byte m = Serial.readBytesUntil('\n', myData, 20);  //save until and without Newline ('\n')
    myData[m] = '\0'; //always insert null-charcater as last element fo char type array
    Serial.println(myData);  //shows: 123,456,789
    //============================================
    byte i = 0;
    byte j = 0;
    do
    {
      receivedcharsA[j] = myData[i];  //copy the charcaters for substring 123
      i++;
      j++;
    }
    while (myData[i] != ',');
    receivedcharsA[j] = '\0';
    //int data1 = atoi(receivedcharsA);  //data1 holds 123 (= 0x7B)
    //Serial.println(data1, DEC);
    Serial.println(receivedcharsA);
    //==============================
    j = 0;
    i++;
    do
    {
      receivedcharsB[j] = myData[i];  //copy the charcaters for substring 456
      j++;
      i++;
    }
    while (myData[i] != ',');
    receivedcharsB[j] = '\0';
    Serial.println(receivedcharsB);
    //==================================
    j = 0;
    i++;
    do
    {
      receivedcharsC[j] = myData[i]; //copy the charcaters for substring 789
      j++;
      i++;
    }
    while (myData[i] != '\0');
    receivedcharsC[j] = '\0';
    Serial.println(receivedcharsC);
    //----------------------------------
    Serial.println("===========================");
  }
}

uartString.png

uartString.png

uartString.png

depending on which one of three start markers, '<', '(', '[', he copies chars into on of the three arrays until the stop marker, '>', is detected. but there are 3 different flags indicating which array is being used but the code always clears the same flag, recInProgress.

but there are 3 different flags indicating which array is being used but the code always clears the same flag, recInProgress.

receivedCharsB[ndx] = '\0'; // terminate the string
                recvInProgress = false;

receivedCharsC[ndx] = '\0'; // terminate the string
                recvInProgress = false;

I believe that the above is what gcjr is speaking of.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.