Are there any string length restrictions in Arduino?

I tried for hours to assemble a simple string of a JSON object on arduino to send a raspberry Pi running node.

I cannot successfully generate a string. I tried to build the string in one go:

"{" + string1 + "," + string2 + "," + string3 + "}" etc... 

I also tried using the String.replace function. Every time I finish a little of my line or nothing at all. The code below shows what happens:

 String msg = "{ \"message\" : \"statusUpdate\", "; String active = " \"active\" : TOKEN, "; String intakeTemp = " \"intakeTemp\" : TOKEN, "; String intakeHumid = " \"intakeHumid\" : TOKEN, "; String exhaustTemp = " \"exhaustTemp\" : TOKEN, "; String exhaustHumid = " \"exhaustHumid\" : TOKEN, "; String targetHumid = " \"targetHumid\" : TOKEN, "; String completed = " \"taskCompleted\" : TOKEN }"; if(isActive) active.replace("TOKEN","true"); else active.replace("TOKEN","false"); intakeTemp.replace("TOKEN",floatToString(intakeTemperature,0)); intakeHumid.replace("TOKEN",floatToString(intakeHumidity,0)); exhaustTemp.replace("TOKEN",floatToString(exhaustTemperature,0)); exhaustHumid.replace("TOKEN",floatToString(exhaustHumidity,0)); targetHumid.replace("TOKEN",floatToString(targetHumidity,0)); if(taskFinished) taskCompleted.replace("TOKEN","true"); else taskCompleted.replace("TOKEN","false"); String body = msg; Serial.println(body); body += active; Serial.println(body); body += intakeTemp; Serial.println(body); body += intakeHumid; Serial.println(body); body += exhaustTemp; Serial.println(body); body += exhaustHumid; Serial.println(body); body += targetHumid; Serial.println(body); body += taskCompleted; Serial.println(body); 

You can see from the last bit of code above that when building a line, I spit it out on a serial monitor. However, here is my serial output:

 { "message" : "statusUpdate", { "message" : "statusUpdate", "active" : false, { "message" : "statusUpdate", "active" : false, "intakeTemp" : 0.0, { "message" : "statusUpdate", "active" : false, "intakeTemp" : 0.0, "intakeHumid" : 0.0, { "message" : "statusUpdate", "active" : false, "intakeTemp" : 0.0, "intakeHumid" : 0.0, "exhaustTemp" : 0.0, { "message" : "statusUpdate", "active" : false, "intakeTemp" : 0.0, "intakeHumid" : 0.0, "exhaustTemp" : 0.0, { "message" : "statusUpdate", "active" : false, "intakeTemp" : 0.0, "intakeHumid" : 0.0, "exhaustTemp" : 0.0, { "message" : "statusUpdate", "active" : false, "intakeTemp" : 0.0, "intakeHumid" : 0.0, "exhaustTemp" : 0.0, 

Is there a string length limit? I did not find mention of such restrictions in the documents. There is nothing special in the sketch, except for the standard Ethernet library and code for sending via an HTTP request (from an example project).

Any idea what could happen?

EDIT: So, I shortened my line like this:

 String msg = "{ \"m\" : \"status\", "; String active = " \"a\" : TOKEN, "; String intakeTemp = " \"iT\" : TOKEN, "; String intakeHumid = " \"iH\" : TOKEN, "; String exhaustTemp = " \"eT\" : TOKEN, "; String exhaustHumid = " \"eH\" : TOKEN, "; String targetHumid = " \"tH\" : TOKEN, "; String dryerJustFinished = " \"f\" : TOKEN }"; 

and, of course, it started working:

 { "m" : "status", { "m" : "status", "a" : false, { "m" : "status", "a" : false, "iT" : 0.0, { "m" : "status", "a" : false, "iT" : 0.0, "iH" : 0.0, { "m" : "status", "a" : false, "iT" : 0.0, "iH" : 0.0, "eT" : 0.0, { "m" : "status", "a" : false, "iT" : 0.0, "iH" : 0.0, "eT" : 0.0, "eH" : 0.0, { "m" : "status", "a" : false, "iT" : 0.0, "iH" : 0.0, "eT" : 0.0, "eH" : 0.0, "tH" : 0.0, { "m" : "status", "a" : false, "iT" : 0.0, "iH" : 0.0, "eT" : 0.0, "eH" : 0.0, "tH" : 0.0, "f" : false } 

This means that there is a limitation. Is this a memory limit?

By the way, the hardware of the Arduino Uno R3

+4
source share
4 answers

The Atmel processor has fairly limited memory management, so it's easy to end up with fragmented memory. Remember that runtime stacks and heaps are also limited.

Static string can also be placed in PROGMEM

Arduino.cc also has a freememory function that will show you how much free memory you have.

+2
source

Arduino has very limited memory - about 2K for your data (32K for your program in Flash). Under the covers, the String class makes a realloc call for each string concatenation. This can lead to fragmented memory, where a single continuous block of memory does not exist for a row.

I would suggest you stop using the String class and just allocate a large buffer at the beginning and add to it, but you will need to understand how big it will be before you allocate it.

If you like living dangerously, you can look at the source code for the String class and see if you can get it to pre-allocate a large buffer, but I don't see a documented way to do this.

+4
source

I had similar difficulties trying to create JSON using the Arduino String class. In the end, I gave up because I realized that I was trying to force large system methods onto a tiny embedded system. Now I use preallocated char arrays and C functions such as sprintf to manipulate strings, and I encode the data in the most compact way that I can still use from my application.

You can find this link interesting (I did not write it):

Five things that I never use in Arduino projects ....

  • String class

On the face, if it is, the String class in the Arduino library simplifies string handling. It provides many functions to do simple things if you present strings as pointers to char arrays, as usual in C. So what is the problem?

The problem is that String operations allocate memory dynamically and in ways that are difficult to predict when program inputs are variable, combined with the fact that Arduinos has a very limited amount of RAM (2K on Arduino Uno). Dynamic memory allocation usually causes memory fragmentation. This means that your program may work correctly for some inputs or for a short time, but a failure with other inputs or after a longer time due to exhaustion of memory. See http://critical.eschertech.com/2010/07/30/dynamic-memory-allocation-in-critical-embedded-systems/ for more information on why dynamic memory allocation is a bad idea in firmware implemented in C / C ++.

When can I use String? When you write a quick and dirty sketch to try something, until it sticks together for more than a few minutes!

+2
source

I had a similar problem with line length, but in almost all cases I was limited by the length of the SPI 64 buffer. Whether there are delays in the code or too many print statements, I’d suggest you always remember about possible overflows.

0
source

Source: https://habr.com/ru/post/1494514/


All Articles