http.getString(); Fails with a very large JSON string. Can we get this working?
Posted: Mon Dec 19, 2022 4:35 am
All,
I'm trying to use my ESP32 to connect to public services to retrieve data--stock quotes for example. I'm able to do this most of the time, but trying to get some data from the National Weather Service (api.weather.gov) is causing failures
I've got
ESP32 (devKit)
Arduino 1.57
Using wireless libraries from https://dl.espressif.com/dl/package_esp32_index.json
Windows OS
I can successfully read and process the JSON string from
ServerPath = "https://api.weather.gov/gridpoints/HUN/56,40/forecast";
But i get a deserializeJson() return code: EmptyInput (or IncompleteInput) failure from this URL (note this JSON string is around 93,000 characters). HTTP Response code is 200 and if I mess with the DynamicJsonDocument and some timeouts I can some times get about half the JSON string. I suspect there is a timing issue or the JSON is just too big. Trying this path:
ServerPath = "https://api.weather.gov/gridpoints/HUN/ ... ast/hourly";
Here's my code.
Any thoughts on how I can read the above URL or is it just too much data for the ESP32?
Thanks in advance.
I'm trying to use my ESP32 to connect to public services to retrieve data--stock quotes for example. I'm able to do this most of the time, but trying to get some data from the National Weather Service (api.weather.gov) is causing failures
I've got
ESP32 (devKit)
Arduino 1.57
Using wireless libraries from https://dl.espressif.com/dl/package_esp32_index.json
Windows OS
I can successfully read and process the JSON string from
ServerPath = "https://api.weather.gov/gridpoints/HUN/56,40/forecast";
But i get a deserializeJson() return code: EmptyInput (or IncompleteInput) failure from this URL (note this JSON string is around 93,000 characters). HTTP Response code is 200 and if I mess with the DynamicJsonDocument and some timeouts I can some times get about half the JSON string. I suspect there is a timing issue or the JSON is just too big. Trying this path:
ServerPath = "https://api.weather.gov/gridpoints/HUN/ ... ast/hourly";
Here's my code.
Any thoughts on how I can read the above URL or is it just too much data for the ESP32?
Code: Select all
#include <SPI.h>
#include <WiFi.h>
#include <WebServer.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#define HOME_SSID "USE_YOUR_SSID"
#define PASSWORD "USE_YOUR_PASSWORD"
String payload;
String ServerPath;
int httpResponseCode = 0;
IPAddress Actual_IP;
IPAddress PR_IP(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress ip;
WebServer server(80);
unsigned long lastTime = 0;
DynamicJsonDocument doc(100000);
DeserializationError error;
void setup() {
Serial.begin(115200);
disableCore0WDT();
disableCore1WDT();
Serial.println("starting server");
WiFi.begin(HOME_SSID, PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
Actual_IP = WiFi.localIP();
Serial.println("CONNECTED");
printWifiStatus();
delay(100);
}
void loop() {
if ((millis() - lastTime) > 5000) {
lastTime = millis();
if (WiFi.status() == WL_CONNECTED) {
Serial.println("WL_CONNECTED ");
HTTPClient http;
// this path works but the JSON string can not be read
// however the JSON string is valid. It some some 93000 characters
//ServerPath = "https://api.weather.gov/gridpoints/HUN/56,40/forecast/hourly";
// this path works and the JSON string can be read
ServerPath = "https://api.weather.gov/gridpoints/HUN/56,40/forecast";
http.begin(ServerPath.c_str());
// trying anything, perhaps due to size of JSON string
// some timeout is failing
http.setTimeout(4000);
httpResponseCode = http.GET();
lastTime = millis();
while ((millis() - lastTime) > 2000) {
}
if (httpResponseCode > 0) {
Serial.print("HTTP Response code: "); Serial.println(httpResponseCode);
const String& Data = http.getString();
Serial.print("Data: "); Serial.println(Data);
error = deserializeJson(doc, Data);
Serial.print(F("deserializeJson() return code: ")); Serial.println(error.f_str());
}
else {
Serial.println("no wifi connection");
}
http.end();
}
}
}
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi shield's IP address:
ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
// print where to go in a browser:
Serial.print("Open http://");
Serial.println(ip);
}
Thanks in advance.