I didn’t think the Arduino threaded so I’m not quite sure how to answer that. Here is an example of a failure:
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <Ticker.h>
#include <Arduino.h>
void connectHost(const char*, int);
void setup() {
Serial.begin(74880);
Serial.setDebugOutput(true);
Serial.flush();
WiFi.begin(F("Xxxxx"), F("xxxxxxxx"));
Serial.println();
Serial.print(F("Waiting for connection."));
while (WiFi.status() != WL_CONNECTED) {
Serial.print(F("."));
delay(500);
}
Serial.println();
Serial.println(F("Connected."));
WiFi.mode(WIFI_STA);
delay(200);
MDNS.begin(WiFi.hostname());
Serial.print(F("DNS #1: "));
Serial.print(WiFi.dnsIP().toString().c_str());
Serial.print(F(", DNS #2: "));
Serial.println(WiFi.dnsIP(1).toString().c_str());
}
void loop() {
Ticker lookup;
lookup.attach(5, [lookup](){connectHost("google.com", 80);});
while (true) {
yield();
}
}
void connectHost(const char* hostname, int port) {
WiFiClient client;
client.setTimeout(10000);
int retval = client.connect(hostname, port);
if (retval != 1) {
Serial.println(F("Connection failed."));
return;
} else {
Serial.println(F("Connected to endpoint."));
}
}
This sketch results in the following consistent failure:
Waiting for connection.......scandone
Connected.
DNS #1: 1.1.1.1, DNS #2: 1.0.0.1
pm open,type:2 0
Connection failed.
While this sketch works as expected:
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <Ticker.h>
#include <Arduino.h>
void connectHost(const char*, int);
void _delay(unsigned long);
void setup() {
Serial.begin(74880);
Serial.setDebugOutput(true);
Serial.flush();
WiFi.begin(F("Xxxxx"), F("xxxxxxxx"));
Serial.println();
Serial.print(F("Waiting for connection."));
while (WiFi.status() != WL_CONNECTED) {
Serial.print(F("."));
delay(500);
}
Serial.println();
Serial.println(F("Connected."));
WiFi.mode(WIFI_STA);
delay(200);
MDNS.begin(WiFi.hostname());
Serial.print(F("DNS #1: "));
Serial.print(WiFi.dnsIP().toString().c_str());
Serial.print(F(", DNS #2: "));
Serial.println(WiFi.dnsIP(1).toString().c_str());
}
void loop() {
WiFiClient client;
client.setTimeout(10000);
while (true) {
int retval = client.connect("google.com", 80);
if (retval != 1) {
Serial.println(F("Connection failed."));
return;
} else {
Serial.println(F("Connected to endpoint."));
}
_delay(5000);
}
}
void _delay(unsigned long ulDelay) {
unsigned long ulNow = millis();
unsigned long ulThen = ulNow + ulDelay;
while (ulThen > millis()) {
yield();
}
}
Result:
Waiting for connection.......scandone
Connected.
DNS #1: 1.1.1.1, DNS #2: 1.0.0.1
pm open,type:2 0
Connected to endpoint.
Since I really wanted the flexibility of the Ticker() callback, I ended up using a static bool which was flipped by the Ticker() and picking that up in the loop and calling my connection like this:
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <Ticker.h>
#include <Arduino.h>
void connectHost(const char*, int);
static bool doConnect = false;
void setup() {
Serial.begin(74880);
Serial.setDebugOutput(true);
Serial.flush();
WiFi.begin(F("Xxxxx"), F("xxxxxxxx"));
Serial.println();
Serial.print(F("Waiting for connection."));
while (WiFi.status() != WL_CONNECTED) {
Serial.print(F("."));
delay(500);
}
Serial.println();
Serial.println(F("Connected."));
WiFi.mode(WIFI_STA);
delay(200);
MDNS.begin(WiFi.hostname());
Serial.print(F("DNS #1: "));
Serial.print(WiFi.dnsIP().toString().c_str());
Serial.print(F(", DNS #2: "));
Serial.println(WiFi.dnsIP(1).toString().c_str());
}
void loop() {
Ticker lookup;
lookup.attach(5, [lookup](){doConnect = true;});
while (true) {
if (doConnect) {
doConnect = false;
connectHost("google.com", 80);
}
yield();
}
}
void connectHost(const char* hostname, int port) {
WiFiClient client;
client.setTimeout(10000);
int retval = client.connect(hostname, port);
if (retval != 1) {
Serial.println(F("Connection failed."));
return;
} else {
Serial.println(F("Connected to endpoint."));
}
}
A bit of a kludge, but it works now.