Openweather fetcher returns null after second attempt

Hello,

I encounter a problem with my code where after the first successful data fetch, I get null values consistently. I am not sure how to remedy this, as only on the first data fetch it always returns and prints a value on the LCD.

Here's the code (removed some stuff except for key for privacy reasons)

#include <TFT_eSPI.h>
#include <Wire.h> 
#include <WiFi.h> 
#include <esp_eap_client.h>
#include <time.h>
#include <HTTPClient.h>
#include <Arduino_JSON.h>

TFT_eSPI tft = TFT_eSPI();   // Invoke library

#define EAP_IDENTITY "identity"  
#define EAP_USERNAME "user" 
#define EAP_PASSWORD "pass" 

const char* ssid = "ssid"; 
int counter = 0;

String openWeatherMapApiKey = "0c4ba1c6318bce1a1d505959054f2239";
String city = "city";
String countryCode = "code";
unsigned long lastTime = 0;
unsigned long timerDelay = 10000;

String jsonBuffer;

void setup() {
  tft.begin(); 
  tft.fillScreen(TFT_BLACK);
  tft.setCursor(0,40);
  tft.setTextSize(2);
  tft.print("Loading...");

  Serial.begin(115200);
  Serial.println();
  Serial.print("Connecting to network: ");
  Serial.println(ssid);
  WiFi.disconnect(true); 
  WiFi.mode(WIFI_STA);
  
  WiFi.begin(ssid, WPA2_AUTH_PEAP, EAP_IDENTITY, EAP_USERNAME, EAP_PASSWORD);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    counter++;
    if(counter>=60){ //after 30 seconds timeout - reset board
      ESP.restart();
    }
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address set: "); 
  Serial.println(WiFi.localIP()); //print LAN IP
}

void loop() {
if ((millis() - lastTime) > timerDelay) {
    // Check WiFi connection status
    if(WiFi.status()== WL_CONNECTED){
      String serverPath = "http://api.openweathermap.org/data/2.5/weather?q=" + city + "," + countryCode + "&units=metric" + "&APPID=" + openWeatherMapApiKey;
      
      jsonBuffer = httpGETRequest(serverPath.c_str());
      Serial.println(jsonBuffer);
      JSONVar myObject = JSON.parse(jsonBuffer);
  
      // JSON.typeof(jsonVar) can be used to get the type of the var
      if (JSON.typeof(myObject) == "undefined") {
        Serial.println("Parsing input failed!");
        return;
      }
    
      Serial.print("JSON object = ");
      Serial.println(myObject);
      Serial.print("Temperature: ");
      Serial.println(myObject["main"]["temp"]);
      Serial.print("Pressure: ");
      Serial.println(myObject["main"]["pressure"]);
      Serial.print("Humidity: ");
      Serial.println(myObject["main"]["humidity"]);
      Serial.print("Wind Speed: ");
      Serial.println(myObject["wind"]["speed"]);     
// print temp
      tft.fillScreen(TFT_BLACK); 
      tft.setTextColor(TFT_WHITE);
      tft.setCursor(tft.width()/6, 40);
      tft.setTextSize(4);
      tft.print(myObject["main"]["temp"]);
      tft.print((char)247);  
      tft.print("C");    
// print min/max temp
      tft.setTextSize(2);
      tft.setCursor(0,70);
      tft.setTextColor(TFT_RED);
      tft.print("Min:");
      tft.print(myObject["main"]["temp_min"]); 
      tft.print((char)247);  
      tft.println("C");   
      tft.setTextColor(TFT_GREEN);
      tft.print("Max:");
      tft.print(myObject["main"]["temp_max"]); 
      tft.print((char)247);  
      tft.print("C");   
// print conditions
      tft.setCursor(0, 115);   
      tft.setTextSize(2);
      tft.setTextColor(TFT_LIGHTGREY);
      tft.print("Conditions:");
      tft.setCursor(0, 135);   
      tft.setTextSize(3);
      tft.setTextColor(TFT_WHITE);
      tft.print(myObject["weather"][0]["main"]); 
      tft.setCursor(0, 160);   
      tft.setTextSize(2);
      tft.setTextColor(TFT_ORANGE);
      tft.print("Description:");
      tft.setCursor(0, 180);   
      tft.setTextColor(TFT_WHITE);
      tft.print(myObject["weather"][0]["description"]);
      delay(100000);
    }
    else {
      Serial.println("WiFi Disconnected");
    }
    lastTime = millis();
  }

  if (WiFi.status() == WL_CONNECTED) { //if we are connected to Eduroam network
    counter = 0; //reset counter
    Serial.println("Wifi is still connected with IP: "); 
    Serial.println(WiFi.localIP());  
    delay(500);
  }else if (WiFi.status() != WL_CONNECTED) { //if we lost connection, retry
    WiFi.begin(ssid);      
  }
  while (WiFi.status() != WL_CONNECTED) { //during lost connection, print dots
    delay(500);
    Serial.print(".");
    counter++;
    if(counter>=60){ //30 seconds timeout - reset board
    ESP.restart();
    }
  }
  
}

bool i2CAddrTest(uint8_t addr) {
  Wire.begin(); 
  Wire.beginTransmission(addr); 
  if (Wire.endTransmission() == 0) {
    return true; 
  }
  return false; 
}

String httpGETRequest(const char* serverName) {
  WiFiClient client;
  HTTPClient http;
    
  // Your Domain name with URL path or IP address with path
  http.begin(client, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  // Free resources
  http.end();

  return payload;
}


try to isolate the problem, remove other unnecessary interactions

confused by multi tests for both WL_CONNECTED and ! WL_CONNECTED. why not a simple if/else?

How often you can fetch new data depends on your license level ($$$).

Ouch. Do you have a link?

It's the same place you got your API key from, and BTW, you have not filled in city and country code plus I think there is more, maybe TZ.

Here's all the pricing: Pricing - OpenWeatherMap

You can get basic data for free with a limit of 60 calls/minute, which seems like overkill for personal use.

As for TZ, it is not needed. You can query by city (if it is one of their predefined cities), or or city+country or city+state+country (USA): Current weather data - OpenWeatherMap

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.