Array giving letter instead of second number in serial.read

Hello,

So while working on an array that can store multiple numbers, I came across a strange error I have not seen before.

In the image attached you will see the problem.

I would like to know how the serial read changes my 1,100 into a B, since I cannot find anything relate able on the interwebs that I can use as reference.

Can someone please give me a few pointers or explain to me where I screwed up with the code?

Thank you in advance!

char coupeNumberChar[4];
char numberOfPeopleChar[4];
int ByteReceived;
bool checkingCoupeNumber = true;
int counter = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (Serial.available() > 0)
  {
    checkingCoupeNumber = false;
    while (Serial.available() > 0) {
      Serial.println("reading");
      ByteReceived = Serial.read();
      delay(50);
      if (ByteReceived == '#') {
        checkingCoupeNumber = true;
      }
      else if (ByteReceived == '%') {
        return;
      }
      else if (checkingCoupeNumber && ByteReceived != ',') {
        coupeNumberChar[counter] += ByteReceived;
        Serial.print("recieved char: ");
        Serial.println(coupeNumberChar[counter]);
        counter++;
      }
      else if (ByteReceived == ',') {
        checkingCoupeNumber = false;
        coupeNumberChar[counter] = '\0';
        counter = 0;
      }
      else if (!checkingCoupeNumber) {
        numberOfPeopleChar[counter] += ByteReceived;
        Serial.print("recieved char: ");
        Serial.println(numberOfPeopleChar[counter]);
        counter++;
      }
    }
    numberOfPeopleChar[counter] = '\0';
    counter = 0;
    for (int i = 0; i < 3; i++) {
      Serial.print(coupeNumberChar[i]);
      Serial.print(", ");
    }
    Serial.println("");
    for (int i = 0; i < 3; i++) {
      Serial.print(numberOfPeopleChar[i]);
      Serial.print(", ");
    }
    Serial.println("");
    int coupeNumber = atoi(coupeNumberChar);
    Serial.println(coupeNumber);
    int numberOfPeople = atoi(numberOfPeopleChar);
    Serial.println(numberOfPeople);
    memset(coupeNumberChar, 0, sizeof(coupeNumberChar));
    memset(numberOfPeopleChar, 0, sizeof(numberOfPeopleChar));
  }

}

Edit: I think personally that the error happens with the memset(); function, so I’ll be checking out if changing that will fix the problem (or at least clarify the number to letter bug)

Edit 2: After making some changes in the code I discovered that the memset (the function that sets the values to 0) is no the culprit, but rather the atoi();

int ByteReceived;

It is a dumb idea to use a type in a name (byte) that is not the type OF the variable. This should be called IntReceived, which you can well imagine is a dumb name. Therefore, the type of the variable is obviously wrong.

Nowhere in your code do you make certain that there is room in the array for the new character (hint) before you add the new character to the end of the array.

      else if (!checkingCoupeNumber) {
        numberOfPeopleChar[counter] += ByteReceived;
        Serial.print("recieved char: ");
        Serial.println(numberOfPeopleChar[counter]);
        counter++;
      }
    }
    numberOfPeopleChar[counter] = '\0';

You are printing the "received char" message 4 times, and then writing into the next (5th) position of a 4 element array. Oops.

Absolutely nothing that happens after you sh*t on memory you don't own can be considered wrong.

A few things:

You have ByteReceived declared as an int, usually that would be a char because you are receiving ascii characters over the serial line.

"return" is normally used in functions, not the main loop. Where you are using it is also causing problems, because it doesn't just get you out of the nested IF statements, or the WHILE loop, but all the way out of the initial "if (Serial.available() > 0)" .

I don't think the following lines of code are doing what you intend. The += adds the value of ByteReceived to whatever is currently in array[counter], and stores the result in array[counter]. This can give you the odd result of a 'b' character when the input is typed in twice without clearing the array in between, because 1 in ascii is the number 49, and 49+49 = 98, which is ascii b.

coupeNumberChar[counter] += ByteReceived;
numberOfPeopleChar[counter] += ByteReceived;

david_2018:
A few things:

You have ByteReceived declared as an int, usually that would be a char because you are receiving ascii characters over the serial line.

“return” is normally used in functions, not the main loop. Where you are using it is also causing problems, because it doesn’t just get you out of the nested IF statements, or the WHILE loop, but all the way out of the initial “if (Serial.available() > 0)” .

I don’t think the following lines of code are doing what you intend. The += adds the value of ByteReceived to whatever is currently in array[counter], and stores the result in array[counter]. This can give you the odd result of a ‘b’ character when the input is typed in twice without clearing the array in between, because 1 in ascii is the number 49, and 49+49 = 98, which is ascii b.

coupeNumberChar[counter] += ByteReceived;
numberOfPeopleChar[counter] += ByteReceived;

