If you’re running an ESP32 or ESP8266 on your local wireless network, you might like to talk to it. Send it some commands, or have it send some data for plotting. But before you can connect to it, we need to find it!
This article looks at finding wireless devices, such as the ESP32 or ESP8266, on a local network using mDNS.
What is mDNS?
mDNS stands for multicast DNS or multicast domain name system. It is a network protocol for resolving host names to IP addresses in small networks. The host-name is simply a text name that you assign your device in your Arduino sketch. Typically that name stays the same. Then mDNS lets you turn the device’s name into its current IP address.
Why is the IP Address Useful?
Serial ports are easy. Plug in an Uno and most software lets you pick the Serial port name from a list of available COM ports. Even if you have a couple of devices plugged in it doesn’t take too long to find the right one; worst case you can unplug the device and see which port disappears.
To make a connection with a WiFi device, such as the ESP32 or ESP8266 you’ll need its IP address. That’s the four dotted number assigned to each device on the network. For example:
192.168.92.1. The first 3 numbers are usually the same and each device gets a different value for the last number.
IP addresses are usually assigned by a DHCP Server when the device connects to the network. But it doesn’t keep track of device names.
How does mDNS work?
mDNS uses broadcast UDP packets. Whenever a client needs to resolve the name of a remote host it sends an IP multicast query to the local network. This query asks whichever host has the matching name to respond with its IP address. This makes it easy to find your device. You can simply ask for it by name!
Finding available devices using mDNS-SD
You can only find an IP Address with mDNS if you remember the name. But most people find it much easier to select a name from a list than to remember, and type it in. That’s where mDNS-SD comes in. The SD stands for Service Discovery.
mDSN-SD is a protocol for discovering services on the network to make a list of devices we might want to talk to. The service might be for serving web pages or controlling the motion of a robot arm. A services defines the protocol used to communicate.
Communication protocols define the language that a device speaks. Just like you’d have a hard job responding to où est la boulangerie if you don’t speak French, you can’t talk to a service on your Arduino if you don’t know the protocol. So we use two protocols:
- the mDNS-SD protocol to find devices that speak a (possibly custom) protocol we understand, then
- The custom protocol to communicate with them.
Happily, advertisements from a mDNS-SD server include the device’s IP address, along with:
- a protocol id: a text string that identifies the protocol
- the transport type, such as TCP or UDP, and
- the port your Arduino server is listening on.
Everything you need to reach out and make a connection.
What does an mDNS Name Look Like?
mDNS names describe a service end-point: all the information you need to find a connection. The name has 3 parts:
- The device’s name: a name you choose to identify the device. It should be unique on your local network so you can distinguish multiple devices.
- The service name.
- The transport type: usually TCP or UDP.
- A top level domain: the top-level domain for mDNS names is always .local.
The name and protocol are always prefixed by underscores (_). Here are some examples of mDNS names:
HallSensor._n8i-mlp._tcp.local: Device name of
n8i-mlp; TCP transport
WaterControl3A._n8i-mlp._udp.local: Device name of
Who uses mDNS?
mDNS, also called Bonjour by Apple, is more common than you might think. It is used by media players, printers and even the Raspberry Pi.
There are several applications for phones that will show you all the devices being advertised on your local network including Network Analyzer Pro and Service Browser for Android. Network Analyzer Pro is available for iOS devices too.
Of course, you can also browse mDNS services with MegunoLink.
mDNS for ESP32 and ESP8266
Espressif’s popular ESP32 and ESP8266 Arduino devices support mDNS. This is very handy for making wireless sensors as it lets you easily connect to them using software that supports mDNS name resolution, such as MegunoLink.
The code to enable mDNS discovery on an ESP32/ESP8266 is pretty straight forward. Here it is wrapped up into a function you can just drop into your sketch. Call the
AdvertiseServices function from your
setup function after connecting to the WiFi network:
void AdvertiseServices(const char *MyName)
Serial.println(F("mDNS responder started"));
Serial.print(F("I am: "));
// Add service to MDNS-SD
MDNS.addService("n8i-mlp", "tcp", 23);
Serial.println(F("Error setting up MDNS responder"));
To use the
AdvertiseServices function, simply supply a name. This is the name that clients will use to find the device.
This function registers a TCP service listening on port 23 with a service name of
n8i-mlp. This is the service that MegunoLink searches for by default. However, you can configure MegunoLink to search for any service using the mDNS Browser.
MegunoLink doesn’t require any specific protocol for the
n8i-mlp service. It treats the connection very similar to a directly connected serial stream. Anything MegunoLink does with a serial port can also be done with the wireless link.
Keep in mind that registering the service only advertises it to the local network. And you’ll need to connect your Arduino to a WiFi network before you can register services.
Choosing a Name
If you are going to have hundreds of devices on your network, you’ll want to take care to manage names so they are all unique. You could store the name in the device’s EEPROM and use MegunoLink’s Programing Visualizer to assign unique ids when the devices are programmed. However, that’s overkill if you’re only going to have a few devices on the network.
An easy solution if you only have one or two devices is to use the ESP8266’s built-in chip id, or part of the ESP32’s MAC address to make a name that’s probably going to be unique.
Here’s a bit of code that will work for the ESP32 and ESP8266. The
MakeMine function combines the device id with a template, which should be an easily recognizable name for the device. You’ll see this name in the mDNS browser.
/* Returns a semi-unique id for the device. The id is based
* on part of a MAC address or chip ID so it won't be
* globally unique. */
/* Append a semi-unique id to the name template */
String MakeMine(const char *NameTemplate)
uint16_t uChipId = GetDeviceId();
String Result = String(NameTemplate) + String(uChipId, HEX);
Then advertise your device and the services it provides in your setup function using:
String MyName = MakeMine("WiFiSensor");
Making the Connection in MegunoLink
MegunoLink includes a mDNS browser that will build a list of services available on the network. By default it will look for the services advertising the
n8i-mlp protocol on a TCP connection, but you can add other services using the mDNS browser.
Use the Connection Manager visualizer to make and manage TCP Client connections in MegunoLink.
- open the Connection Manager and add a TCP Connection.
- Select the mDNS address type.
- Select the protocol type.
- Choose your named device
Press the connect button to open the connection.
- mDNS offers a standard method to get the IP address of devices you want to connect to.
- A small piece of code in your Arduino sketch registers a name and protocol, along with your devices IP address and the service port.
- The name, protocol, transport type, port and IP address are advertised to the local network so client software can build a list of available devices and open connections.
mDNS makes WiIF devices nearly as easy to find as Serial ports.