json - 从串口读取 JSON 缺少部分起始数据
问题描述
当从 ESP8266 的串口读取 JSON 字符串时,它会切断数据的开头。
我尝试从串行端口读取数据并打印每个字符,但是它切断了部分数据的请求。
void setup() {
Serial.begin(115200);
while (!Serial) {
;
}
}
void loop() {
int curSize = 30;
char* buffer = new char[curSize];
std::fill_n(buffer, curSize, 0);
int pos = 0;
Serial.print("Sending: ");
while(Serial.available() == false) delay(500);
while (Serial.available()) {
char c = Serial.read();
Serial.print(c);
if(pos == curSize-1){
char* newBuffer = increaseBuffer(buffer, curSize, curSize + 30);
curSize += 30;
delete[] buffer;
buffer = newBuffer;
}
if(c == '\n'){
buffer[pos] = 0;
pos = 0;
break;
}
buffer[pos++] = c;
}
if(buffer[0] != 0) {
sendBuffer(buffer);
}
delete[] buffer;
}
char* increaseBuffer(char* orig, int oldSize, int newSize){
char* data = new char[newSize];
std::fill_n(data, newSize, 0);
for(int i = 0; i < newSize; i++){
if(i < oldSize) data[i] = orig[i];
else data[i] = '\0';
}
return data;
}
使用的 JSON 数据(和预期的输出)
{"type":0,"ver":"0.0.1","T":[28,29,29,29,29,29,29,29,29,29],"H":[59.1608,59.1608,60,59.1608,60,60,60,59.1608,59.1608,59.1608],"DP":[20.36254,20.36254,20.59363,20.36254,20.59363,20.59363,20.59363,20.36254,20.36254],"HI":[30.90588,30.90588,31.0335,30.90588,31.0335,31.0335,31.0335,30.90588,30.90588]}
实际输出的示例
Example 1: 9,29,29,29,29,29,29,29,29],"H":[59.1608,59.1608,60,59.1608,60,60,60,59.1608,59.1608,59.1608],"DP":[20.36254,20.36254,20.59363,20.36254,20.59363,20.59363,20.59363,20.36254,20.36254],"HI":[30.90588,30.90588,31.0335,30.90588,31.0335,31.0335,31.0335,30.90588,30.90588]}
Example 2: 29,29,29,29,29,29,29,29,29],"H":[59.1608,59.1608,60,59.1608,60,60,60,59.1608,59.1608,59.1608],"DP":[20.36254,20.36254,20.59363,20.36254,20.59363,20.59363,20.59363,20.36254,20.36254],"HI":[30.90588,30.90588,31.0335,30.90588,31.0335,31.0335,31.0335,30.90588,30.90588]}
解决方案
尝试在等待数据开始进入的阻塞循环中将延迟设置为 1 而不是 500。我猜会发生什么是在该循环的一次迭代中Serial.available()
是错误的,并且在延迟期间您开始获取数据当您的延迟结束以再次检查时,最终会被覆盖。
我所描绘的如下。如果您要将延迟(500)扩展为延迟(1)调用500次。
while(Serial.available() == false){
delay(1);
delay(1);
// ...
delay(1); // first character comes in
delay(1);
delay(1); // second character comes in
// ...
delay(1); // n character comes in
}
然后在延迟结束后,您开始实际收集进来的角色。
推荐阅读
- r - 使用新 R 版本更新旧 R 版本中的包
- neo4j - Neo4j 和 Cypher:只反转一个箭头
- exception - 关于哪个 OCaml 标准库函数可以引发哪个错误的文档
- python - FreeOPC 不会在启动时启动
- ios - swift - 使用 Decodable 从 API 解析 JSON
- react-native - 在 react native 中停止启动类似于 TikTok 的视频录制栏
- java - 如何为 Junit 测试模拟 executeNamedQuery(query, params)
- aws-lambda - Pdf to Png with Python in Lambda- 错误:“无法获取页数。是否已安装 poppler 并在 PATH 中?”
- pine-script - 无法从 pine 编辑器中的函数访问值
- rx-java - 在 Vert.x 中重试 HTTP 调用 N 次,然后返回一个 Maybe