i have some ino file that only do the json parsing of the same json response from the same weather service and it's working well here is the code. i am using nano v3 with esp8266 wifi
#include <ArduinoJson.h>
#include "WiFiEsp.h"
#include <SPI.h>
WiFiEspClient client;
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(6, 7); // RX, TX
#endif
// Name address for Open Weather Map API
const char* server = "api.openweathermap.org";
const unsigned long HTTP_TIMEOUT = 10000; // max respone time from server
const size_t MAX_CONTENT_SIZE = 512; // max size of the HTTP response
char ssid[] = "xxxxxxx";
char pass[] = "xxxxxxx";
int status = WL_IDLE_STATUS;
// The type of data that we want to extract from the page
struct clientData {
char temp[8];
// char humidity[8];
};
// ARDUINO entry point #1: runs once when you press reset or power the board
void setup() {
Serial.begin(115200);
// initialize serial for ESP module
Serial1.begin(9600);
// initialize ESP module
WiFi.init(&Serial1);
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println(F("WiFi shield not present"));
// don't continue
while (true);
}
while (status != WL_CONNECTED) {
status = WiFi.begin(ssid, pass);
}
}
// ARDUINO entry point #2: runs over and over again forever
void loop() {
if(connect(server)) {
if(sendRequest(server, resource) && skipResponseHeaders()) {
clientData clientData;
if(readReponseContent(&clientData)) {
printclientData(&clientData);
}
}
}
disconnect();
wait();
}
// Open connection to the HTTP server
bool connect(const char* hostName) {
Serial.print("Connect to ");
Serial.println(hostName);
bool ok = client.connect(hostName, 80);
Serial.println(ok ? "Connected" : "Connection Failed!");
return ok;
}
// Send the HTTP GET request to the server
bool sendRequest(const char* host, const char* resource) {
Serial.print("GET ");
Serial.println(resource);
client.print(F("GET /data/2.5/weather?q=xxxxxx,xxxxxx&units=metric&APPID=xxxxxxxx&type=accurate"));
client.println(F(" HTTP/1.1"));
client.print(F("Host: "));
client.println(host);
client.println(F("Connection: close"));
client.println();
return true;
}
// Skip HTTP headers so that we are at the beginning of the response's body
bool skipResponseHeaders() {
// HTTP headers end with an empty line
char endOfHeaders[] = "\r\n\r\n";
client.setTimeout(HTTP_TIMEOUT);
bool ok = client.find(endOfHeaders);
if (!ok) {
Serial.println("No response or invalid response!");
}
return ok;
}
// Parse the JSON from the input string and extract the interesting values
// Here is the JSON we need to parse
bool readReponseContent(struct clientData* clientData) {
// Compute optimal size of the JSON buffer according to what we need to parse.
// See https://bblanchon.github.io/ArduinoJson/assistant/
const size_t bufferSize = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) +
2*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) +
JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(12) + 390;
DynamicJsonBuffer jsonBuffer(bufferSize);
JsonObject& root = jsonBuffer.parseObject(client);
if (!root.success()) {
Serial.println("JSON parsing failed!");
return false;
}
// Here were copy the strings we're interested in using to your struct data
strcpy(clientData->temp, root["main"]["temp"]);
// strcpy(clientData->humidity, root["main"]["humidity"]);
// It's not mandatory to make a copy, you could just use the pointers
// Since, they are pointing inside the "content" buffer, so you need to make
// sure it's still in memory when you read the string
return true;
}
// Print the data extracted from the JSON
void printclientData(const struct clientData* clientData) {
Serial.print("Temp = ");
Serial.println(clientData->temp);
// Serial.print("Humidity = ");
// Serial.println(clientData->humidity);
}
// Close the connection with the HTTP server
void disconnect() {
Serial.println("Disconnect");
client.stop();
}
// Pause for a 1 minute
void wait() {
Serial.println("Wait 60 seconds");
delay(60000);
}
but when i add it with more code it doesnt work anymore and always giving me parsing failed here is the code of the other project which i have it in a function that is triggered by timer from time to time:
const unsigned long HTTP_TIMEOUT = 10000; // max respone time from server
const size_t MAX_CONTENT_SIZE = 512;
void getTemp(){
char serverName[] = "api.openweathermap.org";
t1.stop(tim);
client2.stop();
if(client3.connect(serverName, 80)) {
if(sendRequest(serverName) && skipResponseHeaders()) {
clientData clientData;
if(readReponseContent(&clientData)) {
printclientData(&clientData);
}
}
}
client3.stop();
tim = t1.every(10000, getTime);
}
bool sendRequest(const char* host) {
client3.print(F("GET /data/2.5/weather?q=xxxxxx,xxxxx&units=metric&APPID=xxxxx&type=accurate"));
client3.println(F(" HTTP/1.1"));
client3.print(F("Host: "));
client3.println(host);
client3.println(F("Connection: close"));
client3.println();
return true;
}
bool skipResponseHeaders() {
// HTTP headers end with an empty line
char endOfHeaders[] = "\r\n\r\n";
client3.setTimeout(HTTP_TIMEOUT);
bool ok = client3.find(endOfHeaders);
return ok;
}
bool readReponseContent(struct clientData* clientData) {
// Compute optimal size of the JSON buffer according to what we need to parse.
// See https://bblanchon.github.io/ArduinoJson/assistant/
const size_t bufferSize = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(12) + 390;
DynamicJsonBuffer jsonBuffer(bufferSize);
JsonObject& root = jsonBuffer.parseObject(client3);
if (!root.success()) {
Serial.println(F("JSON parsing failed!"));
return false;
}
// Here were copy the strings we're interested in using to your struct data
strcpy(clientData->temp, root["main"]["temp"]);
// strcpy(clientData->humidity, root["main"]["humidity"]);
// It's not mandatory to make a copy, you could just use the pointers
// Since, they are pointing inside the "content" buffer, so you need to make
// sure it's still in memory when you read the string
return true;
}
// Print the data extracted from the JSON
void printclientData(const struct clientData* clientData) {
Serial.print(F("Temp = "));
Serial.println(clientData->temp);
//Serial.print(F("Humidity = "));
//Serial.println(clientData->humidity);
}
Actually the first code works when its alone but second doesn't and yes it retrieve the json as i tried to print out the response and all is grabbed well but the problem is the parsing itself and always gives me parsing failed. i am sure you are going to tell me that maybe the memory issue is the problem which i dont think so but not sure.
yes the first code has
Sketch uses 14890 bytes (48%) of program storage space. Maximum is 30720 bytes.
Global variables use 870 bytes (42%) of dynamic memory, leaving 1178 bytes for local variables. Maximum is 2048 bytes.
and the second has lower memo which is
Sketch uses 29106 bytes (94%) of program storage space. Maximum is 30720 bytes.
Global variables use 1339 bytes (65%) of dynamic memory, leaving 709 bytes for local variables. Maximum is 2048 bytes.
but actually the assistant of the jsonarduino lib calculated that i only need AVR 8-bit 697
which is less than the 709 i have of ram. not sure as i mentioned above but here to get more info about this situation/issue.
one more question can i use json-streaming-parser with nano v3 connected to esp? or just work directly with the esp only?
thanks alot,
Max