Raspberry Pi Pico W network becomes inaccessible when not used for some time
Using MicroPython v1.19.1 on 2022-09-20; Raspberry Pi Pico W with RP2040, Pico W loses network operation (though seemingly not AP connection since there is typically still an IP address) if no network operations are performed for some time. The maximum non-operating interval between network operations is typically about 5 minutes with Power-Saving on, and at least 10 minutes with Power-Saving off (more testing continues with this mode). The failure mode is typically OSError: -2.
If some operation, say a ping is done frequently, the network operation is preserved and more complex transactions (e.g., sockets) can be done with much longer intervals.
Code:
import time
import machine
import network
import urequests as requests
TEXT_URL = "http://wifitest.adafruit.com/testwifi/index.html"
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("ssid", "passw0rd")
while not wlan.isconnected() and wlan.status() >= 0:
print(f"Connected? {wlan.isconnected()} Status? {wlan.status()}")
time.sleep(1)
print(wlan.ifconfig()[0])
# increase delay between requests each time
interval_sec = 0
increment_sec = 60
timer_sec = time.time() - interval_sec
while True:
if time.time() - timer_sec > interval_sec:
try:
r = requests.get(TEXT_URL)
print(f"{interval_sec:>5} {r.status_code} {r.reason.decode()} {r.content}")
r.close()
interval_sec += increment_sec
except OSError as e:
print(e)
machine.reset()
timer_sec = time.time()
Output:
Connected? False Status? 1
192.168.6.198
0 200 OK b'This is a test of Adafruit WiFi!\nIf you can read this, its working :)'
60 200 OK b'This is a test of Adafruit WiFi!\nIf you can read this, its working :)'
120 200 OK b'This is a test of Adafruit WiFi!\nIf you can read this, its working :)'
180 200 OK b'This is a test of Adafruit WiFi!\nIf you can read this, its working :)'
240 200 OK b'This is a test of Adafruit WiFi!\nIf you can read this, its working :)'
-2
Possibly related to power-saving mode (wlan.config(pm = 0xa11140)) described in section 3.6.3 here.
Addendum: Pinging the device periodically from an external source also seems to extend accessibility of the network.
Addendum 2: Toggling the LED via the wifi module gives mixed results keeping the network alive, other factors may be at work. But the early test with network failure in Power-Saving off mode was perhaps spurious. A subsequent run has shown a longer interval possible between network operations.
The SDK doc indicates "Both the low level cyw43_driver and the lwIP stack require periodic servicing" (p.265), but it's not clear to me what those intervals are or how to recover the network from lack of servicing without a hard reset of the board after an OSError: -2.
IPv4 address can persist well after wifi AP connection is lost
MicroPython v1.19.1 on 2022-09-20; Raspberry Pi Pico W with RP2040
As noted in a comment in #9455:
wlan.status() of 3 means:
#define CYW43_LINK_UP (3) Connect to wifi with an IP address
as opposed to:
#define | CYW43_LINK_NOIP (2) Connected to wifi, but no IP address
But the device will still have an IP address even when it has become disconnected from the wifi Access Point (at least when it disconnects through the mechanism in 9455). Is this an intended feature, emergent feature, or bug? The IP address also sometimes returns 0.0.0.0, which I suspect is the wlan.status() == 2 case, and is at least is easy to check for.
From #8994:
The idea with soft reset is that it resets Python state but not necessarily hardware state. Eg soft reset won't put GPIO back to a default state, or disable USB. Any hardware that's left untouched after a soft reset should still be in a valid state, and if code expects to run after a soft reset then it must be aware that hardware peripherals can be in a variety of states when MicroPython code starts running.
But this doesn't seem to fall within the realm of hardware state, since the device shows an IP address at times when it doesn't actually have a connection to an AP and, particularly in the DHCP case, doesn't have a valid IP address.