prerequisite
Networking basics
Just enough networking for a microcontroller: WiFi joining, IP addresses, TCP and UDP, HTTP, and publish-subscribe messaging.
Before this
Nothing beyond first-year college math. This is a starting page.
Why you need this
The "Go wireless" stage of the pipeline on the hub is where a gadget stops being alone: it sends a sensor reading to your phone, fetches an update, or tells another board a key was pressed. Each of those rides on a stack of ideas that has nothing to do with the ESP32 itself: radio, addresses, connections, and messages. This page gives you those ideas, so WiFi and MQTT and ESP-NOW and Bluetooth LE can focus on code.
The idea
Networking is built in layers. Each layer solves one problem and relies on the one below it.
| Layer | Problem it solves | Names you will see |
|---|---|---|
| Link | get bytes across one radio hop | WiFi, ESP-NOW, Bluetooth LE |
| Network | get a packet to any machine by address | IP, DHCP |
| Transport | get data to the right program, reliably or quickly | TCP, UDP, ports |
| Application | say something meaningful | HTTP, DNS, MQTT |
| Security (wraps the application) | keep it private and authentic | TLS |
WiFi: joining a network
WiFi is a radio link to an access point (AP), the box that runs the network, usually your router. The ESP32's WiFi radio works on the 2.4 GHz band, per the author's board notes. A board can act in two roles:
- Station (STA): it joins an existing network, like a phone does. This is the usual mode.
- Access point: it runs its own small network that a phone joins. Gadgets use this for first-time setup, when they do not yet know your network's name.
To join, the station needs the network's name, the SSID (service set identifier), and its password. A network lives on one channel, a slice of the band; every device on it uses that channel.
IP addresses and DHCP
Once joined, the board needs an IP address, a number that identifies it on the network, written as four bytes like 192.168.1.42. It almost never picks one itself. It asks with DHCP (dynamic host configuration protocol): the board broadcasts "I need an address", and the router replies with an address to use, the router's own address (the gateway, where traffic for the internet goes), and the address of a name server.
Ports, TCP, and UDP
An IP address finds the machine. A port, a number from 0 to 65535, finds the program on that machine. Well-known services have standard ports: HTTP uses 80, HTTPS 443, DNS 53, and MQTT 1883, or 8883 when wrapped in TLS. The author's ESP_32_SAI sensor project connects its MQTT client to port 8883 with TLS on.
Two transports carry data between ports:
| TCP | UDP | |
|---|---|---|
| Connection | set up first with a three-message handshake | none: just send |
| Delivery | every byte arrives, in order, or the connection reports failure | each packet may be lost, duplicated, or reordered |
| Good for | web pages, MQTT, file downloads | DNS lookups, live sensor streams where the next reading replaces a lost one |
DNS
DNS (domain name system) turns a name like broker.example.com into an IP address, by asking the name server DHCP named.
HTTP
HTTP is request and response over TCP: the client sends a line such as GET /status HTTP/1.1 plus headers; the server returns a status code (200 OK, 404 not found), headers, and a body.
TLS, and why it is hard on a microcontroller
TLS (transport layer security) wraps a TCP connection so nobody in between can read or change it, and so the board can check it is talking to the real server. HTTPS is HTTP inside TLS. Before any data flows, the two sides run a handshake: the server proves its identity with a certificate, a signed document the board checks against a trusted root certificate it carries, and both sides agree on encryption keys using public-key math.
That handshake is the expensive part for a small chip: it needs large buffers for the certificate chain and encrypted records, plus the math, while WiFi also uses RAM. Under MicroPython that memory comes from the same pool your program uses, so a program that runs fine without TLS can fail with a memory error once it connects securely (WiFi and MQTT shows this). It is worth paying for anything that crosses the internet.
Publish and subscribe: MQTT
HTTP has the client ask and the server answer. Sensors want something different: "whenever I have a reading, send it to whoever cares". Publish-subscribe does this through a middleman, the broker:
- A board publishes a message to a topic, a name such as
devices/sensor-1/telemetry. - Any program that subscribed to that topic gets a copy from the broker.
- Publisher and subscribers never connect to each other, only to the broker.
MQTT is the publish-subscribe protocol most microcontrollers use. The board keeps one TCP connection open to the broker and sends small messages over it. The same connection works both ways: ESP_32_SAI publishes readings to a telemetry topic and subscribes to a commands topic for instructions from the cloud.
Without a router: peer-to-peer radio
Two ESP32 boards can also talk radio to radio with ESP-NOW, Espressif's protocol for short messages addressed by each board's MAC address (a fixed 6-byte hardware address): no router, IP, DHCP, or TCP, and no internet at the other end. Bluetooth LE is a third option, for a phone nearby. ESP-NOW and Bluetooth LE covers both.
Worked example
Here is every step from power-on to one sensor reading arriving at a broker, in the shape of the author's ESP_32_SAI project. Names and addresses are illustrative: your-ssid, broker.example.com, and private addresses like those a home router hands out.
| # | Step | Layer | Messages |
|---|---|---|---|
| 1 | Radio on, scan for your-ssid |
Link | the AP's periodic beacons are heard |
| 2 | Join with the password | Link | authentication and association with the AP |
| 3 | Get an address | Network | DHCP: board asks, router answers with 192.168.1.42, gateway 192.168.1.1, name server |
| 4 | Look up the broker | Application (over UDP) | DNS query for broker.example.com to port 53; reply with its IP |
| 5 | Open a connection | Transport | TCP handshake to port 8883: three messages |
| 6 | Secure it | Security | TLS handshake: server certificate checked against the stored root, keys agreed |
| 7 | Log in to the broker | Application | MQTT CONNECT, broker answers CONNACK |
| 8 | Subscribe | Application | MQTT SUBSCRIBE to the commands topic |
| 9 | Read the sensor | none | an I2C read, on the board |
| 10 | Publish | Application | MQTT PUBLISH of a small JSON message to the telemetry topic |
| 11 | Wait, then repeat 9 and 10 | the TCP and TLS connection stays open |
Steps 1 to 8 happen once per boot. Steps 9 and 10 repeat: ESP_32_SAI's config reads every 5 seconds, which is readings a day over one connection. If the connection drops, the board goes back to step 5 (or step 1 if WiFi itself dropped). The bytes in one PUBLISH are sized on WiFi and MQTT.
In an ESP32 project
Joining WiFi usually happens in MicroPython's boot.py or a startup task in C with ESP-IDF. Gadgets that cannot reach the internet, such as the author's keyboard-to-display link, skip the whole table and use ESP-NOW.
Common mistakes
- Wrong band. Symptom: the board never finds a network your laptop sees. The ESP32 radio is 2.4 GHz only; a network that exists only at 5 GHz is invisible to it.
- No timeout on joining. Symptom: the board hangs forever at boot when the router is off. Try for a fixed time, then report failure and carry on or retry.
- Name lookup or TLS failing on an otherwise working network. Symptom: the board has an IP address but cannot reach the broker. Check DNS and the stored root certificate before blaming WiFi.
- Treating a dropped connection as fatal. Symptom: readings stop after the router reboots and never resume. Loop back to reconnect.
- Credentials in shared code. Symptom: your WiFi password ends up in a repository. Keep them in a config file that is never committed.
Cost
The one-time steps dominate: joining, DHCP, DNS, and the TLS handshake take far longer than one publish and need the most RAM, so connect once and keep the connection open. A radio that stays on draws current the whole time, so battery gadgets often turn it off between readings and pay the connect cost on each wake.
Going further
- WiFi and MQTT, the code for the table above.
- ESP-NOW and Bluetooth LE, for links without a router.
- Over-the-air updates, which fetches files over HTTPS.
- The MQTT 3.1.1 specification's sections on CONNECT and PUBLISH, for the packet layouts.
Leads to
Back to ESP32 development: assembly, C, MicroPython, and CircuitPython