WORK IN PROGRESS: MANY FEATURES MAY BE BROKEN โ proof of concept, v0.2.2-wip
Turn a tiny radar chip and an old phone into a people-spotting radar ๐ก
Ever wanted to know who is walking about, and how far away they are, without a camera? Blip does it with a tiny radar chip and a spare phone. The chip sends out invisible radio waves and listens for the echoes. When someone moves, the echo changes, and Blip works out where they are.
The phone is the screen. Blip makes its own Wi-Fi network; you join it, open a web page, and a glowing green radar scope appears, like something from a submarine film. Up to three people show up as dots with their distance, direction and speed. No app to install, no internet needed, no cloud, no camera.
How it works, in three steps
- Plug a little ESP32 board into a radar chip (the Ai-Thinker RD-03D) and power it from USB.
- Join the Wi-Fi network called Blip-Radar on any old phone, tablet or laptop.
- Open the page and watch the dots move. Walk about and see yourself on the scope!
Good things to know
- It only sees things that move. Someone sitting very still fades from the scope.
- It also bounces off big metal things such as fridges, so a small room can look busy.
- A tiny optional screen (an OLED) can sit on the board and show the same picture. Blip finds it by itself when it starts.
- You can switch between tracking the one nearest person or up to three.
It is a slimmed-down take on Stevee87's Arduino-ESP32-Radarproject, which pairs the same radar with a XIAO ESP32-S3 and an Arduino GIGA R1 + display shield. The drawing is the easy part; a phone already does it.
Required Notice: Copyright Matthew Armstrong (https://github.com/The-Dorkknight).
Licensed under the PolyForm Noncommercial License 1.0.0 โ source-available, free for non-commercial use. Provided as-is with no warranty and no liability. Not a medical device. Radar can see motion through thin walls: respect other people's privacy and the 24 GHz rules where you live.
Project started 2026-11-05 10:24.
๐ The whole manual and research notes as one PDF: docs/Blip-manual.pdf (also attached to every release).
Phone screenshot from the simulator (tools/sim_radar.py).
Bonus experiment: the Stetho add-on (parked)
The idea: use a second, very cheap radar-style module (a ยฃ3 CDM324 or HB100 Doppler sensor) as a stethoscope that listens to a heartbeat from a distance. A modded MAX4466 microphone board boosts the signal, and the ESP32 cleans up the sound (ducks knocks, lifts heart, lung and throat sounds, cuts hiss) and plays it live to the phone, to 3.5 mm earphones, or to a small speaker.
Status: abandoned, but kept as an optional install. The radar and phone scope are the project; the stethoscope is parked. The firmware, page and tests are still in the repo and still build, and you can switch it on in Settings, but nobody is working on it. Why, in the author's words: "Needing to build an ultra-low-noise, ultra-high-gain, fast-slew-rate instrumentation amplifier is just too much work for a 'fun' 30-minute project, but I encourage anyone gifted enough with analogue, or mad enough, to carry on my research ๐" Findings and test recordings are in docs/STETHO_SIGNAL_NOTES.md.
Simulator screenshot. The real thing never got past the noise floor.
What exists vs what doesn't
| Part | State |
|---|---|
| RD-03D frame parser (sign bits, resync, ACK tolerance) | Done; unit-tested natively in C++ and Python (tests/) |
| Single/multi-target mode command | Fixed in v0.2.1: now wrapped in enable/end-config like the original project (earlier versions probably did nothing) |
| "Smart" target filter (own track ids, smoothing, hides flickers, wall reflections, fans) | Experimental, opt-in. Native tests on synthetic scenes pass; not tried in a real room |
| Auto-sleep + optional power switches for the RD-03D and the CDM324 | Written, compiles; not tried on hardware |
| Phone web UI: scope, targets table, tracker ping, settings, about | Done; tested in Chromium against the simulator |
| Flasher page the launcher opens (Quick flash of bundled firmware, or build from source; serial output; error tips) | Done; tested end to end with stand-ins for esptool and PlatformIO (tests/test_flasher.py); the bundled images and the esptool command were checked with the real esptool (image_info: valid); not yet used on a real board
|
| Wi-Fi hotspot + captive portal + WebSocket/HTTP API | Running on the author's bench (Nov 2026): the page loads and shows live targets |
| ESP32-C3 Super Mini and Waveshare ESP32-S3-Pico builds | Compile cleanly (pioarduino, Arduino-ESP32 3.3.12); not yet flashed |
| OLED mirror (0.91" 128ร32 / 0.96" 128ร64 SSD1306) | Works on the author's bench; found automatically at boot. The previews below are rendered by the firmware's own drawing code on a PC |
| Stetho audio clean-up on the ESP32 (bump gate, heart/lungs/voice presets, noise suppression, AGC) | Done in fixed point; native test on a synthetic scene passes (knocks โ38 dB vs heart sounds, hiss โ11 dB) |
| Live low-latency audio to the phone, chest-motion trace, heart/breath estimates | Done; tested in Chromium against the simulator (54โ83 ms delay there) |
| Earphone (delta-sigma) and I2S amp outputs on the node | Written, compiles; not heard yet |
| CDM324 + modded MAX4466 front end | Built and tried on a bench (Nov 2026): static fixed by supply caps, but the heartbeat sits at the noise floor even at 2 cm. Abandoned: it needs a custom ultra-low-noise, high-gain instrumentation amplifier (and ideally an I/Q module) |
| Making the RD-03D itself into a Doppler stethoscope | Not possible through its UART โ see DESIGN_NOTES.md |
| RD-03D tracking in a real room | Tracks up to 3 targets, and also big metal objects as you walk towards them; noisy in a small house, outdoor test still to do |
| Enclosure | None yet |
Bill of materials
| Qty | Part | Notes |
|---|---|---|
| 1 | ESP32-C3 Super Mini or Waveshare ESP32-S3-Pico | Either; both envs in firmware/platformio.ini
|
| 1 | Ai-Thinker RD-03D โ or an HLK-LD2450 (see Radar options) | 5 V, โฅ200 mA, UART 256000 baud, 3.3 V logic |
| 1 | Old phone / tablet / laptop with a browser | The display |
| 0โ1 | SSD1306 I2C OLED, 0.91" 128ร32 or 0.96" 128ร64 | Optional second display |
| 0โ1 | CDM324 (24 GHz) or HB100 (10.5 GHz) CW Doppler module | Optional "Stetho"; HB100 if you want to run it alongside the RD-03D (see below) |
| 0โ2 | MAX4466 electret-mic amp board (Adafruit 1063 / GY-MAX4466) | The Stetho amplifier, modded: hardware/max4466-mod.md |
| 0โ1 | 470 ฮฉ, 100 nF, 220 ยตF, 3.5 mm socket | Earphone output, hardware/audio-out.md |
| 0โ1 | MAX98357A I2S amp board + 4โ8 ฮฉ speaker | Speaker output |
| โ | USB-C cable / 5 V supply, wire | The C3's 5V pin can feed the radar for bench tests |
Wiring
| Signal | C3 Super Mini | S3-Pico | Note |
|---|---|---|---|
| Radar TX โ ESP RX | GPIO20 | GPIO12 | UART1, 256000 8N1 |
| Radar RX โ ESP TX | GPIO21 | GPIO11 | only used to send the single/multi-target command |
| OLED SDA / SCL | GPIO6 / GPIO7 | GPIO17 / GPIO18 | I2C 0x3C |
| Stetho: MAX4466 OUT | GPIO1 (ADC1) | GPIO7 (ADC1) | MAX4466 powered from 3V3 |
| Earphones (delta-sigma) | GPIO10 | GPIO16 | via 470 ฮฉ / 100 nF / 220 ยตF |
| I2S amp BCLK / LRC / DIN | GPIO3 / 4 / 5 | GPIO13 / 14 / 15 | MAX98357A |
| Radar 5V / GND | 5V / GND | VBUS / GND | never 3V3 |
Pin numbers live in one place, firmware/platformio.ini; the diagrams are drawn from it.
Stetho front end: CDM324 โ modded MAX4466
โ DC warning. When you desolder the mic capsule and wire the radar's IF pin onto its pads, also remove the mic bias resistor, or put a 10โ47 ยตF DC-blocking cap in series with the IF lead. Otherwise ~1.5 mA of DC from VCC is pushed into the CDM324's mixer diode. Power the MAX4466 from 3V3, never 5 V. Full steps: hardware/max4466-mod.md.
RD-03D + CDM324 at the same time? They share the 24 GHz band. The RD-03D's sweep passes right over the CDM324's frequency, so expect a buzz in the Stetho audio and possibly a noisier RD-03D. Use an HB100 (10.5 GHz) for the Stetho, or fit a 5 V switch on the radar and choose Radar off while listening (
PIN_RADAR_PWR). Details in DESIGN_NOTES.md ยง11.5.
One launcher: flash it, or try it first (double-click)
- Unzip, then double-click
Blip-Linux.sh(choose Run),Blip-Windows.batorBlip-Mac.command(first time on a Mac: right-click โ Open). - Your browser opens the Blip Flasher at
http://127.0.0.1:8080/(the red page). Only Python 3 is needed to open it.- Want to look around before you have hardware? The small Radar simulator โบ button (top right) opens the normal Blip page at
/sim, with three pretend people wandering about and a synthetic Stetho signal; its โก Flasher button brings you back. Start the launcher with--lanto open the simulator from your phone too (the terminal prints the address).
- Want to look around before you have hardware? The small Radar simulator โบ button (top right) opens the normal Blip page at
-
To flash a real board: plug the board in with a USB data cable, pick the board (C3 Super Mini / S3-Pico), the radar (RD-03D / LD2450) and how to flash, pick the port (or leave Auto-detect), press โก Flash firmware.
-
Quick flash (default, recommended): writes the firmware that ships in
firmware/prebuilt/. Nothing is hidden: the page shows the file, version, build date, size and full SHA-256, checks the file againstmanifest.jsonbefore writing, says whether it was built from exactly the source in your folder, and shows the exact esptool command. The first run installs only esptool into.venv(about 40 MB). No Git, no compiler. - Build from source: compiles your folder with PlatformIO so your own changes go in. The first build downloads the ESP32 toolchain (a few GB; needs the internet and Git; 5โ15 minutes), later builds are quick.
- The steps light up as it goes (Quick: Firmware โ Flash tool โ Upload โ Boot; Source: Prepare โ PlatformIO โ Build โ Upload โ Boot) with a progress bar for the upload and the full log underneath (Copy puts it on the clipboard for a bug report).
- If something fails, a tip explains the usual cause: serial-port permission on Linux, the board not in flashing mode (hold BOOT, tap RESET), no board or several boards found, no internet on the first run, Git missing, a port held by another program, your source newer than the bundled firmware.
- Afterwards it shows the board's serial output (no terminal needed). Cancel stops any step.
- Rather use another tool? Any ESP32 flasher can write
firmware/prebuilt/blip-<env>-full.binat address0x0(they are also attached to each GitHub release).
-
Quick flash (default, recommended): writes the firmware that ships in
- Wire the radar as above and power up. The LED on the C3 blinks slowly until frames arrive, then fast.
- On the phone: join Wi-Fi
Blip-Radar, passwordblipblip. The captive portal should open the scope; if not, browse tohttp://192.168.4.1/. It is the same green page as the simulator.
The flasher only answers this computer (127.0.0.1 / localhost): starting a flash needs a per-run token only the page has, and the board, radar and port are checked against fixed lists before anything runs. --no-flash hides it entirely.
Prefer the terminal? cd firmware && pio run -e c3-supermini -t upload (envs: c3-supermini, s3-pico, c3-supermini-ld2450, s3-pico-ld2450). After editing web/index.html run python3 tools/embed_web.py (the Flash tab does this for you).
Using it
| Screen | What it does |
|---|---|
![]() |
Scope โ ยฑ60ยฐ sector, rings every 2 m to 8 m, one coloured blip per tracked person with distance and radial speed. Trails fade over 4 s. Tracker ping is the original project's buzzer, done in the phone's speaker: faster and higher as the nearest person approaches. Mirror L/R flips the picture if you mount the radar the other way round. With the Smart filter on, Show filtered draws what it is hiding as dashed rings (ghost / clutter). |
![]() |
Targets โ the numbers behind the blips plus the raw JSON, handy when checking orientation. |
![]() |
Stetho โ the optional CW Doppler channel. Presets: Heart (S1/S2 heart sounds, 20โ150 Hz), Lungs (breath hiss), Voice (throat/larynx buzz), Wide, Raw (plain Doppler warble). Listen on phone plays it live; Delay shows how far behind real time you are. Knocks are ducked and limited (red in the trace). Beat lock quietens the gaps between beats once a rhythm is found; Record 10 s โ WAV saves a recording for tools/analyze_wav.py; Experiments has ADC averaging and the burst blanker (see docs/STETHO_SIGNAL_NOTES.md). Not a medical device.
|
![]() |
Chest motion view โ the 100 Hz motion trace with heart-rate and breathing rates from the pattern trackers (a ? means only roughly steady); Beat thumps adds a synthetic thump on each detected beat. |
![]() |
Clean-up on the node โ noise suppression, bump rejection, AGC or manual gain; Sound out of the node โ earphones or I2S amp, with its own volume. |
![]() |
Settings โ single/multi target mode (also on the Radar page as Track 1 / Track 3), Target filter (Raw / Smart, experimental) with Forget learned clutter, Auto-sleep, OLED (Auto-detect, or a fixed size), Stetho on/off, radar-off-while-listening, hotspot name and password (reboots). |
![]() |
About โ version, build date, board, pin map and counters. |
![]() |
Flash (simulator on a PC only) โ pick board, radar, Quick flash or Build from source, and port; see exactly what will be written; watch the board boot. |
OLED mirror. Each person is a circle with their distance inside: big digit = metres, small raised digit = tenths, so "1โน" = 1.9 m. The nearest person is solid. There's no status row, so the scope fills the panel. โ top-left = Smart filter on; Wi-Fi icon + number top-right = phones connected; the IP shows bottom-left only until a phone joins. These are exact renders of the firmware's drawing code, not photos:
How it works
Short version: the ESP32 parses 30-byte frames from the radar, keeps the latest three targets, and pushes them as JSON over a WebSocket 20 times a second to whoever is on the hotspot; the browser draws the scope on a canvas. The long version, including the frame format, is in HOW_IT_WORKS.md. The research โ radar physics, why the RD-03D can't be a stethoscope and what can, pin choices โ is in DESIGN_NOTES.md.
Radar options
Blip was written for the Ai-Thinker RD-03D (1.25 mm 4-pin socket, 8 m, up to 3 targets). The HLK-LD2450 (Hi-Link, 24 GHz, about 6 m, up to 3 targets with X/Y position) is supported too:
- It sends the same 30-byte frame (
AA FF 03 00, three 8-byte slots,55 CC), so the same parser reads it. - It has no RD-03D configuration commands, so Blip skips the mode command. Single (nearest) is picked in firmware instead.
- Use the
c3-supermini-ld2450ors3-pico-ld2450build environment (or add-DRADAR_LD2450=1)./api/statusreports"model":"ld2450"while it is running. - Its pins are on a 2.54 mm header, so jumper wires work. Check the labels on the module: its TX goes to the board's RX pin, and its RX to the board's TX.
- Weaker than the RD-03D on people who sit very still (the vendor notes this beyond about 2 m), and range is about 6 m.
- Still 24 GHz, so it clashes with a CDM324 in the same way. Use an HB100 for Stetho, or the radar power switch.
- Not tested on hardware yet. Check the angle direction on the Scope first (Mirror L/R in Settings if left and right are swapped).
Repository map
firmware/ PlatformIO project (src/main.cpp, include/rd03d.h, tracker.h, audio_dsp.h, stetho.h, oled.h, oled_draw.h, web_ui.h)
firmware/prebuilt/ bundled whole-chip images for the four builds + manifest.json (checksums, version, source hash)
web/index.html the phone UI (single file; embedded gzipped into the firmware)
web/flasher.html the flasher (served by the PC tool only; never in the firmware)
web/flash_home.html the red home page the launcher opens, with the flasher inlined
tools/ sim_radar.py, flasher.py, serial_tail.py, make_prebuilt.py, make_pdf.py, embed_web.py, draw_illustrations.py, rd03d_py.py, tracker_py.py
tests/ native C++ tests (parser, audio DSP, tracker, OLED render), Python parser + tracker cross-check, flasher (with fake_pio.py), launcher test
hardware/ wiring, MAX4466 mod (with the DC warning), earphone / I2S amp outputs
examples/ synthetic RD-03D frames for replay; dsp_before.wav / dsp_after.wav
docs/ GitHub Pages site + images + Blip-manual.pdf (built by tools/make_pdf.py)
Source code: The-Dorkknight/blip-radar on GitHub
















Top comments (0)