9.4. Bringing the link up¶
The link layer covered on the previous page is mostly automatic, but there is one place a Python script has to step in: telling the camera which network to join. Until that step succeeds, none of the network features the rest of this section covers will work.
9.4.1. The network module¶
The network module exposes the camera’s networking hardware to Python. The exact set of interfaces depends on the board: many cams have a wireless chip and expose a WLAN class (named for Wireless Local Area Network); some boards also have a built-in Ethernet port and expose a LAN class (named for Local Area Network, i.e. the wired version). The pattern of use is the same for both, with one important difference: a wireless interface has to be told which network to join, while Ethernet picks up whatever is on the cable.
9.4.2. The Wi-Fi flow¶
Joining a Wi-Fi network is three steps: construct the interface, bring it up, ask it to connect to a named network with a password. The interface negotiates with the access point in the background; an isconnected() call reports when the link has finished coming up:
import network
import time
wlan = network.WLAN(network.WLAN.IF_STA)
wlan.active(True)
wlan.connect("my-network", "my-password")
while not wlan.isconnected():
time.sleep_ms(100)
print("link up")
The argument IF_STA selects station mode – the camera joins a network somebody else is hosting. The opposite mode, IF_AP, makes the camera host its own small network that other devices can join; useful for configuration interfaces and on-site setup, but not the common case.
Once isconnected() returns True, the camera is on the network. Everything else the higher layers needed to set themselves up has happened automatically while the link was coming up; the pages ahead spell those pieces out one at a time.
9.4.3. What can go wrong¶
A few practical failure modes show up at this step.
Wrong network name or password. The connection attempt silently retries until the application gives up. Wrap the wait with a timeout so the loop above does not block forever:
start = time.ticks_ms() while not wlan.isconnected(): if time.ticks_diff(time.ticks_ms(), start) > 10000: raise OSError("Wi-Fi did not come up in 10 s") time.sleep_ms(100)
Out of range. The camera and the access point have to be close enough that the signal is strong enough to hold a link.
status()returns a code indicating why the link is not up;scan()returns the list of networks the radio can see, which is the diagnostic to run whenconnectwill not succeed.Access point asks for more than a password. Open networks (no password) and the common password-protected ones are covered by
connectas shown above. Larger networks at workplaces and schools sometimes use a different scheme where the camera has to authenticate against a separate login server; those need extra arguments toconnect. See class WLAN – control built-in WiFi interfaces for the full surface.
9.4.4. Staying connected¶
Bringing the link up is half the problem. Staying connected is the other half – access points reboot, the cam roams out of range, DHCP leases expire, the radio firmware occasionally gets stuck. A cam that is going to live on the network for months has to notice that and recover on its own.
The detection pattern is to call isconnected() once per main-loop iteration and react when it returns False. isconnected() can lie briefly when a connection has dropped without the radio having noticed yet – a socket send that fails when the link “should” be up is the application’s other evidence of a drop. status() is the more authoritative source when the two disagree.
The reconnect pattern is disconnect() followed by connect() with the same credentials, with the wait wrapped in a timeout as on the initial connection. Back off between attempts – one second, two, four, doubling up to a minute or so – so a long outage does not hammer the AP and does not burn the radio’s power budget on spin loops:
import network
import time
_BACKOFF_S = (1, 2, 4, 8, 16, 32, 60)
def reconnect(wlan, ssid, password):
for delay in _BACKOFF_S:
wlan.disconnect()
wlan.connect(ssid, password)
deadline = time.ticks_add(time.ticks_ms(), 10_000)
while not wlan.isconnected():
if time.ticks_diff(deadline, time.ticks_ms()) < 0:
break
time.sleep_ms(100)
if wlan.isconnected():
return True
time.sleep(delay)
return False
When that helper keeps returning False, the radio firmware itself may be wedged. The last resort is power-cycling the radio: active(False), a brief pause, active(True), reconnect from scratch. This brings the radio firmware back to a known state at the cost of an extra few seconds of downtime:
def radio_power_cycle(wlan, ssid, password):
wlan.active(False)
time.sleep(1)
wlan.active(True)
return reconnect(wlan, ssid, password)
A cam that has been off-network for minutes is a real failure that the application has to see. The recovery code should surface that state – mark the network as unhealthy in a flag the main loop checks, and let the application skip the network sends it would have made while the flag is clear – so a long outage does not stall the application waiting on sockets that will never write.
9.4.5. Ethernet, when present¶
Boards with built-in Ethernet expose the same pattern without the connect step. The LAN interface is brought up with active(), and as soon as the cable is plugged in the interface is ready to use:
import network
lan = network.LAN()
lan.active(True)
print("link up")
After this point the rest of this section’s pages apply the same way regardless of which interface brought the camera onto the network. The higher layers do not care whether the link below them is Wi-Fi or Ethernet – “connected” is “connected”.
For the full WLAN and LAN reference, including the configuration knobs that did not fit here, see network — network configuration.