-->
Page 1 of 1

ESP WDT reset getting Wunderground weather forecast

PostPosted: Fri Sep 30, 2016 7:16 am
by tirnasjimmy
ESP software watchdog timer causes ESP to crash and reboot after getting high temperature value from a requested JSON weather forecast on Wunderground.

I've read that the JSON string can be too long for the ESP memory buffer. How would I modify my code to handle the required buffer size?

Code: Select all#include <SPI.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>

// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(23,216,168,120);  // numeric IP for Weather Underground  (no DNS)
const char server[] = "api.wunderground.com";    // name address for Weather Underground (using DNS)
const char* ssid = "";
const char* password = "";
const String myKey = "";  //See: http://www.wunderground.com/weather/api/d/docs (change here with your KEY)
const String myFeatures = "forecast";     //See: http://www.wunderground.com/weather/api/d/docs?d=data/index&MR=1
const String query = "autoip";
//const String myCountry = "UK";            //See: http://www.wunderground.com/weather/api/d/docs?d=resources/country-to-iso-matching
//const String myCity = "Sertaozinho";      //See: http://www.wunderground.com/weather/api/d/docs?d=data/index&MR=1

// Set the static IP address to use if the DHCP fails to assign
//IPAddress ip(192,168,1,177);

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
WiFiClient client;

//Response from Server
String responseString;

boolean startCapture;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);

  while (!Serial){
  }

  //Connecting to WiFi network
  Serial.print("Connecting to ");
  Serial.println(ssid);
  Serial.print("Trying connection to");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED){        // Try to establish WiFi connection and startup Web server.
    delay(500);                                 
    Serial.print(".");                          // Keep printing 'dots' whilst WiFi channel is not connected to ESP. Give up and continue rest of program after 30 sec.
  }
  Serial.println("");                           
  Serial.println("WiFi connected");           // Inform user that WiFi has successfully connected!
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
 
  // if you get a connection, report back via serial:
  if (client.connect(server, 80))
  {
    Serial.println("Connected!");
   
    String html_cmd1 = "GET /api/" + myKey + "/" + myFeatures + "/q/" + query + ".json HTTP/1.1";
    String html_cmd2 = "Host: " + (String)server;
    String html_cmd3 = "Connection: close";
   
    //Uncomment this is necessary
    Serial.println("Sending commands:");
    Serial.println(" " + html_cmd1);
    Serial.println(" " + html_cmd2);
    Serial.println(" " + html_cmd3);
    Serial.println();
   
    // Make a HTTP request:
    client.println(html_cmd1);
    client.println(html_cmd2);
    client.println(html_cmd3);
    client.println();
   
    responseString = "";
    startCapture = false;   
  }
  else
  {
    // if you didn't get a connection to the server:
    Serial.println("Connection failed!");
  }
}

void loop()
{
  // if there are incoming bytes available
  // from the server, read them and buffer:
  if (client.available())
  {
  char c = client.read();
  if (c != '}'){
    if(c == 'c')
      startCapture=true;
   
    if(startCapture)
      responseString += c;
  }
}
  // if the server's disconnected, stop the client:
  if (!client.connected()) {   
    Serial.println("Received " + (String)responseString.length() + " bytes");
    Serial.println("Disconnecting.");
    client.stop();
    client.flush();

    delay(5000);
   
    Serial.println();
   
    //Now, some examples of how to use it!
    Serial.print("Today's High: ");
    Serial.print(getValuesFromKey(responseString, "celsius"));
    Serial.println(" oC\n");
   
    //Serial.print("Current Temperature: ");
    //Serial.print(getValuesFromKey(responseString, "temp_c"));
    //Serial.println(" oC\n");
   
    //Serial.print("Today's Low: ");
    //Serial.println(getValuesFromKey(responseString, "low"));
    //Serial.println();
   
    //Serial.print("Wind: ");
    //Serial.println(getValuesFromKey(responseString, "wind_string"));
    //Serial.println();
   
    //Serial.print("Feels like: ");
    //Serial.print(getValuesFromKey(responseString, "feelslike_c"));
    //Serial.println(" oC\n");
   
    // do nothing forevermore:
    while(true);
  }
}

String getValuesFromKey(const String response, const String sKey)
{
  String sKey_ = sKey;
 
  sKey_ = "\"" + sKey + "\":";
 
  char key[sKey_.length()];
 
  sKey_.toCharArray(key, sizeof(key));
 
  int keySize = sizeof(key)-1;
   
  String result = "";
 
  int n = response.length();
 
  for(int i=0; i < (n-keySize-1); i++)
  {
    char c[keySize];
   
    for(int k=0; k<keySize; k++)
    {
      c[k] = response.charAt(i+k);
    }
       
    boolean isEqual = true;
   
    for(int k=0; k<keySize; k++)
    {
      if(!(c[k] == key[k]))
      {
        isEqual = false;
        break;
      }
    }
   
    if(isEqual)
    {     
      int j= i + keySize + 1;
      while(!(response.charAt(j) == ','))
      {
        result += response.charAt(j);       
        j++;
      }
     
      //Remove char '"'
      result.replace("\"","");
      break;
    }
  }
 
  return result;
}