Serial read integer?

Hey,

I need to read in an integer for a program. I think I figured out the code to do it, but I don’t have an arduino handy to test it on. Let me know what you think of this function:

int function readInt()
{
      int tmp;

      //read in an integer.
      tmp = Serial.read();
      tmp = tmp << 8;
      tmp |= Serial.read();
      
      return tmp;
}

Also, it seems like something like this should be a part of the Serial library. Any thoughts on that? It might also be nice to have a readLong() function as well.

~Hoeken

There seem to be a lot of different cases in which people need to compose two bytes into a word, or split up a word into its bytes. Rather than creating int versions of lots of functions, I've been thinking about adding a few functions:

low = lowByte(w) high = highByte(w) w = makeWord(high, low)

What do you think?

I think those functions would be nice, but its rather verbose. Even if they are there, I'm sure that many people, including myself are just going to write our own readInt() functions. you could always create those functions, and then use them in the background of the Serial.readInt() function.

what other data types are 2 bytes that are commonly used?

at the very least, it would make sense for the Serial.print() to mirror the capability of Serial.print() in what data types it can handle.

aside from that, does my code look right?

Hoeken,

Are you talking reading serial input from the terminal? For example, if user type 8540 in Arduino’s Serial Monitor then you want to receive in as one integer 8540, not 4 different bytes. Notice I say Arduino’s Serial Monitor because it can send multiple bytes at once unlike Hyperterminal that send one character as soon as you type. If I understand you correct, you code doesn’t work.

Here is what I come up with (only work for positive int, but with minor mod. it would work with neg. as well):

int serReadInt()
{
int i, serAva; // i is a counter, serAva hold number of serial available
char inputBytes [7]; // Array hold input bytes
char * inputBytesPtr = &inputBytes[0]; // Pointer to the first element of the array

if (Serial.available()>0) // Check to see if there are any serial input
{
delay(5); // Delay for terminal to finish transmitted
// 5mS work great for 9600 baud (increase this number for slower baud)
serAva = Serial.available(); // Read number of input bytes
for (i=0; i<serAva; i++) // Load input bytes into array
inputBytes = Serial.read();
_ inputBytes = ‘\0’; // Put NULL character at the end_
* return atoi(inputBytesPtr); // Call atoi function and return result*
* }*
* else*
* return -1; // Return -1 if there is no input*
}
If anyone can optimize this code please reply. Many thanks!

Hi coolguy, it looks like the posts above were discussing sending 16 bit values as two binary bytes rather than as strings.

The functionality to convert numbers back and forth as serial strings needs to be handled with care on both the sending and receiving side to ensure that the transmissions remain in sync. Using time delays to ensure that all chars are available can cause bugs if one side or the other happens to be busy with higher priority tasks and delays sending the data.

IMHO, the functionality to do this is useful, but is application dependent and should sit above the core serial library.

BTW, a powerful way of handling binary data on a serial stream is through a serialization class. If you are interested in this topic, an FAQ that covers this is here: Serialization and Unserialization, C++ FAQ


Mellis, I like the low level functionality you proposed
low = lowByte(w)
high = highByte(w)
w = makeWord(high, low)

I would expect this would allow a 16 bit value to be returned as follows:
w = makeWord(Serial.read(),Serial.read()) ;