So that is where it goes wrong, I already started googling about Ascii conversions and the Atoi function.

Also, what would be a good solution to the return function in the first while loop?

I will create 2 new variables that will temporarily store the Byte values, and then put the values into the two arrays[counter]

PaulS:

int ByteReceived;

It is a dumb idea to use a type in a name (byte) that is not the type OF the variable. This should be called IntReceived, which you can well imagine is a dumb name. Therefore, the type of the variable is obviously wrong.

Nowhere in your code do you make certain that there is room in the array for the new character (hint) before you add the new character to the end of the array.

      else if (!checkingCoupeNumber) {

numberOfPeopleChar[counter] += ByteReceived;
       Serial.print("recieved char: ");
       Serial.println(numberOfPeopleChar[counter]);
       counter++;
     }
   }
   numberOfPeopleChar[counter] = ‘\0’;



You are printing the "received char" message 4 times, and then writing into the next (5th) position of a 4 element array. Oops.

Absolutely nothing that happens after you sh*t on memory you don't own can be considered wrong.

Yeah I saw the int variable, and changed it already.
While waiting for some help and pointers I am also working with fixing the code.

Should I make the array bigger then? double the byte amount?

Also, if I would like to make the people counter one number, should I make a separate parse method that combines the first number to the second to the third, etc or should I put it at the bottom of the serial read function?

Thanks again for the help guys!

Code version 2(Changes I have applied before and after your feedback and critique):

char coupeNumberChar[4];
char numberOfPeopleChar[4];
char ByteReceived;
bool checkingCoupeNumber = true;
int counter = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (Serial.available() > 0)
  {
    checkingCoupeNumber = false;
    while (Serial.available() > 0) {
      Serial.println("reading");
      ByteReceived = Serial.read();
      delay(50);
      if (ByteReceived == '#') {
        checkingCoupeNumber = true;
      }
      else if (ByteReceived == '%') {
        return;
        
      }
      else if (checkingCoupeNumber && ByteReceived != ',') {
        coupeNumberChar[counter] = ByteReceived;
        Serial.print("recieved char: ");
        Serial.println(coupeNumberChar[counter]);
        counter++;
      }
      else if (ByteReceived == ',') {
        checkingCoupeNumber = false;
        coupeNumberChar[counter] = '\0';
        counter = 0;
      }
      else if (!checkingCoupeNumber) {

        numberOfPeopleChar[counter]  =ByteReceived;
        Serial.print("recieved char: ");
        Serial.println(numberOfPeopleChar[counter]);
        counter++;
      }
    }
    numberOfPeopleChar[counter] = '\0';
    counter = 0;
    for (int i = 0; i < 3; i++) {
      Serial.print(coupeNumberChar[i]);
      Serial.print(", ");
    }
    Serial.println("");
    for (int i = 0; i < 3; i++) {
      Serial.print(numberOfPeopleChar[i]);
      Serial.print(", ");
    }
    Serial.println("");
    int coupeNumber = atoi(coupeNumberChar);
    Serial.println(coupeNumber);
    int numberOfPeople = char(numberOfPeopleChar);
    Serial.println(numberOfPeople);
     memset(coupeNumberChar, 0, sizeof(coupeNumberChar));
    memset(numberOfPeopleChar, 0, sizeof(numberOfPeopleChar));
  }


}

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

…R

Robin2:
Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

...R

Hello Robin,

I already read that a few times, and with the knowledge from that I made this script.

(I haven't worked a lot with C yet, Mostly in C#)

But thanks again for the tip, maybe I have overseen something simple.

Have a nice day!

char ByteReceived;

You are still using a type in a name that is not the type of the name. Why?

PaulS:

char ByteReceived;

You are still using a type in a name that is not the type of the name. Why?

O, forgot to change the name, sorry for the confusion.
Changed it to a byte ByteReceived.

Thanks for the tip

Changed it to a byte ByteReceived.

You are then storing the contents of that variable in a char array. What is wrong with this picture?

Is it REALLY so hard to type:

char charReceived;

PaulS:
You are then storing the contents of that variable in a char array. What is wrong with this picture?

Is it REALLY so hard to type:

char charReceived;

O, sorry for my misunderstanding, I thought you meant the type name.

I changed all occurrences now into char CharReceived

Again sorry for the misunderstanding and thanks for pointing it out.

Dandekiller:
Hello Robin,

I already read that a few times, and with the knowledge from that I made this script.

The idea behind my tutorial is that you can just include the appropriate function from my code into your program.

...R

Robin2:
The idea behind my tutorial is that you can just include the appropriate function from my code into your program.

...R

I know, but if I just copy paste someone else function without trying to do it myself then I won't learn as much.
I learn the most through trial and error, and feedback (Tips and & Tops from other people)

Still thanks for the explanation and tutorial!