String to int Example

I'm a beginner with C/C++ code so I'm working through "examples" given under "Learning". One of these called 'String to Int' doesn't seem to work if I cut and paste it into the compiler. Here is the code

/*
  String to Integer conversion
 
 Reads a serial input string until it sees a newline, then converts
 the string to a number if the characters are digits.
 
 The circuit:
 No external components needed.
 
 created 29 Nov 2010
 by Tom Igoe
 
 This example code is in the public domain.
 */

String inString = "";    // string to hold input

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  // send an intro:
  Serial.println("\n\nString toInt():");
  Serial.println();
}

void loop() {
  // Read serial input:
  while (Serial.available() > 0) {
    int inChar = Serial.read();
    if (isDigit(inChar)) {
      // convert the incoming byte to a char
      // and add it to the string:
      inString += (char)inChar;
    }
    // if you get a newline, print the string,
    // then the string's value:
    if (inChar == '\n') {
      Serial.print("Value:");
      Serial.println(inString.toInt());
      Serial.print("String: ");
      Serial.println(inString);
      // clear the string for new input:
      inString = "";
    }
  }
}

I think what is wrong is that it should have an #include< ctype.h> to get the isDigit to work but I've tried this and still get no output from the serial monitor after entering numbers in. I thought that the ctype library was included anyway so maybe it is the inString.toInt which is at fault. Could anyone please suggest a reason why this snippet fails to run? Thank you

What out put do you get and what input did you give it?

Mark

I'm not a big fan of using the String class on an Arduino. Your code compiles to 4524 bytes and doesn't work. Try the following:

char inString[10];

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  // send an intro:
  Serial.println("\n\nString toInt():");
  Serial.println();
}

void loop() {
  byte inChar;
  // Read serial input:
  while (Serial.available() > 0) {
    inChar = Serial.readBytesUntil('\n', inString, 10);
    inString[inChar] = '\0';
    Serial.print("Value:");
    Serial.println(atoi(inString));
    Serial.print("String: ");
    Serial.println(inString);
  }
}

It compiles to 2830 bytes and does work.

What is the serial monitor line ending?

Mark

Thanks for your reply. I put a string of digits in but got nothing out.

Hi AWOL
The serial monitor just displays string toInt(): and that's it . I just feed in numbers.

What is the serial monitor's line ending set to?

Thank you Econjack the mod you gave to the code gave me what I expected. I'll study it.

Sorry Awol
It was set to "no line ending".

if (inChar == '\n') {

Thought so.

A very basic example of converting a String to an integer.

//zoomkat 7-30-10 serial servo test
//type servo position 0 to 180 in serial monitor

String readString;
#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 

void setup() {
  Serial.begin(9600);
  myservo.attach(9);
  Serial.println("servo-test"); // so I can keep track of what is loaded
}

void loop() {

  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    readString += c; //makes the String readString
    delay(2);  //slow looping to allow buffer to fill with next character
  }

  if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured String 
    int n = readString.toInt();  //convert readString into a number
    myservo.write(n);
    readString="";
  } 
}

Hi AWOL
Yep you're right. It needs to be set to newline at bottom right. First time I've noticed this drop down option. Thanks. Sorry but I'm new to the Arduino.

Hi Zoomcat

Thanks for your reply. I've been working on serial comms for a few days and your code is interesting. I'm using Liberty basic to send characters(digits) to be read as integers to the arduino. In your code, do you assume there are delays between the sent group of characters? Otherwise in the last 'if' the code would keep outputting a list of numbers. I.e. it relies on the sent information to have delays between packets of digits or different strings representing integers sent.

Many thanks

In my original query I wondered about the ctype.h library. It looks like AWOL has shown that it is. Am I correct here?

In my original query I wondered about the ctype.h library. It looks like AWOL has shown that it is. Am I correct here?

I wouldn't say so. Of course, I can't figure out what you are saying.

I don't think my replies have anything to do with the presence or absence of that header file.

What I meant to say was that in my original query I wondered about whether the ctype.h library is already included in the arduino current version. It looks like AWOL has shown that it is included because with correct line endings set in the serial monitor, the sketch I originally sent works along with isDigit which I think comes from this library?

DrPrince:
Thanks for your reply. I've been working on serial comms for a few days and your code is interesting. I'm using Liberty basic to send characters(digits) to be read as integers to the arduino. In your code, do you assume there are delays between the sent group of characters? Otherwise in the last 'if' the code would keep outputting a list of numbers. I.e. it relies on the sent information to have delays between packets of digits or different strings representing integers sent.

The example code I posted is very simple and somewhat limited using a delay. The best way to send serial data is to use a delimiter like below to mark the end of the data packet.

//zoomkat 3-5-12 simple delimited ',' string parse 
//from serial port input (via serial monitor)
//and print result out serial port

String readString;
#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 

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

  myservo.writeMicroseconds(1500); //set initial servo position if desired
  myservo.attach(7);  //the pin for the servo control 
  Serial.println("servo-delomit-test-22-dual-input"); // so I can keep track of what is loaded
}

void loop() {

  //expect a string like 700, or 1500, or 2000,
  //or like 30, or 90, or 180,

  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      if (readString.length() >0) {
        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);
          myservo.writeMicroseconds(n);
        }
        else
        {   
          Serial.print("writing Angle: ");
          Serial.println(n);
          myservo.write(n);
        }

        //do stuff with the captured readString 
        readString=""; //clears variable for new input
      }
    }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

Thanks Zoomcat the delimiting idea is great.

Thanks to all who answered. I'd still like to know how Arduino knows how to deal with isDigit. It's not mentioned in the reference section - unless I've missed it.

A new-line character is a delimiter. :wink: