Странная ошибка при получении длинного значения от json на esp8266 (arduinoIDE) - PullRequest
1 голос
/ 25 мая 2019

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-битные значения, поэтому я следовал этому руководству и установил эту библиотеку (копия вставила весь файл в мой заголовок).И я мог бы наконец напечатать значение!Надеюсь, это поможет.

...