B4R Question Problem with WiFi.ConnectAsync

RJB

Active Member
Licensed User
Longtime User
Hi,
I'm trying to cover the situation where the router fails then recovers, i.e. it's power goes off then back on.
An ESP32 monitors a ping message and, if it doesn't arrive in time, checks the router connection then loops, trying to reconnect.
if I use WiFi.Connect then it works OK but I don't want the code blocked while it waits (up to 15 seconds).
Using WiFi.ConnectAsync to avoid doesn't work, the 'connected' sub is called immediately (2mS) with 'success' set to fail.
I can't see any way to set the wait time.
If I put a delay (3000 mS) immediately after the WiFi.ConnectAsync then it works OK, but, of course, it blocks again.
The stripped out code is given below.
Is anybody able to help with what I am doing wrong?
Thanks
B4X:
'loops = 1 to 250. > 250 = infinite loops. 0 = do nothing
private Sub RouterConnectAsync(Loops As Byte)
    If Loops = 0 Then
        ReceiveWatchdog.Enabled = True
        Return 'do nothing or 'loop countdown' has reached 0
    End If
    ReconnectLoops = Loops
    Dim SSID As String = ReadSSID
    Dim Password As String = ReadP

    watchstart2 = Millis
    Main.eWiFi.ConnectAsync(SSID, Password, 0, Null, "wifi_Connected")
'    Delay(3000)
'    Dim x As Boolean = Main.eWiFi.Connect2(SSID, Password)
'    If x Then
'        WiFi_Connected(True)
'    Else
'        WiFi_Connected(False)
'    End If

End Sub

Sub WiFi_Connected(Success As Boolean)
    Log("WiFi_Connected: ", Success, " after: ", (Millis - watchstart2), "mS")
    If Success Then
        SetFixedIP(ReadClientIP) 'in case the router tries to change the IP
        AsyncReceiveServer.Listen
        ReceiveWatchdog.Enabled = True
        Return
    End If
    
    'loop, waiting for wifi
    If ReconnectLoops > 250 Then
        CallSubPlus("RouterConnectAsync", 1000, ReconnectLoops)        'infinite tries
    Else
        CallSubPlus("RouterConnectAsync", 1000, (ReconnectLoops - 1))    'loop tries
    End If
End Sub

Sub ReceiveWatchdog_Tick
    Log("Receive WDOG Tick")
    ReceiveWatchdog.Enabled = False

    If Not(Main.eWiFi.IsConnected) Then
        CallSubPlus("RouterConnectAsync", 1, 255) 'infinite tries
    Else
        ReceiveWatchdog.Enabled = True
    End If
End Sub
 

RJB

Active Member
Licensed User
Longtime User
I’m not sure I understand.
If it fails then it loops via the CallSubPlus at line 34 every 1 second.
It fails when the router goes down, calling the ‘connected’ sub immediately, then continues to do so even when the router is back up, looping once a second.
As mentioned Wi-Fi.connect manages to reconnect ok in those circumstances.
 
Upvote 0

RJB

Active Member
Licensed User
Longtime User
Thanks.
I won’t be able to try this until late Friday but will get back with the result then.
 
Upvote 0

RJB

Active Member
Licensed User
Longtime User
I've tried the above 'test' method. The results are a little confusing!
I assume the status values are:
WL_IDLE_STATUS = 0, WL_NO_SSID_AVAIL = 1, WL_SCAN_COMPLETED = 2, WL_CONNECTED = 3, WL_CONNECT_FAILED = 4, WL_CONNECTION_LOST = 5, WL_DISCONNECTED = 6, WL_NO_SHIELD = 255

To test I power up the router and let it boot. I then power up the esp32 and it connects correctly.
If I then de-power the router and re-power it quickly then the esp32 reconnects correctly (status = 3). The status is shown as 5 (disconnected) the first time I de-power the router but as 1 (no ssid) on subsequent times, however the esp32 does recover in both cases.
Repeating the above but leaving the router off longer (two minutes seems to be the limit) then the esp32 never recovers. If the status starts off as 5 then after some time (a minute or so) it changes to 1.
Importantly the actual live code for the 'RouterConnectAsync' sub is as given below, including SSID checking and logging so I know that the SSID is always present and correct.
Does that help to work out what's going on?

RouterConnectAsync:
private Sub RouterConnectAsync(Loops As Byte)
    If Loops = 0 Then
        ReceiveWatchdog.Enabled = True
        Return 'False    'do nothing or loop countdown has reached 0
    End If
    Log(TimeForDebug, " RWD Reconnect?: ", Loops, "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<")
    ErrorCode = RouterReconnect
    ReconnectLoops = Loops
    Dim SSID As String = EEPromFunctions.ReadSSID
    Dim Password As String = EEPromFunctions.ReadP
    Log(SSID, " : ", Password)
    If (SSID <> "") Then
        If Password = "" Then    'open network
            Main.eWiFi.ConnectAsync(SSID, "", 0, Null, "wifi_Connected")
        Else
            Main.eWiFi.ConnectAsync(SSID, Password, 0, Null, "wifi_Connected")
        End If
    Else
        'ssid not set, do nothing
        Log("RCA SSID not set!")
    End If

End Sub
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Find this line in rESP8266Wifi.cpp:
B4X:
if (WiFi.status() != WL_IDLE_STATUS && WiFi.status() != WL_DISCONNECTED) {
Change it to:
B4X:
if (WiFi.status() != WL_IDLE_STATUS && WiFi.status() != WL_DISCONNECTED &&  WiFi.status() != WL_CONNECTION_LOST) {
Does it work better?
You might need to add a check for WL_NO_SSID_AVAIL.
 
  • Like
Reactions: RJB
Upvote 0

RJB

Active Member
Licensed User
Longtime User
Yes, that did it, thanks for the help!
Using:
B4X:
if (WiFi.status() != WL_IDLE_STATUS && WiFi.status() != WL_DISCONNECTED &&  WiFi.status() != WL_CONNECTION_LOST &&  WiFi.status() != WL_NO_SSID_AVAIL) {
 
Upvote 0
Top