I have a fairly large, complex 8266 application that implements a custom mesh-like network that is basically a tree-like structure of nodes. There is a top-level AP+STA node that connects to my TP-Link router. That node has several other 8266s, also in AP+STA mode, connected to it. Each of those nodes has a number of 8266 STA-onlly nodes connected to them. ALL nodes are running the exact same firmware, the only difference being the SSIDs and passwords they use, and their IP addresses. Hard IPs are used everywhere except for the connection to the TP-Link network, and the only communications between the nodes is via UDP packets that are sent between directly-connected nodes.
This all works just great, except for getting the initial STA connections BETWEEN 8266s going. The top-level node always connects to the TP-link just fine. The others generally connect only if all the nodes are started in the correct order. If I reset the nodes all at once, or first the top-level node, then the two intermediary nodes that connect to it, then the lowest-level nodes, all is well. But, if I then reset any of the intermediary or lowest-level nodes, they will, in most cases, never re-connect, despite all having auto-connect and auto-reconnect enabled. It acts like each node is only allowed to connect one time, and never again, either resetting the AP to which a node is trying to connect. What's really odd is the AP always works fine for OTHER drives. I can always connect my phone to any of the 8266 APs. Also, every once in a while, a single message will slip through, as though the connection is made for a split-second, then closed again.
Another thing: I NEVER see a status of WL_CONNECTED, no matter what the state of the connection is - whether the connection is up or down, status() ALWAYS returns any state BUT WL_CONNECTED. Could I be using a bad library? I'm using the one installed by board manager, for IDE v1.8.4. I also sometimes see communications in only one direction. For instance, I can sometimes send messages from an AP to a STA, but not the other way around.
What is the trick to making these things actually be able to disconnect and re-connect?
Here is the code used to initialize all the nodes. InitializeAP() is used to initialize those nodes that are both AP+STA, and InitializeTimer() is used to initalize the STA-only nodes. Again, this always works perfectly on the first try when the 8266s are reset in the correct order, so there seems to be no issue with the init sequence, or the values being passed. There must be something I'm missing in the initialization. I am current running on NODEMCUs, but the behavior is exactly the same running on ESP-01s.
boolean TimerWiFiDeviceAPI::InitializeAP(TimerModes mode,
char *apssid, char *appassword, IPAddress apip, IPAddress gatewayip, uint8_t apchannel,
char *stassid, char *stapassword, IPAddress staip,
uint16_t port)
{
boolean success = false;
ConsolePort->printf("Initializing %s AP for Network %s on Channel %d...\n", DeviceName, TimerAPSSID, TimerAPChannel);
while (!success)
{
// Set Mode
if (!(success = WiFi.mode(WiFiMode_t::WIFI_AP_STA)))
continue;
// Configure STA
if (!(success = WiFi.config(staip, gatewayip, Netmask, gatewayip)))
continue;
// Configure AP
if (!(success = WiFi.softAPConfig(TimerAPIP, GatewayIP, Netmask)))
continue;
if (!(success = WiFi.setAutoConnect(true)))
continue;
if (!(success = WiFi.setAutoReconnect(true)))
continue;
// Start/Connect AP + STA
if (!(success = WiFi.begin(stassid, stapassword)))
continue;
if (!(success = WiFi.softAP(apssid, appassword, apchannel)))
continue;
}
// Setup port listener
UDP = new WiFiUDP();
ConsolePort->printf("UDP listener%s ready!\n", UDP->begin(UDPPort) ? "" : " not");
}
void TimerWiFiDeviceAPI::InitializeTimer(char *stassid, char *stapassword, IPAddress staip, IPAddress gatewayip)
{
boolean success = false;
// Setup WiFi Client
ConsolePort->printf("Initializing %s Timer for Network %s...\n", DeviceName, stassid);
while (!success)
{
// Set Mode
if (!(success = WiFi.mode(WiFiMode_t::WIFI_STA)))
continue;
// Configure STA
if (!(success = WiFi.config(staip, gatewayip, Netmask, gatewayip)))
continue;
if (!(success = WiFi.setAutoConnect(true)))
continue;
if (!(success = WiFi.setAutoReconnect(true)))
continue;
// Connect STA
if (!(success = WiFi.begin(stassid, stapassword)))
continue;
}
// Setup port listener
UDP = new WiFiUDP();
ConsolePort->printf("UDP listener%s ready!\n", UDP->begin(UDPPort) ? "" : " not");
}
Regards,
Ray L.