string Arduino 中的字符串长度有限制吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17972523/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Are there limits on string length in Arduino?
提问by Dermot
I've been trying for hours to put together a simple JSON object string on an arduino to send to a Raspberry Pi running node.
我已经尝试了几个小时在 arduino 上组合一个简单的 JSON 对象字符串以发送到 Raspberry Pi 运行节点。
I cannot seem to successfully build the string. I have tried building the string all in one go:
我似乎无法成功构建字符串。我试过一次性构建字符串:
"{" + string1 + "," + string2 + "," + string3 + "}" etc...
I've also tried using a the String.replace function. Each time I end up with a bit of my string, or none at all. The below code shows what's happening:
我也试过使用 String.replace 函数。每次我最终都会得到一些字符串,或者根本没有。下面的代码显示了正在发生的事情:
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 as the string is being built, i'm spitting it out to the 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 limit to the string length? I haven't found any mention of such limits in the docs.
There's not much else to the sketch except the standard Ethernet
library and the code to send it via an HTTP request (from the sample project).
字符串长度有限制吗?我在文档中没有发现任何提及此类限制的内容。除了标准Ethernet
库和通过 HTTP 请求(来自示例项目)发送它的代码之外,草图没有太多其他内容。
Any idea what might be happening?
知道会发生什么吗?
EDIT: Ok, I've shortened my string like so:
编辑:好的,我已经像这样缩短了我的字符串:
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 sure enough, it's started to work:
果然,它开始工作了:
{ "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 }
Which means there is a limitation. Is this a memory limitation?
这意味着有一个限制。这是内存限制吗?
By the way, the hardware is an Arduino Uno R3
顺便说一句,硬件是Arduino Uno R3
采纳答案by user2534603
Atmel processor has fairly limited memory management so its easy to end up with fragmented memory. Remember the runtime stack and heap also limited.
Atmel 处理器的内存管理相当有限,因此很容易出现内存碎片。记住运行时栈和堆也是有限的。
Static string can be put into PROGMEM also
静态字符串也可以放入 PROGMEM
There is also a freememory function on the arduino.cc that will show you how much free memory you have.
arduino.cc 上还有一个 freememory 功能,可以显示您有多少可用内存。
回答by Craig
The arduino has very limited memory -- about 2K for your data (32K for your program in flash). Under the covers the String class is doing a realloc call for every string concatenation. This could lead to fragmented memory where there isn't a single contiguous block of memory available for the string.
arduino 的内存非常有限——数据大约为 2K(闪存中的程序为 32K)。在幕后,String 类正在为每个字符串连接进行 realloc 调用。这可能会导致内存碎片化,其中没有可用于字符串的单个连续内存块。
I would suggest you stop using the String class and just allocate a large buffer at the beginning and append to it, but you will need to have an idea of how big it will be before you allocate it.
我建议你停止使用 String 类,只在开始时分配一个大缓冲区并附加到它,但在分配之前你需要知道它有多大。
If you like to live dangerously, you could look at the source code for the String class and see if you can force it to pre-allocate a large buffer, but I see no documented way to do that.
如果你喜欢危险的生活,你可以查看 String 类的源代码,看看你是否可以强制它预先分配一个大缓冲区,但我没有看到有记录的方法来做到这一点。
回答by Kaypro II
I had similar difficulties trying to build JSON using the Arduino String class. Eventually I gave up because I realized I was trying to force large system techniques onto a tiny embedded system. Now I use preallocated char arrays and C functions like sprintf for string manipulation, and I encode data in the most compact way that I can still use from my application.
我在尝试使用 Arduino String 类构建 JSON 时遇到了类似的困难。最终我放弃了,因为我意识到我试图将大型系统技术强加给一个小型嵌入式系统。现在,我使用预分配的字符数组和 C 函数(如 sprintf)进行字符串操作,并以最紧凑的方式对数据进行编码,我仍然可以在我的应用程序中使用这种方式。
You might find this linkinteresting (I didn't write it):
你可能会发现这个链接很有趣(我没有写):
Five things I never use in Arduino projects....
- The String class
On the face if it, the String class in the Arduino library makes string handling easier. It provides a host of functions to do things that you can't easily do if you represent strings as pointers to char arrays, as is usual in C. So what's the problem?
The problem is that String operations allocate memory dynamically and in ways that are hard to predict when the inputs to the program are variable, combined with the fact that Arduinos have a very limited amount of RAM (2K on the Arduino Uno). Dynamic memory allocation typically causes memory fragmentation. This means that your program may work correctly for some inputs or a short while, but crashes with other inputs or after a longer time, due to memory exhaustion. See http://critical.eschertech.com/2010/07/30/dynamic-memory-allocation-in-critical-embedded-systems/for more about why dynamic memory allocation is a bad idea in embedded software implemented in C/C++.
When might I use String? When writing a quick-and-dirty sketch to try something out, as long it doesn't have to hold together for more than a few minutes!
我在 Arduino 项目中从未使用过的五件事......
- 字符串类
从表面上看,Arduino 库中的 String 类使字符串处理更容易。它提供了许多函数来完成如果您将字符串表示为指向 char 数组的指针(就像在 C 中通常那样)就无法轻松完成的事情。那么问题是什么?
问题在于,字符串操作会动态分配内存,并且以难以预测程序输入何时可变的方式分配内存,再加上 Arduino 的 RAM 量非常有限(Arduino Uno 上为 2K)。动态内存分配通常会导致内存碎片。这意味着您的程序可能会在某些输入或短时间内正常工作,但由于内存耗尽而在其他输入或较长时间后崩溃。请参阅http://critical.eschertech.com/2010/07/30/dynamic-memory-allocation-in-critical-embedded-systems/了解更多关于为什么动态内存分配在用 C/C++ 实现的嵌入式软件中是一个坏主意的更多信息.
我什么时候可以使用字符串?当写一个快速而肮脏的草图来尝试一些东西时,只要它不必保持在一起超过几分钟!
回答by Jim C
I was having a similar problem with string length, but found in almost all cases that I was being limited by SPI buffer length of 64. Whether delays are put into the code on purpose, or there are too many print statements, I'd suggest always being mindful of possible overflows.
我在字符串长度方面遇到了类似的问题,但发现在几乎所有情况下,我都受到 SPI 缓冲区长度 64 的限制。无论是故意将延迟放入代码中,还是打印语句过多,我都建议始终注意可能的溢出。