ESP32/Other radios/65. ESP-WIFI-MESH
Your chip
Your language
Other radios · 65 of 81

ESP-WIFI-MESH

Nodes that relay for each other, so the far end of the shed reaches the router through the one in the middle. It costs latency, throughput and complexity — here is when that trade is worth making.

/esp32/esp-wifi-mesh · arduino · S3

What "self-healing" actually is

One node dies, the tree re-forms
healthy
Nodes up
6
Orphaned
none
Worst path
2 hops
Step 0 of 5. A healthy mesh. Only the root talks to your router; everything else reaches the internet through a parent.

It is a sequence, not a property. A parent stops answering, its children notice after a few missed beacons, they scan for anything already in the mesh, and they re-attach wherever they can hear. Nobody configures it and no code of yours runs.

The cost is in the last frame: the node that lost its parent is now further from the root, so its messages cross more links. Self-healing keeps the network up; it does not keep it fast.

Two different things are called mesh here

ESP-WIFI-MESH is Espressif's own, in ESP-IDF. It has a root node that holds the connection to your router, so the mesh has a way out to the internet, and it manages the tree properly.

painlessMesh is the Arduino library everybody actually starts with. It builds a standalone network with no router in it at all. That makes it trivial to set up and means nothing reaches the internet until you write a bridge node that runs both the mesh and a normal Wi-Fi connection.

Knowing which one an example is using explains most of the confusion in mesh forum threads.

Before you build one

Ask whether you need a mesh or just more range. Three honest alternatives:

  • A second access point. Cheap, boring, and it makes every board a plain station with no library at all.
  • ESP-NOW. No router, no association, about two milliseconds per message, and a one-hop relay is ten lines. Most "mesh" projects are this.
  • LoRa. If the far end is a paddock away rather than a room away, kilometres at a few hundred bytes a minute beats any number of Wi-Fi hops.

A mesh earns its complexity when there are many nodes, the layout is not known in advance, and nodes come and go. For six sensors in a house it is usually the harder path to the same result.

On your S3
ChipXtensa LX7 · 2 × 240 MHz
Board settingESP32S3 Dev Module
Default I2CSDA 8 · SCL 9
Watch out forThe port vanishes after upload

The code

painlessMesh is the approachable way in. Every node runs the same sketch and the tree forms itself — there is no root to configure and no addresses to assign.

mesh.ino
#include <painlessMesh.h>

#define PREFIX "tinkerblock-mesh"
#define PASS   "meshpassword"
#define PORT   5555

Scheduler scheduler;
painlessMesh mesh;

void sendReading() {
  mesh.sendBroadcast("21.4 from " + String(mesh.getNodeId()));
}
Task tReport(TASK_SECOND * 5, TASK_FOREVER, &sendReading);

void setup() {
  Serial.begin(115200);
  mesh.setDebugMsgTypes(ERROR | CONNECTION);
  mesh.init(PREFIX, PASS, &scheduler, PORT);

  mesh.onReceive([](uint32_t from, String &msg) {
    Serial.printf("%u: %s\n", from, msg.c_str());
  });
  mesh.onChangedConnections([]() {
    Serial.printf("topology changed, %d nodes\n", mesh.getNodeList().size() + 1);
  });

  scheduler.addTask(tReport);
  tReport.enable();
}

void loop() {
  mesh.update();
}

painlessMesh builds its own network with no router in it, which is the difference from Espressif's ESP-WIFI-MESH. Nothing here reaches the internet unless you add a bridge node.

When it does not work

Nodes see each other and messages never arrive

The prefix, password and port must be identical on every node, and the password must be at least eight characters. A node with a different port joins the same Wi-Fi and lands in a separate mesh that looks identical from the outside.

The mesh works on the bench and not in the building

Mesh nodes need to hear each other, not the router. Two nodes at opposite ends with nothing in between do not form a link no matter how good the router is. Walk the path and place a node where the signal is still workable.

Latency is fine for two nodes and terrible for eight

Every hop is a full Wi-Fi transmission, and the tree gets deeper as it spreads. Three hops is already several hundred milliseconds. If the data is a reading every minute this is irrelevant; if it is a light switch, it is not.

One node keeps restarting and the whole mesh stutters

A node re-joining forces its children to re-parent, which ripples. Find why it resets — brown-out during a transmit burst is the usual answer — before blaming the mesh library.

Where this goes next

The standardised version of this idea, on a different radio, with a phone app that already exists and did not need writing.

Zigbee, Thread and Matter

Edit this page — content/esp32/esp-wifi-mesh.mdx

Discuss this article

Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.

Browse ESP32 on the forum