Reference architecture

The runtime runs inside your ESP-IDF product. Your firmware runs the product; ESPectre runs the sensing.

Who does what

YOUR FIRMWARE

Product lifecycle

Boot, Wi-Fi setup and connection, storage, updates, logging, UI, and what happens when motion changes.

ESPECTRE

Sensing lifecycle

CSI capture and filtering, calibration, detection, readiness, state snapshots, diagnostics, and events.

BOUNDARY

One controller and one listener

RuntimeFrontendController takes configuration and commands. IRuntimeListener receives state changes and errors.

Lifecycle and tasks

Create stationinterface + event loop
setup(listener)prepare CSI capture
Join Wi-Fiproduct connects
loop()deliver events
shutdown()release runtime

Create the default Wi-Fi station and event loop first. If you can, call setup() before connecting to Wi-Fi, so the runtime can configure the radio for CSI when the station starts. Call setup(), loop(), the controls, and shutdown() from one task. Listener callbacks run on that same task and must return quickly; hand network publishing, flash writes, and other blocking work to another task.

If setup() fails, nothing is configured, so you can fix the configuration and retry. Controls return false when a value is invalid, a feature is unavailable, or the change is refused. Errors that happen later arrive through on_runtime_fault().

Three-layer architecture

Dependencies go one way: frontend → runtime → core. A product usually replaces the frontend and reuses the other two layers.

Frontend src/cpp/frontend/
Connects sensing to the product: behavior, protocols, logging, and ecosystems. ESPHome, Native, and Matter are examples to learn from, not a supported library.
Runtime src/cpp/runtime/
Lifecycle, calibration, state snapshots, events, diagnostics, capabilities, and controls. The ESP-IDF code lives in runtime/esp_idf/.
Core src/cpp/core/
CSI format, filtering, features, and the Lightweight and High Accuracy detectors. Portable C++17 or later, with no ESP-IDF dependency.

Runtime data flow

Wi-Fi trafficproduct environment
CSI captureruntime/esp_idf
Featurescore
Detectioncore
Product eventfrontend
Optional services have their own headers. Include espectre_protocol_sdk.h to speak the ESPectre Protocol over your own transport, espectre_services_sdk.h for commands, Direct HTTP, discovery, provisioning, and startup helpers, and espectre_mqtt_sdk.h for MQTT. Enable the source groups your firmware needs, or plug in your own services through the same interfaces.

The SDK's provisioning service stores Wi-Fi credentials; your firmware chooses how the user enters them. The Improv Serial and update code used by the reference firmware is not part of the SDK.

Logging works the same way. Core and runtime write to a log sink. Before setup, the frontend can connect it to ESPHome, esp_log, or anything else. Without a sink, the SDK logs nothing.
Extending the source tree or porting another platform

Where new code belongs

If the code…Put it in…
Changes CSI processing or detector behaviorcore/, with matching Python behavior
Defines shared lifecycle, events, snapshots, or transport rulesruntime/
Calls ESP-IDF, FreeRTOS, Wi-Fi, NVS, or lwIPruntime/esp_idf/
Connects sensing to a protocol, ecosystem, or product UIfrontend/

Building a runtime for another platform

A port builds on the shared core: it feeds CSI in the expected format, keeps the same timing and readiness behavior, and sends IRuntimeListener events from its own task. The runtime behind RuntimeFrontendController is internal to ESP-IDF, so a new platform brings its own runtime and controller.

Arduino on ESP32Possible as a new adapter on Arduino-ESP32, which gives access to ESP-IDF's CSI, if the build supports C++17. There is no Arduino runtime today.
Raspberry Pi / LinuxNeeds a Wi-Fi chip, firmware, and driver that provide usable CSI. Ordinary Linux Wi-Fi is not enough.
The architecture guide has the full rules and the reasons behind them, and the decision records explain each design choice.