Fork me on GitHub

Project Notes

#508 Using mDNS

Delving into multicast DNS and how it can be used to find and connect to ESP32 devices on the network.

Build

Notes

When an ESP32 is used to offer some kind of network service (e.g. a web interface or API), it necessary to figure out how a client can locate and connect to the service, especially of the ESP is getting an address from a DHCP pool instead of being statically assigned.

It is not very convenient to use IP address, as these can change over time and one has to find out the address it is using in the first place. What we want to do is connect by hostname, and have the network perform the name resolution for us.

The ESP32 supports Multicast DNS (mDNS) for this purpose. The mDNS protocol resolves hostnames to IP addresses within small networks that do not include a local name server.

For the ESP32, support for mDNS is included in both ESP-IDF and Arduino ESPmDNS library.

I’m using the ESPmDNS library for this investigation.

Building and Running the Example

The UsingMDNS.ino is a simple web server example that demonstrates registration with mDNS.

Copy settings.h.template to settings.h and fill in the WiFi access credentials before compiling and uploading the program to the ESP32.

The console will confirm the DHCP IP address and name that the device registers on the network:

console_startup

Minimum Registration Details

The minimum required to regster the ESP32 is to begin the mDNS service with a hostname:

#include <ESPmDNS.h>
char hostname[] = "esp32-using-mdns";
MDNS.begin(hostname)

Querying the Device

The dns-sd utility is available on MacOS for managing and querying mDNS registrations. With dns-sd, I can find the ESP32 on the network, and confirm the IP address it is using.

$ dns-sd -q esp32-using-mdns.local
DATE: ---Sun 10 Nov 2019---
14:55:54.837  ...STARTING...
Timestamp     A/R Flags if Name                          Type  Class   Rdata
14:55:54.838  Add     2  7 esp32-using-mdns.local.       Addr   IN     192.168.1.181

console_lookup

The ESP32 web service can be loaded by domain name:

$ curl -vv http://esp32-using-mdns.local/
*   Trying 192.168.1.181...
* TCP_NODELAY set
* Connected to esp32-using-mdns.local (192.168.1.181) port 80 (#0)
> GET / HTTP/1.1
> Host: esp32-using-mdns.local
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/html
< Content-Length: 261
< Connection: close
<
* Closing connection 0
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"></head><body><h1>UsingMDNS</h1><p>Hostname: esp32-using-mdns.local</p><p>IP address: 192.168.1.181</p></body></html>$
$

web_result

Additional Registration Details

Additional details can be registered with the addService method:

// (optional) Register standard HTTP service
MDNS.addService("http", "tcp", 80);
// (optional) Register an arbitrary service name
MDNS.addService("leap", "tcp", 80);

Browsing HTTP services:

$ dns-sd -B _http
Browsing for _http._tcp
DATE: ---Sun 10 Nov 2019---
14:21:51.641  ...STARTING...
Timestamp     A/R    Flags  if Domain               Service Type         Instance Name
14:21:51.642  Add        2   7 local.               _http._tcp.          esp32-using-mdns
...

Browsing HTTP services and listing in zone file format:

$ dns-sd -Z _http
Browsing for _http._tcp
DATE: ---Sun 10 Nov 2019---
16:56:08.001  ...STARTING...

; To direct clients to browse a different domain, substitute that domain in place of '@'
lb._dns-sd._udp                                 PTR     @

; In the list of services below, the SRV records will typically reference dot-local Multicast DNS names.
; When transferring this zone file data to your unicast DNS server, you'll need to replace those dot-local
; names with the correct fully-qualified (unicast) domain name of the target host offering the service.

_http._tcp                                      PTR     esp32-using-mdns._http._tcp
esp32-using-mdns._http._tcp                     SRV     0 0 80 esp32-using-mdns.local. ; Replace with unicast FQDN of target host
esp32-using-mdns._http._tcp                     TXT     ""
...

$ dns-sd -Z _leap
Browsing for _leap._tcp
DATE: ---Sun 10 Nov 2019---
14:53:40.540  ...STARTING...

; To direct clients to browse a different domain, substitute that domain in place of '@'
lb._dns-sd._udp                                 PTR     @

; In the list of services below, the SRV records will typically reference dot-local Multicast DNS names.
; When transferring this zone file data to your unicast DNS server, you'll need to replace those dot-local
; names with the correct fully-qualified (unicast) domain name of the target host offering the service.

_leap._tcp                                      PTR     esp32-using-mdns._leap._tcp
esp32-using-mdns._leap._tcp                     SRV     0 0 80 esp32-using-mdns.local. ; Replace with unicast FQDN of target host
esp32-using-mdns._leap._tcp                     TXT     ""

The ESPmDNS library has an enableArduino method that registers Arduino details in a TXT record

// (optional) Register arduino details
MDNS.enableArduino(80, false);

Listing the registered details:

$ dns-sd -Z _arduino
Browsing for _arduino._tcp
DATE: ---Sun 10 Nov 2019---
14:52:30.093  ...STARTING...

; To direct clients to browse a different domain, substitute that domain in place of '@'
lb._dns-sd._udp                                 PTR     @

; In the list of services below, the SRV records will typically reference dot-local Multicast DNS names.
; When transferring this zone file data to your unicast DNS server, you'll need to replace those dot-local
; names with the correct fully-qualified (unicast) domain name of the target host offering the service.

_arduino._tcp                                   PTR     esp32-using-mdns._arduino._tcp
esp32-using-mdns._arduino._tcp                  SRV     0 0 80 esp32-using-mdns.local. ; Replace with unicast FQDN of target host
esp32-using-mdns._arduino._tcp                  TXT     "auth_upload=no" "ssh_upload=no" "tcp_check=no" "board=esp32"

Construction

There is no “circuit” to construct per se - simply powering the ESP32 from the USB port.

Breadboard

Schematic

Credits and References

About LEAP#508 ESP32mDNS
Project Source on GitHub Project Gallery Return to the LEAP Catalog

This page is a web-friendly rendering of my project notes shared in the LEAP GitHub repository.

LEAP is just my personal collection of projects. Two main themes have emerged in recent years, sometimes combined:

  • electronics - usually involving an Arduino or other microprocessor in one way or another. Some are full-blown projects, while many are trivial breadboard experiments, intended to learn and explore something interesting
  • scale modelling - I caught the bug after deciding to build a Harrier during covid to demonstrate an electronic jet engine simulation. Let the fun begin..
To be honest, I haven't quite figured out if these two interests belong in the same GitHub repo or not. But for now - they are all here!

Projects are often inspired by things found wild on the net, or ideas from the many great electronics and scale modelling podcasts and YouTube channels. Feel free to borrow liberally, and if you spot any issues do let me know (or send a PR!). See the individual projects for credits where due.