Cannot connect to api.openweathermap.org a second time - need to restart wifi

I have code that uses an Openweathermap API and works on an ESP32. I'm porting it to a MKR1000 and encounter the following issue:

It calls api.openweathermap.org the first time and gets a response just fine. Shortly later (3 minutes), when it tries again, it fails to connect. I've boiled down the code to what's below to just isolate the problem. When the second call fails, if I close down the wifi connection and restart it and fire off the request to openweathermap again, that works. But I don't want to keep doing that for other reasons.

I'm not violating any "too many calls too quickly" limit in any way.

This seems to have something to do with the original connection. Maybe not being closed out? I've tried adding wtclient.stop() but that doesn't help. And I've tried "Connection: close" and that doesn't help either.

Any insight into why this might fail would be appreciated.

  #include <WiFi101.h>
  #include <WiFiUdp.h>

// POST and Wifi parameters
const char* ssid     = "XXXXXXXXXXXXX"; // removed
const char* password = "XXXXXXXXXXXXX"; // removed 

WiFiClient wtclient; // For weather only

#define WifiTryLimit 24 // max attempts (12 seconds) before resetting connection and trying again

// Weather openweathermap.org API key
String apiKey= "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; // removed
String location= "XXXXXXXXXXXXX,NJ,US";             // removed
char   WeatherServer[] = "api.openweathermap.org";    
int    WeatherOK;
long   CycleTime   = 180L*1000L;
long   MinuteTimer = 0;

void setup() {
  Serial.begin(115200);
  delay(1000); 
  Serial.println("Starting.");

  ConnectWifi();   
  WeatherOK = GetWeather(45);  
  MinuteTimer = millis() + CycleTime;
}

void loop() {
  long CurTime;

  CurTime = millis();
  if ((CurTime > MinuteTimer) ) {
    WeatherOK = GetWeather(45);
    MinuteTimer = CurTime + CycleTime; // Every minute check timers
    if (!WeatherOK) { // Reset everything
      WiFi.disconnect(); 
      WiFi.end(); 
      ConnectWifi();   
      WeatherOK = GetWeather(45);  // get current weather and log on tft screen
    }
  }
}

void ConnectWifi() {
  int NotConnected = true;
  int Tries = 0;

  while (NotConnected) {
     // Initialize Wifi Connection
    Serial.print("Connecting to WiFi ");
    WiFi.begin(ssid, password);
    
    Tries = 0;
    while ((WiFi.status() != WL_CONNECTED) && (Tries < WifiTryLimit)) {
      delay(500);
      Serial.print(".");
      Tries=Tries+1;
    }
   
    if (WiFi.status() == WL_CONNECTED) {
      NotConnected = false;
      Serial.println(" connected.");
    } else {
      WiFi.disconnect(); // jusst in case
      Serial.println(" connection failed.");
      delay(1000); 
    }
  }  
}

int GetWeather(int AvailLimit) {
  int    result = false;
  int    AvailTime = AvailLimit; 
  String line = "";

  Serial.println("Starting connection to weather server.");

  if (wtclient.connect("api.openweathermap.org", 80)) {
    Serial.print("connected to weather server: ");
    // Make a HTTP request:
    wtclient.print("GET /data/2.5/weather?"); 
    wtclient.print("q="+location);
    wtclient.print("&appid="+apiKey);
    wtclient.print("&cnt=1");                             // count of cities around point to return
    wtclient.println("&units=imperial");
    wtclient.println("Host: api.openweathermap.org");
    wtclient.println("Connection: keep-alive"); // tried "Connection: close");
    wtclient.println();
  } else {
    Serial.println("unable to connect");
    return result;
  }
  while (!wtclient.available() && (AvailTime > 0)) {
    delay(1000);
    AvailTime = AvailTime-1;
    Serial.print(". ");
  }
  if (AvailTime == 0) {
    Serial.println("No response from weather.");
    return false;
  }

  while (wtclient.available()) {
    line = wtclient.readStringUntil('\n');
    Serial.print("Received weather report: "); Serial.println(line);
    // ParseWeather(line);
    result=true;
    yield();
  }
  wtclient.flush(); 
  return result;
}

change wtclient.flush(); to wtclient.close();
and remove the keep-alive header

There is no .close() for WiFiClient

However, I updated the firmware on the MKR1000 and things are working now.

Thanks.

Thank you for giving this feedback, it helps others with the same problem.

sorry. it is stop() not close()

Yes. I did try that but it had no effect. What worked was updating the MKR1000 firmware. Thanks.

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