An offline network built from inexpensive ESP32 boards.
LocalGrid turns ordinary ESP32 boards into a self-forming network. Access points find each other and form a mesh by themselves, and touchscreen handhelds send text, emergencies, and push-to-talk voice across it. No Internet, no phones, and no cell service, ever.
Lines, and how far they reach
| Line | What it is | Hardware today | Distance |
|---|---|---|---|
| A hop between two access points over ESP-NOW. A message takes up to 3 hops. | ESP32 dev board, built-in PCB antenna | ~100–200 m estimate, clear line of sight | |
| A handheld's Wi-Fi link to its access point. | Six ESP32 display boards supported; built-in antennas | ~30–60 m estimate, handheld in a pocket | |
| GPS signal to MAIN: time and location. Receive only; optional. | GT-U7 GPS module on MAIN | From orbit needs open sky | |
| GPS signal to a handheld. Receive only; optional. | GPS module on a Freenove handheld | From orbit needs open sky | |
| The LoRa backbone between access points, drawn beneath the mesh, used when the ESP-NOW link cannot reach. Carries messages, alerts and positions; never live talk. | Modules on all three access points, in use (D74) | Kilometres general figure for LoRa, not measured here | |
| A laptop or phone beside the grid, watching its health over Bluetooth. Read-only, and never part of the network. | Built into every ESP32 access point | ~10–30 m typical Bluetooth range |
Distances are estimates for these boards and have not been measured yet. Trees, walls, bodies, and other Wi-Fi on the channel shorten them. A field test will replace them with measured ranges.
Symbols
- Access point (AP). MAIN is the one with the GPS. Up to 8 in a grid.
- Handheld. Up to 32 in a grid.
- Text and push-to-talk. Has a microphone, like the Freenove.
- Text, and listens to talk. No microphone, like the Hosyond.
- GPS on a handheld (optional).
- LoRa module on a handheld — two of them carry one alongside a GPS. Fitted; the firmware is still to be written, so it is drawn faded.
- An access point on the LoRa backbone. The ring marks the three that carry a module and link to each other over it.
How it works
There are two kinds of device. Access points are small boards with no screen that you place around the area and power; they carry the messages. Handhelds are the touchscreen devices people carry.
- Place and power the access points. Up to eight, in any order. They share one network name, find each other by radio, and link up on their own. Nothing to set up after the first time.
- Handhelds connect to a nearby access point. Each picks one with a good signal, the load spreads across access points, and a handheld switches as you walk. Up to 32 handhelds.
- Messages hop between access points. Private, group, and everyone messages hop from access point to access point until they reach the right people, and the sender sees when they arrive.
- Set it up from any phone or laptop. Join the network's Wi-Fi and open
http://192.168.4.1/to name the network, add people and groups, and set the time.
Designed to keep working
If an access point fails, only the area it covered loses signal; the rest of the network carries on. When a device restarts, it gets back what it knew from the devices that stayed on.
Every device has fixed limits built in, so a busy network slows down instead of crashing. Every design choice is written down, with the reasoning, in the project's documents.
What is ESP-NOW?
ESP-NOW is a radio protocol built into every ESP32 by Espressif, the chip's maker. It sends short packets straight from one board's Wi-Fi radio to another's. There is no router, no joining a network, and no Internet involved. LocalGrid's access points use it to talk to each other.
- Say hello. When an access point starts, it broadcasts a hello on the network's channel: five times, 200 ms apart, then every 2 seconds.
- Become neighbours. Every access point that hears the hello adds the sender as a neighbour. No pairing, no setup, and power-on order does not matter.
- Pass messages on. A message goes to each neighbour, which passes it on to theirs. Each access point ignores copies it has already seen, and a message stops after 3 hops, so nothing circulates forever.
- Work around a lost access point. A neighbour that misses three hellos (6 seconds) is dropped, and messages keep flowing through the access points that are left.
One radio, one channel
Each access point runs ESP-NOW and the Wi-Fi network the handhelds join at the same time, on one radio and one fixed channel. Handhelds use Wi-Fi to reach their access point; access points use ESP-NOW to reach each other.
Slow on purpose, for range
Access points talk at 1 Mbps, the slowest Wi-Fi rate, because slower signals reach farther. That is still plenty: one packet holds up to 1,470 bytes, enough for a whole message or a slice of voice.
Encrypted by LocalGrid
ESP-NOW's built-in encryption cannot protect messages sent to everyone at once, and it uses up connection slots the Wi-Fi side needs. So LocalGrid encrypts every message between access points itself, with a key only that network's devices hold.
What it does today
Everything below runs on the test boards. It is a prototype: expect rough edges, and read the status section before you rely on it.
Private messages stay private
A private message is encrypted on the sender's handheld and only decrypted on the recipient's. Access points carry it without being able to read it. Group and everyone messages are encrypted over the air too.
Emergencies get through
An urgent message appears on every screen, even a locked one, and the sender sees who has read it.
Push-to-talk
Hold a person or a group to talk, like a walkie-talkie. Voice is encrypted like text and levels itself so quiet and loud voices come through evenly. The Freenove handheld has a microphone and can talk; the Hosyond has none, so it listens.
Recovers after a restart
What one device knows that others need, such as who is on the network and which groups exist, is copied to its neighbours. A device that restarts gets it back from them, and the newest version always wins.
Its own clock, and GPS
The network keeps its own time. It survives a restart that keeps power, and handhelds bring it back to access points that lost it. A GPS module on MAIN sets the time from satellites and shows where MAIN is, with map links, on its admin page. A handheld can carry its own GPS too, and then it backs up the time as well.
Everyone on a map
A handheld with a GPS shares its position with the network, so the admin page can show where people are and a handheld can show how far it is from the main access point. Positions are held in memory only, never written to storage, and a handheld without a GPS simply does not appear.
Watch the network without joining it
Every access point broadcasts a sealed Bluetooth status. A laptop or phone nearby can show the health of each access point, who is online, batteries, and any alert, without joining the network. It only listens: no message text, no voice, and it never takes part.
A simple touchscreen interface
Handhelds have their own lightweight interface with a phone-style keypad. It adapts to the screen it runs on, so supporting a new display board is mostly a matter of describing its pins and screen.
Being built: LoRa
LoRa is a low-power, long-range radio that works below the Wi-Fi band. It reaches kilometres instead of a couple of hundred metres, but carries far less data. ESP32 chips have no LoRa radio, so it would mean adding a small LoRa module to a board. The modules are now fitted to the access points and the firmware for them is being written, so none of this runs yet.
| Wi-Fi and ESP-NOW (today) | LoRa (being built) | |
|---|---|---|
| Range | ~100–200 m between access points, ~30–60 m to a handheld (estimates) | Kilometres with a clear line of sight; less through trees and hills |
| Speed | 1 Mbps between access points | Roughly 0.3 to 20 kbps, depending on settings; slower goes farther |
| Text and emergencies | Yes | Yes, in seconds rather than instantly |
| Push-to-talk voice | Yes | No: voice needs more data than LoRa carries |
| Hardware | Built into every ESP32 | An extra LoRa module per device, and local radio rules on channel and airtime |
Access points first
Access points too far apart for ESP-NOW will still reach each other, so two groups of access points, say at two sites a few kilometres apart, become one network. The LoRa link carries messages, alerts, who is around, positions and the time, but never live talk. A module is optional: an access point without one behaves exactly as it does today.
Handhelds later
A handheld with a module would not go silent when it walks out of Wi-Fi range: it could still send and receive messages and emergencies from much farther away, with talk returning once it is back in range. This comes after the access points, and stays optional, since each handheld needs the extra module.
What stays the same
Wi-Fi and ESP-NOW stay the main links, because they are fast enough for live talk. LoRa is the long-distance path for short, important messages. The aim is for encryption, groups, and emergencies to work the same way over either.
If you have LoRa experience or LoRa boards, we would like to hear from you.
Hardware
Common, inexpensive ESP32 boards. Adding a new display board mostly means describing its pins, screen, and touch controller in one file, which makes it one of the best first contributions.
| Board | Chip | Role | Details |
|---|---|---|---|
| Elegoo ESP32 dev board | ESP32 | Access point | CP2102, 4 MB flash, no PSRAM |
| Hosyond 3.2in ESP32 display | ESP32 | Handheld | ST7789P3 240x320, resistive touch, CH340, 4 MB flash |
| Freenove FNK0104B 2.8in ESP32-S3 display | ESP32-S3 | Handheld | ILI9341, FT6336U touch, 16 MB flash, 8 MB PSRAM |
| LCDWIKI E32R28T-1 2.8in ESP32-32E display | ESP32 | Handheld | ILI9341 240x320, XPT2046 touch on its own pins, DAC speaker, one USB-C, 4 MB flash |
| ESP32-2432S028 2.8in 'CYD', dual-USB variant with the inverting panel | ESP32 | Handheld | ILI9341 240x320, XPT2046 touch on its own pins, DAC speaker, no battery, 4 MB flash |
| LCDWIKI E32R40T 4.0in ESP32-32E display | ESP32 | Handheld | ST7796 320x480, XPT2046 touch on the display bus, DAC speaker, one USB-C, 4 MB flash |
| Waveshare ESP32-C6-LCD-1.47 | ESP32C6 | Handheld | ESP32-C6, ST7789 172x320, no touch, BOOT button, WS2812 LED, TF slot, native USB-Serial/JTAG, 4 or 8 MB flash, no PSRAM). Alert and distress unit (D66). |
| Waveshare ESP32-C6-Touch-LCD-1.47 | ESP32C6 | Bench | ESP32-C6FH8, JD9853 172x320, AXS5106L capacitive touch, QMI8658 IMU, battery sense on GPIO0, BOOT button, native USB-Serial/JTAG, 8 MB flash, no PSRAM). Alert and distress unit (D66). |
| GPS module, GT-U7 (u-blox 7 class, NMEA at 9600 baud), optional | UART | On MAIN | Gives the grid its time from satellites, and shows MAIN's location on its admin page as coordinates and map links. Receive only; the grid works the same without one. |
Status
The prototype is built in milestones. Each has a written report with how to build it, what a working board prints, a test procedure, and known limitations. Every test runs on real ESP32 boards.
- P1Messaging corePassed on hardware, 2026-09-15
- P2Node firmwarePassed on hardware, 2026-09-15
- P3Admin web pageSetup verified on hardware, 2026-09-15
- P5Handheld joins the gridVerified on the bench from serial captures
- P6Chat on the handheldsMessaging verified on hardware over the console; screens built and flashed, on-screen checks by the owner pending
- P7Aps as one mesh networkBuilt with zero warnings; MAIN verified alone on hardware
Recently
- Changed the diagram: a LoRa backbone that looks like one, and nothing sitting on anything
- Added two handhelds now carry LoRa as well as a GPS
- Fixed the diagram showed a LoRa antenna on MAIN but no LoRa link to it
- Changed the README and the site tell the truth, and show the network
- Added the chaos engineering write-up, with the run behind it
- Added D76: public, under GPL-3.0-or-later, with the README, site and CI in the tree
Tested by breaking it
The network's core claim is that it heals itself, so it is tested by attacking it: a framework randomly kills access points and handhelds, cuts their power and switches their radios off, for hours at a time, unattended, while the handhelds keep messaging each other. In a ten-hour run: 55 faults injected, 55 recovered, the backbone whole again in a median of 3.7 s. It found three bugs that code review and unit tests could not. How it was chaos tested →
Still to do
Two handhelds now carry a LoRa module alongside a GPS, but the handheld LoRa firmware is still to be written. Purpose-built handhelds are still being designed, and the access points have no cases yet. Every test so far has run on one workbench, with every board in radio range and on a cable: chaos testing in the field, on batteries and with no wires, is planned, and the ranges quoted above are estimates rather than measurements. If you have LoRa experience or boards, we would like to hear from you.
Build it with us
LocalGrid is written in the open, decisions and all. These are the places a contributor helps most.
Port a board
Describe a board's pins, screen, and touch controller in one file. If you have an ESP32 display board that is not listed, you can probably bring it up.
Test on real radios
Measure range, handover as you walk, and recovery on your hardware and in your space. A test tool switches access points off at random for hours and reports how the network recovers.
Improve the admin page
The web page every access point serves for setup. Try it here against a simulated network, no hardware needed.
Review the messaging and encryption
The code that carries and encrypts messages is plain C, checked against published test values. Careful reviewers are welcome.
Licence. Released under the GNU GPL v3 or later (GPL-3.0-or-later). Third-party material keeps its own licence; see THIRD_PARTY.md.