Converting Char Array[] into int

Hello people (I assume that you are all people and that skynet is still in development stages)

Ok i've run into a issue converting some data and combined with this insufferable heat it's left me bereft of brain power. I am sure its a really simple fix but ive gone screen blind from staring at it too long.

char receivedChars[M,1,4]; // Char Array of received data
static byte ndx = 3; // index size of current array
int     mode = 0; // Animation mode index


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

void loop() {
  recvWithStartEndMarkers(); // Receive BT serial data
  showNewData(); // Use BT serial Data                    
}

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char IncomingChar;
 
    while (HM10.available() > 0 && newData == false) {
        IncomingChar = HM10.read();

        if (recvInProgress == true) { // If receiving
            if (IncomingChar != endMarker)  { // if incoming is not line end marker
                receivedChars[ndx] = IncomingChar; // index chars in array 
                ndx++; // increase index number
                if (ndx >= numChars) { // if index exceeds byte limit
                    ndx = numChars - 1; // set index to re-write over last char in array
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string 
                recvInProgress = false; 
                //ndx = 0; //reset index value
                newData = true; // enable data release
            }
        }

        else if (IncomingChar == startMarker) { /// if string start marker found
            recvInProgress = true; // enable data copy proccess
//            Serial.println(recvInProgress);
        }
    }
}

void showNewData() { /// Find values in received Data
    if (newData == true) {
//        char NewData = receivedChars ;
        Serial.print("This just in ... ");
        Serial.println(receivedChars);

        
        if (receivedChars[0] == 77){ // if mode char found        
//          int what = atoi(&receivedChars[1]);
//          what += atoi(&receivedChars[2]);          
//           Serial.print(what); // print mode result
          mode = 0;
          for (int i = 1; i < ndx; i++){ // from 1 to ndx length 
            mode += atoi(&(receivedChars[i])); 
          }
          
          Serial.print("ndx:"); // print mode result
          Serial.println(ndx); // print mode result          
          Serial.print("mode:"); // print mode result
          Serial.println(mode); // print mode result
        }
        
        else if (receivedChars[0] == 'S'){ // if speed char found
          
        }        
        else if (receivedChars[0] == 'V'){ // if brightness char found
          
        }
        else if (receivedChars[0] == 'R'){ // if red char found
          
        }        
        else if (receivedChars[0] == 'G'){ // if green char found
          
        }
        else if (receivedChars[0] == 'B'){ // if blue char found
          
        }
        
        newData = false;
    }
}

This script should be converting a "Char Array" of "ndx" size, Checking the character of 0 index. Then Ignoring the 0 index, Converting what is left from ASCII to a single Int from 0 to 100+.

I anyone has a better function instead of "atoi" for doing the conversion please could you leave some example code so i can see how it is meant to be used.

Kind regards,
Someguyfromtheinterwebs

doesn't atoi() expect a C-style NUL-terminated string?

  1. What is it? char receivedChars[M,1,4];
  1. 'mode' was not declared in this scope
  1. void setup() {} Where is "Serial.begin(xxxx); ?

Hey thanks for the replies. I cut down the code as the whole thing is 350+ lines. But i have no edited the code to add the missing values/functions.

"char receivedChars" is a character array that is populated inside void recvWithStartEndMarkers()

void recvWithStartEndMarkers() is a copy almost word for word of example 3 here It is a non blocking hardware serial reader which i've changed to use softwareserial.h

You may well be correct. I didn't research the function correctly as its about 35 degrees by my pc at the moment.
The recvWithStartEndMarkers() concatinates a null onto the array.

receivedChars[ndx] = '\0'; // terminate the string 

Whether that null is the same as a C-style Null i have no clue.

Your question about Null terminated strings got me searching on the right path. Thank you.
The solution. Might be a bug or intended usage. but it seems atoi will convert upwards from a specified index number.


        if (receivedChars[0] == 77){ // if mode char found        
          mode = atoi(&receivedChars[1]); /// convert chars from (Index 1) to (Index containing Nul)
          
          Serial.print("ndx:"); // print mode result
          Serial.println(ndx); // print mode result          
          Serial.print("mode:"); // print mode result
          Serial.println(mode); // print mode result
        }

If you have a string "12345", then from index 1 ("2345") is still a string

atoi will stop at the first non-digit character it gets. What you are doing here is passing a pointer to the second element in the string. atoi sees a string that starts there.

This would also work:
mode = atoi(receivedChars + 1);

1 Like

A simple way to convert an ascii digit to an int is to subtract 48, which is the ascii value of '0'.

mode = (receivedChars[1] - 48) *10 + (receivedChars[2] - 48)

1 Like

That is painfull to know now that i've spent this much time on it

:laughing:

For clarity, we normally write it

mode = (receivedChars[1] - '0')
1 Like

Yes, it is.

Not quite: it starts at the address (a pointer) you give it, and works on from there.

This is how C strings work.

Documentation of atoi():

https://cplusplus.com/reference/cstdlib/atoi/

I suggest that you bookmark https://cplusplus.com/ - it is an excellent reference for this kind of thing (despite the name, id does cover both C and C++)

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