Tldr;Проблема заключалась в том, что тип long в esp8266 переводится как 32-битное целое число со знаком, которое настолько мало, чтобы содержать значение.Использование unsigned long long works.Более подробное объяснение внизу.
Я хочу проанализировать ответ JSON из http://worldclockapi.com/api/json/utc/now и извлечь поле "currentFileTime".В качестве аппаратного обеспечения я использую ESP-01.К сожалению, я могу извлечь все поля, кроме того, которое мне нужно.
Я использую библиотеку arduinoJSON в Версии 6. Я использовал https://arduinojson.org/v6/assistant/ для генерации кода, необходимого для десериализации.Я попытался найти что-нибудь в документах, указывающих на причину такого поведенияОжидается, что для синтаксического анализатора будет возвращаться значение по умолчанию для переменной, если ключ отсутствует, а это будет 0, которое я вижу, даже если я проверяю, присутствует ли ключ с jsonBuffer.containsKey("currentFileTime")
, он все равно возвращает 0.Я также пытался использовать StaticJsonDocument с тем же результатом.
long GetDateTime() {
HTTPClient http; //Object of class HTTPClient
http.begin("http://worldclockapi.com/api/json/utc/now");
int httpCode = http.GET();
//Check the returning code
if (httpCode > 0) {
// Get the request response payload
String payload = http.getString();
const size_t capacity = JSON_OBJECT_SIZE(9) + 200;
DynamicJsonDocument doc(capacity);
// Just using this payload from the Arduino Assistant to test
const char* json = "{\"$id\":\"1\",\"currentDateTime\":\"2019-05-25T07:40Z\",\"utcOffset\":\"00:00:00\",\"isDayLightSavingsTime\":false,\"dayOfTheWeek\":\"Saturday\",\"timeZoneName\":\"UTC\",\"currentFileTime\":132032436125212740,\"ordinalDate\":\"2019-145\",\"serviceResponse\":null}";
deserializeJson(doc, json);
const char* _id = doc["$id"]; // "1"
const char* currentDateTime = doc["currentDateTime"]; // "2019-05-25T07:40Z"
const char* utcOffset = doc["utcOffset"]; // "00:00:00"
bool isDayLightSavingsTime = doc["isDayLightSavingsTime"]; // false
const char* dayOfTheWeek = doc["dayOfTheWeek"]; // "Saturday"
const char* timeZoneName = doc["timeZoneName"]; // "UTC"
long currentFileTime = doc["currentFileTime"]; // 132032436125212740
const char* ordinalDate = doc["ordinalDate"]; // "2019-145"
Serial.println("What I want:");
Serial.println(currentFileTime);
Serial.println("The rest:");
Serial.println(dayOfTheWeek);
Serial.println(currentDateTime);
Serial.println(utcOffset);
Serial.println(isDayLightSavingsTime);
Serial.println(timeZoneName);
Serial.println(ordinalDate);
if (doc.containsKey("currentFileTime")) {
Serial.println("Yes currentFileTime is a key!");
Serial.println(currentFileTime);
} else {
Serial.println("No currentFileTime is not a key!");
}
if (doc.containsKey("timeZoneName")) {
Serial.println("Yes timeZoneName is a key!");
Serial.println(timeZoneName);
} else {
Serial.println("No timeZoneName is not a key!");
}
return currentFileTime;
}
return 0;
}
и на последовательном выходе я получаю:
What I want:
0
The rest:
Saturday
2019-05-25T07:40Z
00:00:00
0
UTC
2019-145
Yes currentFileTime is a key!
0
Yes timeZoneName is a key!
UTC
Я ожидаю, что «currentFileTime» даст мне значение132032436125212740, но вместо этого возвращается значение по умолчанию 0.Может ли это быть проблемой с длинным типом данных на esp-01?
Большое спасибо!
Редактировать : Поиск ошибок: 1. Преобразование значения в строку привело кв правильном выводе:
String currentFileTime = doc["currentFileTime"].as<String>(); // 132032436125212740
Ouput было что-то вроде 1.3e ^ 17.Таким образом, значение было в этом поле, и ключ не был проблемой.2. В esp8266 c_types.h Я обнаружил, что long переводится в знаковое int32 (макс. Значение: 2,147,483,647 ), что очень мало.3. Используя unsigned long long, который является int 64 с максимальным значением 18446744073709551616, добился цели 4. Я попытался напечатать значение с помощью
Serial.println(currentFileTime);
Но получил ошибку:
call of overloaded 'println(long long unsigned int&)' is ambiguous
Очевидно, что библиотека Serial может обрабатывать только 32-битные значения, поэтому я следовал этому руководству и установил эту библиотеку (копия вставила весь файл в мой заголовок).И я мог бы наконец напечатать значение!Надеюсь, это поможет.