Moving an Ethernet prototype to another network: check DHCP and DNS separately

Your prototype sends data across your desk, but the first person testing it elsewhere gets an offline message. Before rewriting the application, ask two smaller questions: did the board get a usable network address, and can it find the server by name?

We ran separate DHCP and DNS experiments on a W5500 Ethernet board under MicroPython to make those two checkpoints visible. They are useful when preparing a connected exhibit, a data logger or another wired prototype for handoff. Our runs show address configuration and name lookup; they do not establish that an application service is working.

This distinction appears in real development questions. In a November 2021 GHI forum thread, a builder's W5500 setup worked with a static address but failed to obtain one through DHCP. That example uses TinyCLR, not MicroPython, so its replies are not a fix for this board. It illustrates why "Ethernet works" is too vague to describe the starting point.

Record the address the board actually received

DHCP lets a network assign configuration to the device. In our setup the W5500 was connected to a router with a DHCP service. A cable directly to a computer is not automatically equivalent: something on that connection still needs to provide the address configuration, or both ends need a suitable manual setup.

In one run the board reported an address of 192.168.1.11, a subnet mask of 255.255.255.0, and 192.168.1.1 for both gateway and DNS. The board address identifies this device on that network; the mask describes the local address range; the gateway provides a route beyond it; DNS helps turn a server name into an address. These are example results, not settings to copy to the next site.

The program talks to the W5500 over SPI0 at a requested 2 MHz, using GPIO19/16/18 for MOSI/MISO/clock, GPIO17 for chip select and GPIO20 for reset. Those are this board's connections. The firmware identified itself as MicroPython 1.23.0 on a W5500-EVB-Pico; confirm the board-specific network build as well as the Python version.

A second recorded run got 192.168.2.161, with gateway and DNS at 192.168.2.1. DHCP is meant to obtain settings from the attached network, so a different address is not in itself a fault. However, these two runs do not amount to a controlled test of moving the same running device between networks.

The program calls nic.ifconfig('dhcp'), then prints the four returned settings. The exact calls depend on the firmware. The MicroPython 1.23 WIZNET5K reference documents the configuration tuple and compile-time chipset support, but does not list every call used by this board build. Keep the working firmware image or release identifier with the project.

Do not let a fallback hide the failure

Our test program caught an exception from DHCP and substituted a fixed configuration: 192.168.1.20, mask 255.255.255.0, gateway 192.168.1.1, and DNS 8.8.8.8. That is a convenient bench setup. It is not a recovery strategy for another building's network.

If the new site uses a different address range, the fallback may leave the board apparently configured but unreachable. Even on a matching range, that fixed address might already belong to another device. A product should make the chosen mode visible: address obtained automatically, manual configuration applied, or configuration failed. The user should not have to infer it from a light beside the Ethernet socket.

Next we sent four ping requests from a computer to the assigned address and got four replies with no loss, in that small sample. That is a useful reachability check, not a test of the server your product needs. Similarly, the WIZNET5K reference describes isconnected() as physical link status. A cable link, a usable address and a successful application request are separate observations. Record them separately so the engineer receiving a failure report knows where to start.

Resolve a name before testing the service

The DNS experiment asked for the address of a public website after initializing the interface, using a small helper:

from usocket import getaddrinfo, SOCK_STREAM

def dns_query(domain):
    results = getaddrinfo(domain, 80, 0, SOCK_STREAM)
    return results[0][4][0]

The requested port and stream type describe the kind of socket address needed. This call does not open a web page or send an HTTP request. The 0 family argument permits the available address families rather than explicitly requesting IPv4; check the result and the capabilities of the selected firmware when turning this into an application. The MicroPython socket reference explains the returned address records.

With the fixed configuration (192.168.1.20, DNS 8.8.8.8) the lookup returned 118.31.180.41. A later run with DHCP configuration returned 114.55.118.8 for the same name. These are results from different runs. Domain names can have changing or multiple answers, so the test is not "does today's answer equal the number from last time?"

We also compared the returned address against a public IP-lookup website. That helps explain what was returned at the time, but it does not prove that the board can reach an application, authenticate to it or exchange useful data. Continue with the actual service connection and a known request after name lookup succeeds.

Give the next tester a useful failure report

During name lookup you may see OSError: -2, and a common suggestion is to try another DNS server. Treat that as a starting hypothesis. MicroPython documents name-lookup errors separately from ordinary system error numbers; the exception alone does not establish that a particular resolver is blocked. A missing route, an unsuitable configuration or firmware behavior can require a different investigation.

At a managed site, use the resolver and network settings agreed with the network owner. Replacing an internal resolver with a public one may prevent an internal service name from resolving. It also makes the prototype behave differently from other devices at the site, which complicates the next diagnosis.

Before the handoff, prepare a short startup report:

Keep credentials out of that report. Add a visible timeout or retry state so a failed network step does not leave the product silently waiting forever; our test connection loop had no overall deadline.

Then ask the tester to repeat the startup on the intended network and after a cable reconnection. We have not run these acceptance checks; they answer the practical question behind the experiment: can another person connect the device and tell you what failed without opening the firmware?