If the numbers might be greater than 32768 you will need to use atol instead of atoi and store the result in long variables instead of int.
Have you actually tried this? The atoi() function does not know what a String is, so it has no idea how to get the characters from it.
Thanks for pointing this out, I didn't notice he was using the String class and not a character array. Personally, I don't think classes that use dynamic memory allocation - such as String - have any place on a small embedded device with only 2k of RAM.
As the String class doesn't provide a method for accessing the raw character array (unlike the proper STL std::string class), nor any methods for parsing the contents, doing the conversion isn't so straightforward. Here's another attempt, compiled but otherwise untested, and with no handling of leading minus signs or any other non-numeric characters:
unsigned int toInt(const String& s)
{
unsigned int val = 0;
for (unsigned int i = 0; i < s.length(); ++i) {
val = (10 * val) + (s.charAt(i) - '0');
}
return val;
}
...
amount = toInt(Data[0]);
...
As the String class doesn't provide a method for accessing the raw character array (unlike the proper STL std::string class), nor any methods for parsing the contents, doing the conversion isn't so straightforward.
I do believe you should have another peek at the documentation for the String class. It does provide a toCharArray() method to get at the underlying character data, and it provides methods to locate specific characters in the String (the basis for a parsing function).
As the String class doesn't provide a method for accessing the raw character array (unlike the proper STL std::string class), nor any methods for parsing the contents, doing the conversion isn't so straightforward.
I do believe you should have another peek at the documentation for the String class. It does provide a toCharArray() method to get at the underlying character data, and it provides methods to locate specific characters in the String (the basis for a parsing function).
I have looked not only at the documentation but also at the implementation. The toCharArray function requires you to allocate a buffer and therefore to know how long the string might be; that is why I rejected it. I did use one of the methods to access specific characters in the string in the solution I proposed.
The toCharArray function requires you to allocate a buffer and therefore to know how long the string might be
Knowing in advance how long the String is is not required. You can use the length function to know how big the array needs to be, then use malloc to allocate the space, extract the array, convert it to a long/int/float/whatever, then free the array.
The toInt() method makes this unnecessary, but something like this might be needed for floats/doubles.
Granted, the String class has a lot of overhead, but it does simplify, for a beginner, the process of getting a string from the Serial port.
Yes, I see now that the String class does provide a toInt method. The reason I didn't spot it before is that it is NOT documented in the reference page String() - Arduino Reference.
Granted, the String class has a lot of overhead, but it does simplify, for a beginner, the process of getting a string from the Serial port.
Yes, it makes things easier for a beginner, unless/until he/she gets strange crashes some while after the program started, due to memory allocation calls failing.
Using malloc in C/C++-based embedded systems other than during initialization is generally a bad idea.
The String class makes extensive use of the malloc function, and seems to work pretty well. Relying on malloc succeeding, without checking that it did, is a bad idea, I agree.
But, in general, if a String object contains data that atoi() or atof() are capable of processing, the char array needed to hold a copy of the data is going to be pretty small. If malloc()'s use is a concern, statically allocate a 24 byte array, and only process the String object if it is less than 24 bytes long.
PaulS:
The String class makes extensive use of the malloc function, and seems to work pretty well.
The danger is that in a long-running system that uses the String class, the heap will get fragmented to the point where eventually a malloc fails and the system crashes - especially if the programmer is using lots of arrays or string literals as well so that RAM is tight. Using the String class comes at the price of not knowing whether the system will run reliably for long periods of time.
PaulS:
Relying on malloc succeeding, without checking that it did, is a bad idea, I agree.
In an embedded system, there is often little you can do if a malloc fails, other than stop or restart the system.
dc42:
The danger is that in a long-running system that uses the String class, the heap will get fragmented to the point where eventually a malloc fails
What seems to happen in Arduino is that the brkval and stack cross, causing the stack to get smashed, and or heap contents to get corrupted. Threads that wind up with the root cause being some OOM problem are the second most common theme on these forums -- next to the "I have homework, won't someone do it for me?" theme, which is by far the most common.
There was a thread in Suggestions for the Arduino Project regarding this. I would like to see a super-lightweight trap that can use blink codes on pin 13 to report errors, and have things like a malloc() failure or an instance where the millis() interrup notices that brkval and the stack have crossed should branch there. Maybe other run-time catastrophic errors could use it, and generate unique blink codes.
I would also like to see a heuristic in the IDE where it looks at the sum of the sizes of the data, bss and largest stack frame and mentions something if the sum exceeds 70% of available memory on the target board.
gardner:
I would also like to see a heuristic in the IDE where it looks at the sum of the sizes of the data, bss and largest stack frame and mentions something if the sum exceeds 70% of available memory on the target board.
I agree - it is crazy that the IDE reports the amount of flash memory used (which rarely approaches the maximum for the atmega328) when uploading a sketch, but not the RAM. AFAIK you can't even get a map file out without hacking the IDE.