▶ Watch the presentation video
ESP-PPB is the first distributed, phase‑coherent Wi‑Fi CSI platform. It is also fully open-source, wireless, and battery-powered !
CSI (Channel State Information) captures how a Wi-Fi signal travels between transmitter and receiver : amplitude and phase on every subcarrier. With phase-coherent CSI across multiple nodes you can do angle-of-arrival estimation, indoor localization, and distributed wireless sensing.
Each ESP-PPB node synchronizes its clock over the air using Wi-Fi FTM and a VCTCXO disciplined by dual DACs, achieving sub-PPB clock alignment and phase-coherent CSI captures.
Drop nodes wherever you need them, power them on, and collect synchronized CSI data on your laptop over Wi-Fi, no cables, no wired backhaul, no tethered power.
Looking for hardware? A Crowd Supply application is planned. See the Get Hardware section to join the interest list.
Existing Wi-Fi CSI platforms either require cables between antennas, need a wired connection to a PC, or cannot synchronize phase across devices. ESP-PPB removes all three constraints:
| ESP-PPB | ESPARGOS | Intel 5300 CSI Tool | Atheros CSI Tool | |
|---|---|---|---|---|
| Wireless (no cables between nodes) | Yes | No (coax + Ethernet) | No (PCIe in PC) | Partial (OpenWRT routers) |
| Remote data collection | Yes (battery powered +Wi-Fi) | No (Ethernet) | No (local) | Partial (router) |
| Max synced nodes | Unlimited | ~4 arrays documented | N/A | N/A |
| Antennas per node | 1 | 8 (2x4 array) | 3 (3x3 MIMO) | Up to 3 (3x3 MIMO) |
| Open source firmware | Yes | Yes | No (closed binary) | Yes |
| Actively maintained | Yes | Yes | No (discontinued ~2011) | Limited |
| Cost per node | ~$50-80 | Not available | Discontinued | ~$90-145 (router) |
In short: ESP-PPB is the only solution that is simultaneously wireless, battery-powered, phase-synchronized, and remotely observable, with no upper limit on the number of synced nodes.
- Angle-of-arrival estimation: place nodes around a room, triangulate sources
- MUSIC / ESPRIT: super-resolution direction-finding algorithms
- Multi-node phase-coherent CSI capture: build a distributed virtual array
- Distributed wireless sensing: synchronized, cable-free, battery-powered nodes
- Indoor localization: deploy and relocate freely without cable constraints
- Phase-coherent WiFi sensing: see also ESPARGOS, a wired ESP32-based CSI array
Wireless phase-coherent CSI is largely uncharted territory. Most existing research assumes wired synchronization. If you're looking for a paper topic, this is it.
ESP-PPB is working end-to-end: synchronization is stable at the PPB level, multi-node phase-coherent CSI capture works, and angle-of-arrival testing is functional. Below is an example/demo captured with ESP-PPB boards sitting on a desk in a normal room, no shielding, no lab equipment. This is the kind of data you get out of the box.
Angle-of-arrival matrices across scenarios. Each heatmap shows the pairwise CSI phase difference between four ESP-PPB nodes (TOP, BOTTOM, RIGHT, LEFT) for a different physical setup: reference (no obstruction), paper placed behind/below/between nodes, and a hand in the middle. The phase pattern changes visibly with each scenario, showing that the nodes can detect the presence and position of objects.
CSI phase per subcarrier across four synchronized nodes. The top plot shows the raw phase angle for each node across all 52 OFDM subcarriers. The bottom plot shows the phase difference relative to the TOP node, demonstrating stable, flat phase offsets between nodes, which is the foundation for angle-of-arrival estimation.
┌──────────┐ ┌──────────┐
│ Slave 1 │ ◄──────────────────►│ │
│ (VCTCXO) │─────┐ FTM │ │
└──────────┘ │ │ Master │
│ │ │
│ │ (AP) │
┌──────────┐◄───────────────────►│ │
│ │ | FTM └──────────┘
│ Slave 2 │─────┤
│ (VCTCXO) │ │
└──────────┘ │
│ CSI data (Wi-Fi broadcast)
...more...─────┤
│
┌────▼─────┐
│ Listener │ ← any ESP32 + PC
│ (PC) │
└──────────┘
- One node acts as the AP / FTM responder (the master clock).
- Slave nodes initiate FTM exchanges every few hundred milliseconds (configurable).
- A small IDF hack enables nanosecond-level RX timestamps via promiscuous mode.
- Each slave estimates its clock drift VS master (PPB slope) and corrects its VCTCXO via dual DACs (coarse + fine).
- Everytime an (external) CSI frame is seen, AP send a reference frame 1ms later.
- Slave records both external and reference CSI and broadcast results over Wi-Fi
- Any listener (a cheap ESP32 connected to a PC) collects the data for post-processing.
| Metric | Best case (lab) | Typical (real world) |
|---|---|---|
| Clock alignment | < 0.1 PPB | ~1 PPB |
| Single-frame phase accuracy | < 1 degree | < 10 degrees |
| Time to 10 PPB lock | Instant | Seconds |
| Time to < 1 PPB lock | Seconds | Minutes (needs thermal stability) |
- Compact: under 4 cm x 4 cm, 5+ PCB revisions refined
- ESP32-C3 with custom RF antenna tuning (2.4 GHz)
- VCTCXO 0.5ppm voltage-controlled temperature-compensated crystal oscillator
- Dual DAC: 2x12 bits DAC (coarse + fine) control for oscillator discipline
- OLED display: live accuracy and status readout
- LiPo battery charger 8 h runtime with a 1000 mAh battery (120 mA draw, battery not included),
- 6 exposed GPIOs: connect your own sensors, actuators, or peripherals (see Exposed IO)
Full schematics, PCB layout, and 3D board model are in schematics/.
Production files (BOM, Gerbers, pick-and-place, schematic PDF, and source archives) are in
schematics/production/.
Limitations: each node has a single antenna, so spatial diversity requires multiple nodes. The ESP32-C3FH4 is not FCC/CE certified — this product is intended for laboratory and research use.
Minimum setup: 1 master (AP) + 2 slaves = 3 nodes.
Typical setup: 1 master + 4 slaves, with a listener ESP32 connected to a laptop.
Nodes auto-detect their role based on MAC address (configurable in firmware). Power them on and they synchronize automatically.
Get the CSI (external + reference) from the the serial of the laptop connected ESP32 and start processing !
Want to flash and run? See
BUILD_IT_YOURSELF.mdfor the full setup guide.
Join the interest list for updates. Email jonathan.muller12@gmail.com with subject ESP-PPB interest and include your country, intended use, and quantity.
You can also open a discussion.
The design files are in schematics/ if you want to build your own, but I recommend ordering assembled boards unless you are experienced with RF PCB design and antenna tuning.
This project thrives on early feedback. Whether you're a researcher, engineer, or hobbyist, your input shapes the next revision.
| # | How to contribute |
|---|---|
| 1 | Try it: request a board and test in your environment |
| 2 | Report: share results, bugs, or calibration observations |
| 3 | Suggest: propose new use cases or features |
| 4 | Collaborate: co-author research, co-develop algorithms |
Open a discussion or email jonathan.muller12@gmail.com.
Do I need a special access point?
An ESP-PPB node as AP gives the best results (built-in FTM sync). A regular Wi-Fi router also works, but you'll need an external ESP32 (doesn't have to be ESP-PPB) to send a sync frame alongside each CSI frame.
What's required to collect data?
Any Wi-Fi listener can receive the broadcast data. A reference ESP32 logger connected to a PC is provided for convenience.
How many nodes can I synchronize?
There is no hard limit. The system has been tested with more than 5 nodes. Add as many slaves as you need.
What ESP-IDF version do I need?
ESP-IDF v5.x works. v6.0 is also supported.
- First prototype
- Prototype validation
- Multi-revision PCB refinement (5+ revisions)
- Sub-PPB synchronization demonstrated
- Multi-node deployment tested (5+ nodes)
- Open source firmware release
- Early production ← you are here
- Crowd Supply campaign
- Python post-processing examples (AoA, MUSIC)
- Extended documentation and tutorials
Details
Each node selects its role at boot based on its MAC address (main/main.c). The role determines which callbacks and loop function are registered.
| Role | MAC match | Wi-Fi mode | Description |
|---|---|---|---|
| Slave (FTM) | LEFT, RIGHT, TOP, BOTTOM |
Station | Syncs to master via FTM, captures and broadcasts CSI |
| Master (AP) | MIDDLE |
Access Point | Runs FTM responder, responds to CSI pings |
| Default client | Any other MAC | Station | Receives and logs broadcast data from slaves (listener / PC bridge) |
| Function | Registered as | Role | Trigger | What it does |
|---|---|---|---|---|
promi_ftm_cb |
Promiscuous RX callback | Slave | Every received management frame | Extracts nanosecond RX timestamps from FTM frames for clock drift estimation |
csi_send_summary |
CSI RX callback | Slave | Every CSI frame received | Packages CSI + timing data and broadcasts it over Wi-Fi |
infinite_ftm |
Main loop | Slave | Runs continuously | Initiates FTM exchanges with the AP, estimates PPB drift, corrects VCTCXO via dual DACs |
csi_ping_pong |
CSI RX callback | Master | CSI frame from a slave | Immediately responds with a CSI frame back (anchors phase for the slave) |
print_now_recv |
ESP-NOW RX callback | Default | ESP-NOW packet received | Logs received data (used by the listener / PC bridge) |
simple_send_cb |
ESP-NOW TX callback | Default | After sending an ESP-NOW packet | Logs TX rate for debugging |
infinite_send |
Main loop | Default | Runs continuously | Sends ESP-NOW packets in a loop (test / relay mode) |
1. Print MAC address
2. Init GPIO9 interrupt (button)
3. Init I2C → OLED → DACs (reset VCTCXO)
4. Detect role from MAC address
5. Init Wi-Fi (AP or Station)
6. Register callbacks (promiscuous, CSI, ESP-NOW)
7. Enter main loop (if any)
| File | Purpose |
|---|---|
main/main.c |
Entry point and role selection |
main/helper_init.c |
Wi-Fi init, CSI, promiscuous mode |
main/perf.c |
FTM table, PPB slope, DAC correction |
main/i2c_helper.c |
OLED + DAC + I2C utilities |
main/constant.h |
Channel, SSID, and protocol constants |
hack_struct.patch |
IDF patch for nanosecond RX timestamps |
Details
| Component | License |
|---|---|
| Firmware / software | GPL-3.0 |
| Hardware design files | CERN-OHL-S-2.0 |
Details
If you use ESP-PPB in academic work, please cite:
@misc{muller2025espppb,
author = {Jonathan Muller},
title = {{ESP-PPB}: Wireless Battery-Powered Phase-Coherent {CSI} Synchronization Platform},
year = {2025},
howpublished = {\url{https://github.com/jonathanmuller/esp-ppb}},
}