Библиотека ArduinoJson: сколько места выделить для сериализованного буфера?
Я использую великолепную библиотеку ArduinoJson
для работы с данными JSON на моем ESP8266. Я сталкивался с проблемами случайного программного сброса wdt и исследовал утечки памяти везде, где только мог. Я хочу максимально сократить использование Strings
и DynamicJsonDocument
. Поэтому я подумал об использовании автоматических переменных: буферов символов: char[N]
и StatitcJsonDocument
.
Я использую ассистент ArduinoJson, чтобы определить, сколько байт мне следует зарезервировать. Ниже приведены полезные данные одного ответа, которые я ожидаю получить:
// ввод символов[MAX_INPUT_LENGTH];
StaticJsonDocument<128> doc;
DeserializationError error = deserializeJson(doc, input, MAX_INPUT_LENGTH);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
int statusCode = doc["statusCode"]; // 200
bool needUpdate = doc["needUpdate"]; // истинный
const char* message = doc["message"]; // "требуется обновление"
JsonObject data = doc["data"];
const char* data_deviceId = data["deviceId"]; // "DLD00005"
const char* data_user_fw_version = data["user_fw_version"]; // "0.0.0quot;
const char* data_new_fw_version = data["new_fw_version"]; // "0.0.5quot;
Как вы можете видеть, я использую тип char [N]
в качестве входных данных, который фактически копируется с помощью strncpy()
из https .getString().c_str()
из ответа на предыдущий запрос https.POST()
. Моя проблема в том, что я не знаю, сколько памяти мне следует зарезервировать для массива char[N]
, т.е. каким должно быть значение N
? Причина, по которой я спрашиваю, заключается в том, что я получаю ошибку deserialization(): IncompleteInput
, что, я почти уверен, связано с тем, что буфер char[N]
недостаточно велик. . Итак, мой вопрос: если объект StaticJsonDocument имеет размер 128
байт, то какого размера мне следует сделать буфер char[N]
(есть ли какая-либо связь между размерами)? Или мне следует просто использовать произвольно большое значение, например char[512]
, которого я хочу избежать, чтобы избежать переполнения стека?
StaticJsonDocument<128> payload;
char payloadSerial[???];
...
int status = https.POST(payloadSerial);
strncpy(payloadSerial, https.getString().c_str(), sizeof(payloadSerial));
DeserializationError error = deserializeJson(payload, payloadSerial, sizeof(payloadSerial));
if (error) {
Monitor.print(F("DeserializeJson() failed: "));
Monitor.println(error.f_str());
}
@First User, 👍1
1 ответ
Вы спрашиваете о коде, который выглядит следующим образом:
StaticJsonDocument<128> payload;
char payloadSerial[???];
...
int status = https.POST(payloadSerial);
strncpy(payloadSerial, https.getString().c_str(), sizeof(payloadSerial));
DeserializationError error = deserializeJson(payload, payloadSerial, sizeof(payloadSerial));
Документация для deserializeJson()
показывает, что это может принимать String
напрямую:
DeserializationError deserializeJson(JsonDocument& doc, const String& input);
Поэтому нет необходимости копировать https.getString().c_str()
в payloadSerial
. Вы можете просто передать String
, который возвращает https.getString()
:
StaticJsonDocument<128> payload;
int status = https.POST(request_body);
DeserializationError error = deserializeJson(payload, https.getString());
Вы использовали здесь один и тот же массив символов как для тела запроса, который вы передали в POST()
, так и для десериализации ответа JSON. Хотя это нормально, для ясности я изменил вызов POST
, чтобы использовать что-то другое, поскольку массив символов совершенно не нужен для обработки ответа.
Даже если deserializeJson()
не принял тип String
в качестве аргумента, вам все равно не потребуется копировать ответ в буфер. Вы можете просто передать https.getString().c_str()
:
StaticJsonDocument<128> payload;
int status = https.POST(request_body);
DeserializationError error = deserializeJson(payload, https.getString().c_str());
Вам действительно следует проверить значение status
. Он указывает, прошел ли POST успешно или нет. Если это не удалось, вам следует сообщить об этом и указать причину сбоя, а не пытаться обрабатывать возвращенные полезные данные, поскольку возвращенных полезных данных нет.
- Загрузка кода Arduino, OTA, через подключенный ESP8266-12E с запущенным Esp-Link
- Проблема с WiFi на Mega + WiFi R3 ATmega2560 + ESP8266
- Последовательная связь arduino mega и D1 Wemos Mini
- ESP8266 отправляет веб-страницу клиенту, но html-коды отображаются в браузере вместо веб-страницы
- Ошибка ESP8266 error: espcomm_upload_mem failed while uploading sketch
- Какой максимальный размер статического документа Json в Arduino JSON?
- esp8266 esp-01 печатает значения мусора на последовательном мониторе
- Ошибка тайм-аута с Arduino Mega и ESP8266 в качестве модуля Wi-Fi