Arduino的字符串长度是否有限制?

时间:2013-07-31 13:59:54

标签: string arduino

我已经花了好几个小时在arduino上组合一个简单的JSON对象字符串,以发送到Raspberry Pi运行节点。

我似乎无法成功构建字符串。我试过一次性构建字符串:

"{" + 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, 

字符串长度是否有限制?我没有在文档中提到任何这种限制。 除了标准Ethernet库和通过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 R3

4 个答案:

答案 0 :(得分:6)

arduino的内存非常有限 - 数据大约为2K(闪存中的程序为32K)。在封面下,String类正在为每个字符串连接执行realloc调用。这可能会导致内存碎片,而字符串中没有一个连续的内存块。

我建议你停止使用String类,只是在开始时分配一个大缓冲区并附加到它上面,但是你需要知道它在分配之前会有多大。

如果您喜欢危险地生活,您可以查看String类的源代码,看看是否可以强制它预先分配一个大缓冲区,但是我没有记录这样做的方法。

答案 1 :(得分:3)

Atmel处理器具有相当有限的内存管理,因此很容易以碎片内存结束。请记住,运行时堆栈和堆也是有限的。

静态字符串也可以放入PROGMEM

arduino.cc上还有一个freememory函数可以显示你有多少可用内存。

答案 2 :(得分:3)

尝试使用Arduino String类构建JSON时遇到了类似的困难。最终我放弃了,因为我意识到我试图将大型系统技术强加到一个小型嵌入式系统上。现在我使用预分配的char数组和像sprintf这样的C函数进行字符串操作,并且我以最紧凑的方式编码数据,我仍然可以在我的应用程序中使用它。

你可能会发现this link很有意思(我没写过):

  

我从未在Arduino项目中使用过的五件事......

     
      
  1. String类
  2.         

    如果是这样,Arduino库中的String类使字符串处理更容易。它提供了许多函数来处理你不能轻易做的事情,如果你将字符串表示为char数组的指针,就像在C中一样。那么问题是什么?

         

    问题在于,字符串操作动态分配内存,并且当程序的输入变化时很难预测,并且Arduinos的内存量非常有限(Arduino Uno上为2K)。动态内存分配通常会导致内存碎片。这意味着您的程序可能会在某些输入或短时间内正常工作,但由于内存耗尽而导致其他输入崩溃或更长时间后崩溃。有关为什么动态内存分配在C / C ++中实现的嵌入式软件中不是一个坏主意,请参阅http://critical.eschertech.com/2010/07/30/dynamic-memory-allocation-in-critical-embedded-systems/

         

    我什么时候可以使用String?当写一个快速而肮脏的草图来尝试一些东西时,只要它不需要在一起持续超过几分钟!

答案 3 :(得分:0)

我遇到类似字符串长度的问题,但几乎在所有情况下都发现我受到SPI缓冲区长度64的限制。是否故意将延迟放入代码中,或者打印语句太多,我建议始终注意可能的溢出。

相关问题