Tldr;问题是esp8266上的long类型被转换为一个有符号的32bit int,它太小了以至于无法保存该值。使用unsigned long long作品。底部有更长的解释。
我想解析来自http://worldclockapi.com/api/json/utc/now的JSON响应并提取“ currentFileTime”字段。 作为硬件,我正在使用ESP-01。 不幸的是,我可以提取除所需字段以外的所有字段。
我正在使用版本6中的arduinoJSON库。我使用了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. In the esp8266 c_types.h我发现,该long被转换为一个有符号的int32(最大值:2,147,483,647),该整数大小很小。 3.使用无符号long long可以解决问题,它是一个int 64,最大值为18446744073709551616 4.我尝试使用
打印值Serial.println(currentFileTime);
但收到错误:
call of overloaded 'println(long long unsigned int&)' is ambiguous
显然,串行库只能处理32位值,因此我遵循了this指南并安装了this库(将整个文件复制粘贴到我的标头中)。我最终可以打印出该值! 希望这会有所帮助。