2

I'm currently writing and testing a professional Arduino application, I'm aware of the dangers of using the String class, so I began to implement C-style strings in some places, but it's just way harder using them to receive data from a Software Serial port that's variable in size and needs some manipulation.

I've upgraded from an Arduino Uno to a Leonardo so my current minimum SRAM usage is 1325 bytes (51%)

Here's the relevant part of my code:

String serialContents;
char emailChar[SIZEOF_ARRAY][SIZEOF_CHAR];

void setup(){ 
  serialContents.reserve(70);
  SerialOne.begin(9600);
}

void loop{

  if (SerialOne.available() > 0) //something is there to be read
  {
    serialContents = SerialOne.readStringUntil('\n'); //make a string of the characters coming on serial
  }

  if (serialContents.length() >= 60)
  {
   serialContents = ""; //ignore serial data
  }
 else{
  serialContents = cutString(serialContents); //some String manipulation, no adding only cutting
  serialContents.replace("@", "%40");   
  serialContents.toCharArray(emailChar[count], 31); 
  serialContents = ""; //String reset
}

So my question is, does something like this make my code unstable? Does the reserve() function help at all?

Edit: Here's the cutString() function

String cutString(String request) {

  int points = request.indexOf(':');

  if (request.substring(0, points) == "CHECKOUT")
  {
    modoPedido[count] = 'o'; //char array
  }
  else if (request.substring(0, points) == "CHECKIN")
  {
    modoPedido[count] = 'i';
  }

  request = request.substring(points + 1);

  return request;
}
  • there is readBytesUntil if you want a convenient function for c-string – Juraj Mar 23 '18 at 5:19
4

Reserving space will help reduce memory fragmentation, but much of what else you are doing is swamping that small improvement you have made.

The biggest area of concern is your cutString function, which you have omitted from your code above. Passing a String as a parameter, modifying it, and then returning it again, ends up in new String objects being created and destroyed multiple times, which will make a mess of your heap.

Instead you should pass a String object by reference, and modify that object in-place. No need to return anything.

void cutString(String &theString) {
    // Modify theString here.
}

Of course, what you do in cutString could cause more problems - you should include that function in your code above so we can check it out.

  • Thanks! I've updated the first post. Damn, I think I'm creating at least three more String objects with the substring() function. I guess I'll use other way to see if the string contains checkin or checkout like indexOf(), and use the reference method instead of returning the String object. – Jorge Gonçalves Mar 22 '18 at 20:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.