我已经花了好几个小时在arduino上组合一个简单的JSON对象字符串,以发送到Raspberry Pi运行节点.
我似乎无法成功构建字符串.我试过一次性构建字符串:
"{" + string1 + "," + string2 + "," + string3 + "}" etc...
Run Code Online (Sandbox Code Playgroud)
我也尝试过使用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);
Run Code Online (Sandbox Code Playgroud)
你可以从上面的最后一段代码看到,正在构建字符串时,我将它吐出到串行监视器.但是,这是我的串口输出:
{ "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,
Run Code Online (Sandbox Code Playgroud)
字符串长度是否有限制?我没有在文档中提到任何这种限制.除了标准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 }";
Run Code Online (Sandbox Code Playgroud)
果然,它开始起作用了:
{ "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 }
Run Code Online (Sandbox Code Playgroud)
这意味着存在限制.这是内存限制吗?
顺便说一句,硬件是Arduino Uno R3
arduino的内存非常有限 - 数据大约为2K(闪存中的程序为32K).在封面下,String类正在为每个字符串连接执行realloc调用.这可能导致碎片化内存,其中没有可用于字符串的单个连续内存块.
我建议你停止使用String类,并在开头添加一个大缓冲区并附加到它,但是你需要知道在分配之前它有多大.
如果你喜欢危险地生活,你可以查看String类的源代码,看看你是否可以强制它预先分配一个大缓冲区,但是我没有看到记录的方法.
小智 4
Atmel 处理器的内存管理相当有限,因此很容易出现内存碎片。请记住,运行时堆栈和堆也是有限的。
静态字符串也可以放入 PROGMEM 中
arduino.cc 上还有一个空闲内存功能,可以显示您有多少空闲内存。