Serial input/output of string of numbers - error in code?

Hello,

I’m using an Arduino UNO R3 and Arduino IDE 1.8.10 to run this sample code from the Serial Input Basics - updated thread by Robin2 https://forum.arduino.cc/index.php?topic=396450.msg2727728#msg2727728 (example 4) to send a string of integer numbers and then receiving the same number. However, there is a problem with this code as it only works for a string of up to 4 numbers but gives wrong received values if the string input consists of 5 numbers or more.

Untouched example code from the ‘Serial Input Basics - updated’ thread:

// Example 4 - Receive a number as text and convert it to an int

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;

int dataNumber = 0;             // new for this version

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

void loop() {
    recvWithEndMarker();
    showNewNumber();
}

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '\n';
    char rc;
   
    if (Serial.available() > 0) {
        rc = Serial.read();

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

void showNewNumber() {
    if (newData == true) {
        dataNumber = 0;             // new for this version
        dataNumber = atoi(receivedChars);   // new for this version
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        Serial.print("Data as Number ... ");    // new for this version
        Serial.println(dataNumber);     // new for this version
        newData = false;
    }
}

numChars has been set to 32, so it should allow up to 32 characters or 32 numbers in a string? I think the problem lies within these lines from the sample code above, which don’t make sense to me:

if (ndx >= numChars) {
    ndx = numChars - 1;
}

Sample input/output from Serial Monitor:

<Arduino is ready>
This just in ... 415
Data as Number ... 415
This just in ... 1452
Data as Number ... 1452
This just in ... 98563
Data as Number ... -32509
This just in ... 4158
Data as Number ... 4158
This just in ... 987456
Data as Number ... 4416
This just in ... 123456
Data as Number ... -7616
This just in ... 4598965
Data as Number ... 11445
This just in ... 45252
Data as Number ... -20284
This just in ... 4525
Data as Number ... 4525
This just in ... 85
Data as Number ... 85
This just in ... 456
Data as Number ... 456

Other than pointing out this bug in the sample code (since the source thread is apparently quite popular and used as reference by many other Arduinoids), my objective is to make the code limit the string input to 6 numbers and give an error to the user if a string of more than 6 numbers is inputted and then allow to re-enter the numbers again.

Please give an example of a number that you enter that "does not work" and describe what happens

The lines of code that you posted are designed to prevent the array index going out of bounds and are correct. Have you by any chance changed the declaration of numChars in your code ?

UKHeliBob:
Please give an example of a number that you enter that "does not work" and describe what happens

The lines of code that you posted are designed to prevent the array index going out of bounds and are correct. Have you by any chance changed the declaration of numChars in your code ?

Hi UKHeliBob,

Thank you for your reply. I was still editing my thread to add the sample output copied from my Arduino IDE Serial Monitor. I have not changed anything in the code. I simply copied and pasted it into a new sketch and compiled and uploaded it to my Arduino UNO R3.

since you defined dataNumber as an int, it has range of -32768 to 32767 (16 bits)
you can define dataNumber as long (32-bits)

gciurpita:
since you defined dataNumber as an int, it has range of -32768 to 32767 (16 bits)
you can define dataNumber as long (32-bits)

Sample input/output:

<Arduino is ready>
This just in ... 145
Data as Number ... 145
This just in ... 5254
Data as Number ... 5254
This just in ... 45896
Data as Number ... -19640
This just in ... 414526
Data as Number ... 21310

gciurpita:
since you defined dataNumber as an int, it has range of -32768 to 32767 (16 bits)
you can define dataNumber as long (32-bits)

I presume that you changed the code. If so, please post your new version

Note that you will need to change this line

dataNumber = atoi(receivedChars);   // new for this version

to

dataNumber = atol(receivedChars);   // new for this version - convert to a long

as well as declaring dataNumber as a long