Convert amount received by the serial

Hi

I am getting the serial numbers of type char, how can I convert these values ??into integers?

My code:

char serial;

serial = Serial.read();

Thank you

Very basic servo test code that captures a numeric string sent from the serial monitor, captures the string as a String object, then converts that String into an integer for use as a servo command. may be close to what you are looking for.

//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="";
  } 
}

The simplest method is

int temp = 0; // global variable

void loop()
{
  if(Serial.available() > 0)
  {
     char serial = Serial.read();
     temp = (temp * 10) + (serial - '0');
  }
/* . . . other stuff */
}

HazardsMind:
The simplest method is

Good idea to check the received character is a decimal digit before you treat it as one.

Technically it holds up to the simplest method, because regardless of what comes in, its going to get converted to an integer (or some form of an integer).

However, as Peter said it would be a good idea to check if what came in was actually a decimal, which would then require a little more though and so it would then be a simple method.

if(Serial.available() > 0)
  {
     char serial = Serial.read();
     if( serial >= '0' || serial <= '9' ) // only digits get converted
        temp = (temp * 10) + (serial - '0');
  }

@Gillard
Note: once the integer is used for it’s purpose, it is best to set it back to zero

Say you read in a 5, it’s currently a char type so you need to make it an integer. To do this, you take whatever char comes in(preferably a digit) and subtract 48 or ‘0’ from it. 5 as a char is 53, then subtract 48 and you get 5.

Now this is when you use (temp = temp * 10).
Temp is currently 0, so it looks like this: 0 = (0 * 10) + (“incoming char”);
You add the 5 now. 5 = (0 * 10) + 5;

Ok now read in a ‘9’. Subtract 48 to give you 9.
59 = (5 * 10) + 9;

Add another char 8, subtract and now you have:
598 = (59 * 10) + 8;

If you keep reading in chars, it will keep storing them. Note an int is only so big, so if you go over 32767, you will start to get negative numbers. To fix this you can either make the variable temp “unsigned” or type long or even unsigned long.

HazardsMind:
Say you read in a 5, it's currently a char type so you need to make it an integer. To do this, you take whatever char comes in(preferably a digit) and subtract 48 or '0' from it. 5 as a char is 53, then subtract 48 and you get 5.

Now this is when you use (temp = temp * 10).
Temp is currently 0, so it looks like this: 0 = (0 * 10) + ("incoming char");
You add the 5 now. 5 = (0 * 10) + 5;

Ok now read in a '9'. Subtract 48 to give you 9.
59 = (5 * 10) + 9;

Add another char 8, subtract and now you have:
598 = (59 * 10) + 8;

If you keep reading in chars, it will keep storing them. Note an int is only so big, so if you go over 32767, you will start to get negative numbers. To fix this you can either make the variable temp "unsigned" or type long or even unsigned long.

@Gilliard
Continuing HazardsMind's logic, you probably also want to have your Arduino know when you have finished sending a number and want to start sending a new number. To do this you need to have some sort of token that you use to tell the Arduino to either start building a number from sequential digits and/or stop building a number from sequential digits.

Commonly an end token is used, either in the form of a carriage return and/or a line feed character (depending on what your system uses for an newline character or sequence when you press the return key). Using current technology, it is probably safe to just watch for the line feed character because both MS-Win systems and HTTP use the sequence carriage return then line feed, and Unix-style systems (linux, OS-X, actual unix, android, etc) use just the line feed character. Because of your check to make sure the incoming character is a digit, the carriage return character will be ignored so you can just focus on the character that is common in the two (modernly) common newline character sequences. But if you are going to be connecting to an old-school Mac running OS9 or earlier, it will use just the carriage return character (and as I recall the same thing is true about C64s)... If you can reasonably expect to connect to an old dinosaur Mac (don't laugh, the lab I just started working at has an old PC running Windows 3.1 because that is the latest OS that runs the needed software and has the proper hardware drivers for the attached expensive equipment, classic "if it works don't fix it") you may want to check for a carriage return OR a line feed.

Check this wiki page if you are interested in the history of newline character sequences.

A start token might be useful to tell the Arduino what variable the following sequence of numbers should be stored in. This is useful if you want to be able to control multiple parameters via the serial port.

Gilliard:
Do not have a simpler way to convert char into integer?

sure...

zoomkat:

Gilliard:
Do not have a simpler way to convert char into integer?

sure...

Convert amount received by the serial - #2 by zoomkat - Programming Questions - Arduino Forum

There are a few issues with your suggestion zoomkat. I'm not going to argue pro or con on the String object, I expect that from you so I would be surprised not to see it. The issues with your sketch is it makes too many assumptions about the incoming serial stream. I'm not going to bother doing the math to see if your 2ms delay is long enough, I'll assume you've already found that to be true. The assumption your code is making is that each set of digits for the numbers will be sent in a burst as fast as the serial port baudrate will allow, and there will be at least a 2ms delay between numbers (bursts of digits). Also, the error condition (i.e. a non digit character starting a new burst of serial transmission) will result in getting a value of zero. What if zero is a valid number to accept? An error transmission will be giving false values (instead of either being ignored or producing an error message).

It will work in many cases, but it just isn't robust enough for all reasonable cases.

Gilliard:
Do not have a simpler way to convert char into integer?

Save it into a c-string (null-terminated char array) and then call atoi() to parse it into an int, or atol() to parse it into a long. There are other parsing functions available if you want to parse non-decimal values, floating point values, etc.

HazardsMind:
However, as Peter said it would be a good idea to check if what came in was actually a decimal, which would then require a little more though and so it would then be a simple method.

The function isdigit() comes in handy here. IMO it would pay to think about what you want to happen if you get a non-digit in the middle of a string that you expect to contain digits.

The issues with your sketch is it makes too many assumptions about the incoming serial stream.

It works under the conditions I listed.

I'm not going to bother doing the math to see if your 2ms delay is long enough, I'll assume you've already found that to be true.

Sounds like you can't do the math, as the code works as described. Why are you whining about simple code that demonstrates the "int n = readString.toInt();" function? Did I somehow make your cornflakes taste like urine? 8)

zoomkat:

The issues with your sketch is it makes too many assumptions about the incoming serial stream.

It works under the conditions I listed.

I'm not going to bother doing the math to see if your 2ms delay is long enough, I'll assume you've already found that to be true.

Sounds like you can't do the math, as the code works as described. Why are you whining about simple code that demonstrates the "int n = readString.toInt();" function? Did I somehow make your cornflakes taste like urine? 8)

I'm sure it works under the conditions that you listed (i.e. each number sent as a burst of digits as fast as the serial port's baud rate would allow). And it isn't that I can't do the math, I just didn't bother because I trusted you enough not to intentionally post non-functional code. I was just pointing out the fragility of the code. Your code certainly won't work if the transmitting serial device (UECIDE Serial Terminal, any one of a number of standalone serial terminal emulators like Realterm, serially connected keyboard, etc) is sending multi-digit numbers one character at a time at the speed a normal person types. For robustness it is best to watch for an end token (like a newline character) instead of relying on a timeout.

No need to imagine urine flavored cornflakes. :stuck_out_tongue:

Sembazuru:
I was just pointing out the fragility of the code.

Agreed, it represents a very poor technique for handling serial input. In addition to all the flaws you have already pointed out, it needs to be hand-tuned to each serial speed and will then throttle the serial input to the speed it is tuned for, even if the serial port is configured to a higher speed subsequently. There are numerous disadvantages to this approach, and no significant advantages to it that I can see.