Help with converting a sting of chars to an int via toInt().

:astonished: Hello.

The aim of my code is to:
-read in a string serial and use it to determine DC motor control for a car (2 motors and a h-bridge)
EXAMPLE STRING IncomingStr = "++135"

  • from the string read in, take the first charecter: + = forwards and - = backwards directions of travel
  • from the second charecter determine if the vehicle is turning right or left or going straight + = right, - = left, 0 = straight
  • from the last 3 charecters, determine the motor speed (0-255) ***Help Needed Here ***
    THUS EXAMPLE STRING is making a forwards right hand turn at a speed of 135.

My help is needed to convert the last three characters into an int. What i have so far is to take the last three charecters of IncomingStr (that is 135)and assign that to a new string specially for the motos speed, called MotorVal.
I then attempt to perform the following:
MotorVal = IncomingInts.toInt(); //Convert Incoming Ints string to an integer.
From this an error occurs when compiling:
motor_test_emV9.ino: In function 'void loop()':
motor_test_emV9:107: error: request for member 'toInt' in 'IncomingInts', which is of non-class type 'char [4]'

It would be incredibly handy to convert MotorVal to an int as i do not want to write 255 if statements to compare MotorVal string to pre saved stings and then assign the motor value. For example, i dont want to do:
char known_motor_val[4] = "135";
if(strcmp(known_motor_val, MotorVal) == 0){
//Cont troll motor speed to 135
}

I am open to changing methods if there is a better suggestion than this.

My Code is as follows

//Please excuse if i have accidentally missed including out one of the initialization...they are all in place in my code.
char IncomingStr[7]; //Our strings must be <= 5 charecters long
char IncomingChar = -1; //We are going to append to the end of our IncommingStr
int CharIndex = 0; //An index into the array
char IncomingDir[2];
char IncomingSign[2];
char IncomingInts[4];

