Flash and set up your device
Take a blank ESP32 board to a working motion sensor through either published browser images or a local CLI build. Both paths meet at the same provisioning, verification, and monitoring steps.
What you need
- A compatible Espressif board listed in the hardware guide.
- A USB cable that carries data, not only power. If in doubt, try another cable first; charge-only cables are a common setup problem.
- For the browser path, Chrome or Edge on desktop. Browser flashing uses Web Serial, which Firefox and Safari do not support.
- For the CLI path, Python 3. Docker is optional; without it, install ESP-IDF 5.5 or newer locally. When Docker is available, the CLI automatically downloads and uses the pinned build image containing the correct ESP-IDF version.
Step 1 — Choose your firmware
Pick the row that matches how you want to use the sensor. You can reflash later if your needs change.
| If you... | Flash | You get |
|---|---|---|
| Want a standalone sensor, browser tools, MQTT, or Home Assistant through an existing broker | Native | Improv Serial setup, broker-free Direct monitoring, optional MQTT, Home Assistant MQTT Discovery, and browser games |
| Want the most complete Home Assistant integration and YAML configuration | ESPHome | Auto-discovered device with motion, movement level, threshold slider, and recalibrate switch |
| Use a controller that supports Matter occupancy sensors | Matter | A standard occupancy sensor; controller validation is still limited, so check the current validation notes |
| Want raw CSI data for research | Streamer | Raw capture over UDP; not flashable from the browser, see the setup reference |
Step 2 — Build or select an image, then flash
Browser path: install a published image
Plug the board in
Connect the ESP32 to your computer over USB. Close anything that may be using the serial port, such as a previous flasher tab, the Arduino IDE, or a serial monitor.
Open the flasher
Go to the Flash page, keep Latest Release selected unless you want a Release Preview from
mainor a Development image fromdevelop, and choose the firmware from Step 1. The installer detects the chip over USB and selects the matching image.Connect
Click Connect. The browser shows a list of serial ports: pick the one that appears when you plug the board in (on Windows a
COMxport, on macOS/Linux something likeusbserial,usbmodem, orttyACM).Install
Choose Install, confirm, and wait. Flashing takes one to three minutes; do not unplug the cable. When it finishes, the device reboots into ESPectre.
CLI path: build, flash, and monitor
Prepare the repository environment once. Native, Matter, and Streamer prefer a local ESP-IDF installation and can use the pinned Docker build environment when it is absent; flashing still needs local serial tooling. ESPHome manages its own toolchain.
git clone https://github.com/francescopace/espectre.git
cd espectre
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
Choose the frontend from Step 1. The examples target ESP32-C3; replace c3 with c5, c6, s2, s3, or esp32 for another supported board. ESP32-S2 is supported by ESPHome, Native, and Streamer, but not Matter. --clean is optional: add it to a build when configuration or toolchain changes require a clean rebuild of that frontend and chip. Flashing resets the board and starts the application, so no frontend needs a separate run command. Flash, QR, and serial-monitor commands select the only connected device automatically or present a selection menu when several devices are available.
Native uses the shared ESP-IDF build environment. Flashing starts the application; the top-level monitor follows its serial output:
./espectre native build --chip c3 --clean
./espectre native flash
./espectre monitor --reset
ESPHome selects the maintained YAML for the target chip and manages its own build toolchain. Use the same chip when building, flashing, and monitoring:
./espectre esphome build --chip c3 --clean
./espectre esphome flash --chip c3
./espectre esphome monitor --chip c3
Flash and monitor discover the target automatically. With one available device they use it directly; with several serial or network devices, the CLI presents a selection menu.
For a specific local YAML, add the same --config path/to/espectre.yaml option to all three commands and keep its credentials in an ignored secrets.yaml. Use --dev instead of --config to select the maintained development YAML for that chip and load the component from the local checkout:
./espectre esphome build --chip c3 --config path/to/espectre.yaml --clean
./espectre esphome flash --chip c3 --config path/to/espectre.yaml
./espectre esphome monitor --chip c3 --config path/to/espectre.yaml
Matter uses the shared ESP-IDF build environment. After flashing, retrieve the device-specific onboarding code and use the serial monitor while commissioning:
./espectre matter build --chip c3 --clean
./espectre matter flash
./espectre matter qr
./espectre monitor --reset
Streamer has no browser image or interactive provisioning. Save local Wi-Fi values in the ignored src/cpp/frontend/streamer/app/sdkconfig.wifi before building:
CONFIG_ESPECTRE_WIFI_SSID="YourSSID"
CONFIG_ESPECTRE_WIFI_PASSWORD="YourPassword"
CONFIG_ESPECTRE_WIFI_CHANNEL=0
CONFIG_ESPECTRE_WIFI_BAND_2G=y
Then build, flash, and monitor the device:
./espectre streamer build --chip c3 --clean
./espectre streamer flash
./espectre monitor --reset
Collect on your computer
Run ./espectre devices --frontend streamer to list advertised Streamer targets without starting a capture. ./espectre collect uses the same host-side mDNS discovery, selects the only device automatically, or presents a menu when it finds several. The collector receives the raw CSI stream over UDP; when you save a capture, it creates the dataset files on your computer rather than transferring files from the ESP32.
./espectre devices --frontend streamer
./espectre collect
Run ./espectre devices to inspect ESPectre endpoints advertised on the local network. The command recognizes Native, Streamer, first-party ESPHome, and Matter devices whose commissioning window is open; use --frontend when you need only one firmware type.
On Windows, use espectre.cmd instead of ./espectre; the setup reference and CLI reference cover complete prerequisites, explicit device overrides, --clean-all, and backend options.
Step 3 — Connect it to your network
Select the firmware you flashed and follow only that setup path.
Provision Wi-Fi over USB
After flashing, complete the standard Improv Serial prompt in Chrome or Edge. If the handoff cannot open the device automatically, keep the returned URL.
Open Direct Configure
Go to Configure and enter the device IP or its
espectre-<device_id>.localhostname. From a repository checkout,./espectre devices --frontend nativelists Native endpoints advertised on the same mDNS-visible network; use the router lease table when multicast discovery is unavailable. Direct WebSocket can set an optional BSSID pin, edit the device label, and add or clear MQTT without returning stored passwords. A failed Wi-Fi change rolls back to the last-known-good network. Hold BOOT for 3 seconds when USB recovery is needed.Start sensing
Open Monitor, keep Direct WebSocket selected, connect to the same endpoint, and start sensing without a broker. Choose MQTT only when you need Home Assistant, automation, a remote broker, or multiple devices. MQTT Monitor requires a browser-compatible WebSocket listener.
Tune from the MQTT shell
Run the shell on your computer with the broker address. It selects a single device automatically or presents a menu when several devices are online. Use help to see the available commands, then adjust the motion threshold or start a new calibration:
./espectre mqtt --broker 192.168.1.20
espectre> help
espectre> set_threshold 0.35
espectre> recalibrate
For a reproducible integrator image, Native also supports build-time Wi-Fi and MQTT defaults through its ESP-IDF Kconfig surface. Keep generated sdkconfig files and credentials local; the Native reference owns those options.
Configure Wi-Fi in the flasher
Right after installation, the same dialog offers Configure Wi-Fi. Enter your network name and password. Published images use 2.4 GHz. On ESP32-C5 this dialog is not available yet: connect to the
ESPectre Fallbackhotspot the device creates and enter the credentials there.Add it in Home Assistant
Within a minute, Home Assistant shows a notification for a discovered ESPHome device. Accept it, and you get the motion sensor, movement score, threshold control, and recalibrate switch. The Home Assistant dashboard guide turns those entities into a focused sensing and diagnostics view.
CLI path: use --dev to embed the Wi-Fi credentials from secrets.yaml directly in the firmware.
Get the QR code
After flashing, use Read the onboarding QR over USB on the Flash page, or run
./espectre matter qr. Each device has its own code, and reflashing does not change it, so you can save it.Add the device in your app
In a controller that supports Matter occupancy sensors, choose its add-device flow and scan the QR code. The exact UI varies by controller. Keep the phone near the board: commissioning starts over Bluetooth, then the device joins your Wi-Fi.
Place it in a room
The device appears as an occupancy sensor. Use it in automations exactly like any other motion sensor.
CLI path only: the Streamer tab in Step 2 covers its local Wi-Fi configuration, device build, flash, and serial monitor, followed by the separate collector process on your computer. Streamer does not expose motion entities by itself; it sends raw CSI to the host-side collector over UDP.
Step 4 — Let it calibrate, then test
- Published firmware defaults to Lightweight Detection. After joining Wi-Fi, it calibrates its quiet threshold for up to about ten seconds: keep the room still, then move normally. High-Accuracy Detection skips this threshold calibration.
- Wave an arm a few meters from the board: the motion state should turn active within about a second and clear shortly after you stop.
Troubleshooting
No serial port appears
- Try another USB cable; charge-only cables are a common cause.
- Try another USB port, ideally directly on the computer.
- Hold BOOT while plugging in, then retry Connect.
Flashing starts but fails midway
- Close other tabs or programs using the port and retry.
- Use a rear USB port or a powered hub: unstable power interrupts flashing.
- Retry with Erase enabled to start from a clean flash.
The installer says the board is not supported
- The connected chip has no published image for the selected firmware and channel.
- The Flash page lists the chips that currently have firmware.
- ESP32-S2 is available for ESPHome and Native, but not Matter; other variants outside the listed matrix cannot be flashed from the browser.
Device will not join Wi-Fi
- Confirm that the selected band is available. Configure exposes 5 GHz and automatic selection only on capable ESP32-C5 devices, and a band change requires a restart.
- Re-enter the exact SSID and password: both are case-sensitive.
- Move the board closer to the access point for the first join.
Native Direct cannot find a previously configured device
- Try its stable
espectre-<device_id>.localhostname, then check the router lease table for its current address. - Forget the stale endpoint in Configure or Monitor before entering the current IP address or hostname.
- Grant local-network access only to the ESPectre portal in a supported browser; an Origin or mixed-content error means that browser path is not available.
Native recovery or rollback is required
- Hold BOOT for 3 seconds to clear saved Wi-Fi, then repeat Improv Serial provisioning over USB.
- Reflash the full factory image when OTA cannot complete; this path does not require MQTT or the original browser profile.
- Use an older factory image only when that release's migration notes explicitly allow the downgrade, and erase flash when its persisted configuration is incompatible.
Matter commissioning times out
- Keep the phone within a meter of the board while pairing.
- Make sure the phone's Bluetooth is on and the board is powered.
- Power-cycle the board to reopen the commissioning window, then retry.