String Arduino中的字符串长度有限制吗?
几个小时以来,我一直试图在arduino上组合一个简单的JSON对象字符串,以发送到Raspberry Pi运行节点 我似乎无法成功地构建字符串。我已经尝试过一次建成字符串:String Arduino中的字符串长度有限制吗?,string,arduino,String,Arduino,几个小时以来,我一直试图在arduino上组合一个简单的JSON对象字符串,以发送到Raspberry Pi运行节点 我似乎无法成功地构建字符串。我已经尝试过一次建成字符串: "{" + string1 + "," + string2 + "," + string3 + "}" etc... 我还尝试使用String.replace函数。每一次,我都会得到一点字符串,或者根本没有。 下面的代码显示了发生的情况: String msg = "{ \"message\" : \"statusUpd
"{" + string1 + "," + string2 + "," + string3 + "}" etc...
我还尝试使用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);
您可以从上面的最后一段代码中看到,在构建字符串时,我会将其输出到串行监视器。但是,以下是我的串行输出:
{ "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,
字符串长度有限制吗?我在文档中没有发现任何关于此类限制的提及。
除了标准的以太网
库和通过HTTP请求发送它的代码(来自示例项目),草图中没有其他内容
知道会发生什么吗
编辑:
好的,我把我的绳子缩短成这样:
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 }";
果然,它开始起作用了:
{ "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 }
这意味着有一个限制。这是内存限制吗
顺便说一下,硬件是Arduino Uno R3Arduino的内存非常有限——大约2K用于存储数据(32K用于闪存中的程序)。在封面下,String类正在为每个字符串连接执行realloc调用。这可能导致内存碎片,其中没有一个连续的内存块可用于字符串 我建议您停止使用String类,只在开始时分配一个大的缓冲区并附加到它,但在分配它之前,您需要知道它会有多大
如果你想过一种危险的生活,你可以看看String类的源代码,看看是否可以强制它预先分配一个大的缓冲区,但我看不到有文档记录的方法来做到这一点。Atmel处理器的内存管理相当有限,因此很容易导致内存碎片。请记住,运行时堆栈和堆也是有限的 静态字符串也可以放入PROGMEM中
arduino.cc上还有一个freememory函数,可以显示您有多少可用内存。我在尝试使用arduino字符串类构建JSON时遇到了类似的困难。最终我放弃了,因为我意识到我试图将大型系统技术强加给一个小型嵌入式系统。现在,我使用预分配的字符数组和sprintf等C函数进行字符串操作,并以我仍然可以从应用程序中使用的最简洁的方式对数据进行编码 你可能会觉得有趣(不是我写的): 我在Arduino项目中从未使用过的五件事
我在字符串长度方面也有类似的问题,但发现几乎所有情况下我都受到SPI缓冲区长度64的限制。无论是故意在代码中添加延迟,还是有太多的打印语句,我建议您始终注意可能的溢出。快速愚蠢的问题:您连接的任何字符串中都没有未转义的字符串定界符吗?不幸的是,没有。从我的编辑中可以看出,它在我缩短键名(“message”到“m”,“exhaustTemp”到“eT”等)后开始工作,因此它显然是一个字符串长度问题,或者至少是一个问题本身。尽管这里的所有答案都是正确的和有用的,您对freememory函数的引用帮助我确认它肯定是错误的原因。