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;
}