void loop() {		
	
	if (Serial.available() > 0){

		if(CharIndex < 6){
			IncomingChar = Serial.read();
			IncomingStr[CharIndex] = IncomingChar;  //Save the char to our list
			CharIndex ++;
			IncomingStr[CharIndex] = 0;  //Insure the next place is cleared
		}	
		
		Serial.write("Incomming str: ");              //Display the string
			for (int i = 0; i < 6; i++){
				Serial.write(IncomingStr[i]);  
			}
		Serial.println("");

                  //get the direction forwards /back
                IncomingDir[0] = IncomingStr[0];               //Select the sign from the string
               
                Serial.write("Incomming dir: ");              //Display the sign string
                        for (int i = 0; i < 2; i++){
                                Serial.write(IncomingDir[i]);  
                        }
                Serial.println("");
		
                  //get the sign to turn right/left
                IncomingSign[0] = IncomingStr[1];               //Select the sign from the string
               
                Serial.write("Incomming sign: ");              //Display the sign string
                        for (int i = 0; i < 2; i++){
                                Serial.write(IncomingSign[i]);  
                        }
                Serial.println("");

                  //Help is needed here!!
                for (int i = 0; i < 3; i++){
                        IncomingInts[i] = IncomingStr[i+2];
                }

                Serial.write("Incoming Ints: ");              //Display the sign string
                        for (int i = 0; i < 3; i++){
                                Serial.write(IncomingInts[i]);  
                        }
                Serial.println("");

                MotorVal = IncomingInts.toInt();              //Convert Incoming Ints string to an integer.
                Serial.print("MotorVal:  ");
                Serial.println(MotorVal);

Many thanks in advance

Emma :slight_smile:

                        for (int i = 0; i < 2; i++){
                                Serial.write(IncomingDir[i]);  
                        }

Or

Serial.print(incomingDir);

It would be incredibly handy to convert MotorVal to an int

Like atoi() does?

Welcome to the Forum, Emma. First, what terminates the input stream? Is it a newline character ('\n"), null ('\0'), of what? If it is always in a field of 6 characters, you might change:

void loop() {		
	
	if (Serial.available() > 0){

		if(CharIndex < 6){
			IncomingChar = Serial.read();
			IncomingStr[CharIndex] = IncomingChar;  //Save the char to our list
			CharIndex ++;
			IncomingStr[CharIndex] = 0;  //Insure the next place is cleared
		}

to

void loop() {		
	
	if (Serial.available() > 0){
            Serial.readBytesUntil('\n', incomingStr, 6);

This grabs everything and puts it in one place. Next, I would separate out the display info into it's own function, like:

void loop() {		
		
	if (Serial.available() > 0){
            Serial.readBytesUntil('\n', incomingStr, 6);
            ShowMeWhatArrived();
// more of your code...
}  // End of loop()

void ShowMeWhatArrived()
{
   incomingStr[5] = '\0';           // Make sure we can treat it as a string

   Serial.print("Direction: ");
   Serial.print(incomingStr[0]);
   Serial.print("Left-Right: ");
   Serial.print(incomingStr[1]);
   Serial.print("Magnitude: ");
   Serial.print(atoi(&incomingStr[2]));
}

Obviously I haven't tried this, but it should point you in the right direction. The only thing that may seem a little weird is the argument to atoi(). Think of the address-of operator (&) as saying: "Give me the memory address where I can find...". So, if incomingStr[] is located at memory address 1000, &incomingStr[2] fetches memory address 1002. The atoi() function then goes to that address, finds "135", and converts it from an ASCII character sequence to a 16-bit integer.

Well this worked beautifully, and it was a great explanation too. Very much appreciated :).

Something bothered me about my answer. Use this instead:

const int BUFFSIZE = 6;


void loop() {		
   int bytesRead;

   if (Serial.available() > 0){
      bytesRead = Serial.readBytesUntil('\n', incomingStr, BUFFSIZE );
      ShowMeWhatArrived();
    // more of your code...
}  // End of loop()

void ShowMeWhatArrived(int bytesRead)
{
   incomingStr[bytesRead] = '\0';           // Make sure we can treat it as a string

   Serial.print("Direction: ");
   Serial.print(incomingStr[0]);
   Serial.print("Left-Right: ");
   Serial.print(incomingStr[1]);
   Serial.print("Magnitude: ");
   Serial.print(atoi(&incomingStr[2]));
}

There...more better! Now if a one or two digit value comes in, the null is placed in the correct position.

I did something similar for servo control. I put the numeric value first, then the servo identifier. another identifier could be added and evaluated for its input.

//zoomkat 11-22-12 simple delimited ',' string parse 
//from serial port input (via serial monitor)
//and print result out serial port
//multi servos added 

String readString;
#include <Servo.h> 
Servo myservoa, myservob, myservoc, myservod;  // create servo object to control a servo 

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

  //myservoa.writeMicroseconds(1500); //set initial servo position if desired

  myservoa.attach(6);  //the pin for the servoa control
  myservob.attach(7);  //the pin for the servob control
  myservoc.attach(8);  //the pin for the servoc control
  myservod.attach(9);  //the pin for the servod control 
  Serial.println("multi-servo-delimit-test-dual-input-11-22-12"); // so I can keep track of what is loaded
}

void loop() {

  //expect single strings like 700a, or 1500c, or 2000d,
  //or like 30c, or 90a, or 180d,
  //or combined like 30c,180b,70a,120d,

  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      if (readString.length() >1) {
        Serial.println(readString); //prints string to serial port out

        int n = readString.toInt();  //convert readString into a number

        // auto select appropriate value, copied from someone elses code.
        if(n >= 500)
        {
          Serial.print("writing Microseconds: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.writeMicroseconds(n);
          if(readString.indexOf('b') >0) myservob.writeMicroseconds(n);
          if(readString.indexOf('c') >0) myservoc.writeMicroseconds(n);
          if(readString.indexOf('d') >0) myservod.writeMicroseconds(n);
        }
        else
        {   
          Serial.print("writing Angle: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.write(n);
          if(readString.indexOf('b') >0) myservob.write(n);
          if(readString.indexOf('c') >0) myservoc.write(n);
          if(readString.indexOf('d') >0) myservod.write(n);
        }
         readString=""; //clears variable for new input
      }
    }  
    else {     
      readString += c; //makes the string readString
    }
  }
}