c++ - 在 Arduino 上解析蓝牙 ble.write json 字符串
问题描述
我正在尝试解析从我的手机进入 Arduino 的 JSON 字符串。我对 C++ 和这些库还很陌生,所以我遇到了一些问题。以下是我到目前为止的代码。除了我试图将 json[] 设置为来自手机的值的部分之外,一切正常。它是一个有效的 JSON,并返回到如下所示的控制台。
错误:初始化程序无法确定“json”的大小
从手机收到的 JSON:
{"SSID":"Sample","PSK":"test","TOKEN":"1234","HOSTNAME":"secondarycontroller"}
ESP32 代码:
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <ArduinoJson.h>
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string value = pCharacteristic->getValue();
if(value.length() > 0) {
StaticJsonDocument<800> doc;
char json[] = value;
DeserializationError error = deserializeJson(doc, json);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
return;
}
Serial.println(doc["SSID"]);
Serial.println(doc["PSK"]);
Serial.println(doc["HOSTNAME"]);
Serial.println(doc["TOKEN"]);
Serial.println("*********");
Serial.print("New value: ");
for (int i = 0; i < value.length(); i++)
Serial.print(value[i]);
Serial.println();
Serial.println("*********");
}
}
};
void setup() {
Serial.begin(115200);
pinMode(LEDpin, OUTPUT);
Serial.println("1- Download and install an BLE scanner app in your phone");
Serial.println("2- Scan for BLE devices in the app");
Serial.println("3- Connect to MyESP32");
Serial.println("4- Go to CUSTOM CHARACTERISTIC in CUSTOM SERVICE and write something");
Serial.println("5- See the magic =)");
BLEDevice::init("MyESP32");
BLEServer *pServer = BLEDevice::createServer();
BLEService *pService = pServer->createService(SERVICE_UUID);
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setCallbacks(new MyCallbacks());
pCharacteristic->setValue("Hello World");
pService->start();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
}
void loop() {
// put your main code here, to run repeatedly:
delay(2000);
}
解决方案
根据desrializeJson() 的文档,第二个输入参数接受char*
零拷贝;和,const char*
或const std::string&
重复。
文档中的原型(仅相关的):
// writable input => zero-copy
DeserializationError deserializeJson(JsonDocument& doc, char* input);
DeserializationError deserializeJson(JsonDocument& doc, char* input, size_t inputSize);
// read-only input => duplication
DeserializationError deserializeJson(JsonDocument& doc, const char* input);
DeserializationError deserializeJson(JsonDocument& doc, const char* input, size_t inputSize);
// ...
DeserializationError deserializeJson(JsonDocument& doc, const std::string& input);
观察上述原型中的第二个参数!
因此,以下几行:
char json[] = value;
DeserializationError error = deserializeJson(doc, json);
将会:
const char* json = value.c_str();
DeserializationError error = deserializeJson(doc, json);
或者,直接这样传递value
:
DeserializationError error = deserializeJson(doc, value);
那应该可以解决您的问题。
你得到的错误是关于这一行的:
char json[] = value;
// ^^
char
这里缺少数组的大小。您必须在此上下文中指定静态数组的大小。另外,value
在这种情况下不能直接兑换。
小费:
在以下情况下使用std::string::empty() :
if(value.length() > 0)
IE
if( !value.empty() )
它更具可读性和表现力!
推荐阅读
- r - 在数据帧之间进行比较以在两个数据帧中的相同位置找到观察值的 +/- 1
- sql - 超表和“普通”表之间多对多关系的替代方案
- java - 运行 JLink 可执行文件的 Alpine Docker Image
- c - CMake - 与静态和动态库的链接
- java - STS not picking up Open JDK 11 JRE
- xcode - 如何防止 SPM 项目中的示例代码导入 Xcode?
- r - shinydashboard 切换框 - 默认隐藏
- javascript - 构造函数对象总是返回一个函数而不是一个字符串
- javascript - 带有 jQuery 语法变量的 eval() 方法不起作用
- python - 如何规避使用 pandas 过滤 txt 文档,其中行包含字符串、整数和浮点数