Vigil
2 North · 4 rooms Built on RuView ↗ ← Portfolio

Contactless ward monitoring

Vigil

A vigil is keeping watch over someone who is ill — continuously, quietly, without waking them. Vigil does that with no camera, no wearable, and nothing clipped to the patient.

Radio reflections off the body carry breathing and heart rate through the wall. A thermal array over the bed confirms who is actually in the room. The nurse gets presence, vitals, and bed-exit alerts for a room they never had to walk into.

Through-wall~5 mFresnel-zone, signal-dependent
Respiration6–30 BPM0.1–0.5 Hz band
Heart rate40–120 BPM0.8–2.0 Hz band
Fall latency< 200 ms3-frame debounce
Per room~$95No camera, no consumables
CSI · 56 subcarriers × time ch 1 / 6 / 11
01

Why two sensors, not one

Vigil is the clinical application layer on top of RuView, the open-source WiFi CSI sensing stack by ruvnet. The sensing physics is theirs, and every performance figure on this page is carried over from their published benchmarks unchanged rather than restated as my own. What I designed is the fusion layer, the clinical semantics, and the interface.

Radio — through the wall

Channel State Information from $9 ESP32 nodes reads the millimetre chest-wall motion of breathing and the pulse riding underneath it. Radio passes through drywall and bedding, so the sensing works from the corridor, in the dark, under a blanket.

Infrared — inside the room

A 32×24 thermal array over the bed cannot see through walls — it is strictly line-of-sight, and that is the point. It answers what radio is worst at: how many bodies are in here, which one is in the bed, and is surface temperature climbing.

Fusion — the actual product

Radio alone cannot reliably separate a patient from the nurse leaning over them. Infrared alone cannot reach through a wall or recover a heart rate. Together they resolve the ambiguity that makes single-modality ward sensing untrustworthy.

Try it below. The console is driven by a physical model of this signal chain, not a recording. Switch the modality selector to RF only or IR only and watch specific capabilities disappear — that degradation is the entire argument for the second sensor.
02

How radio sees a breath

The whole system rests on one physical fact: a chest wall moves 4–12 mm when someone breathes, and that movement changes the length of the path a radio wave takes to bounce off them. Measure the change in phase, and you have measured the breath — through the wall, in the dark, under a blanket.

Cross-section of one room, viewed from the side. Chest travel is drawn far larger than life so the mechanism is legible — in reality it is a few millimetres. Nothing here is a camera: the only thing travelling between the patient and the sensor is ordinary WiFi the building already radiates.

2b

One signal, two vital signs

Breathing and heartbeat arrive mixed together in the same measurement. They are separated by frequency, not by cleverness: breathing lives below 0.5 Hz, the pulse lives above 0.8 Hz, so two bandpass filters pull them apart.

Raw phase — what the node measures

Breathing, pulse, and sensor noise summed into one messy signal. Unreadable as-is.

0.1–0.5 Hz → respiration

Slow, high-amplitude. Count zero-crossings → 14 breaths/min.

0.8–2.0 Hz → cardiac

Fast, roughly 20× smaller. Same method → 62 beats/min.

Why this is not an ECG. Radio measures the chest physically moving, not the heart's electrical activity. There is no P wave, QRS complex, or T wave to read — just a displacement bump per beat. It gives you a rate you can trust and a rhythm you cannot. That limit is why Vigil alerts on rate and absence, never on morphology.
03

Ward sensing console

The same physics across four beds on a step-down unit. Pick a room, press a scenario, and watch the panels respond. Three things worth trying: Fall (the room turns red and distress latches), Bed exit (vitals cut out mid-walk, because motion swamps a millimetre-scale signal), and the RF only / IR only toggle (capabilities visibly disappear).

Floor plan — RF occupancy 8 CSI nodes
CSI node Thermal array Patient Staff

Four rooms seen from above, corridor along the bottom. Dashed blue lines are radio links crossing the shared walls — that is the through-wall sensing.

Drive a scenario in the selected room
Thermal — 32×24

Heat map of the selected room. Bright blob = a body. This is how the system counts people and tells the patient in bed from the nurse beside it.

Respiration — 0.1–0.5 Hz
Cardiac — 0.8–2.0 Hz

The two separated bands from section 02, live for this patient. They grey out whenever the person moves too much to measure.

Inferred state

Plain-language conclusions the system will commit to. Highlighted = currently true. These, not the raw waveforms, are what would page a nurse.

Event feed
04

Signal chain

From raw subcarrier phase to a state a nurse can act on, in six stages.

01 · Capture

CSI at the node

ESP32-S3 reports amplitude and phase across 56 subcarriers, channel-hopped over 1/6/11 on a TDM slot schedule for roughly 3× the sensing bandwidth of a single link.

02 · Clean

Unwrap and de-spike

Hampel filtering on amplitude, phase unwrapping and linear-fit removal to strip transmitter clock offset, then a coherence gate that rejects bad measurements rather than guessing through them.

03 · Separate

Two bandpass filters

0.1–0.5 Hz isolates the chest wall for breathing. 0.8–2.0 Hz isolates the pulse riding on top of it. Rate comes from circular variance and zero-crossing, not a learned regressor.

04 · Gate

Motion vetoes vitals

Gross body motion swamps a millimetre-scale signal. Motion-band power above threshold suppresses the vitals output entirely instead of reporting a number derived from noise.

05 · Confirm

Thermal cross-check

The array segments warm blobs in-room, counts bodies, and tags the one on the bed footprint as the patient. Radio says something is moving; infrared says it is the nurse.

06 · Infer

Semantic states

Fused features drive the states a nurse acts on — bed exit, no movement, elevated fall risk, possible distress — each carrying its own confidence rather than one blended score.

05

Per-room bill of materials

The economics are the reason this is interesting for observation and step-down beds, which today get no continuous monitoring at all.

PartRoleQtyApprox.
ESP32-S3 CSI nodeRadio capture — two per room for a multistatic link, plus reuse of the neighbouring room's nodes as extra illuminators2$18
MLX90640 thermal array32×24 far-infrared, 55° FOV, ceiling-mounted over the bed footprint1$45
Raspberry Pi 5Fusion, semantic inference, ward console — one per 8 rooms, amortised0.125$10
PoE splitter + mountsSingle-cable install, no new mains runs1$22
Per roomNo camera, no wearable, no consumables~$95
06

What is measured, and what is not

RuView is unusually blunt about the gap between its published benchmarks and its live hardware path, and a clinical concept built on top of it inherits that obligation. Vigil is deliberately scoped to the primitives the upstream project can actually stand behind.

Used here

Breathing and heart rate

Deterministic bandpass and zero-crossing over unwrapped phase. No model weights involved, so there is nothing to over-claim — 6–30 BPM and 40–120 BPM, real-time.

Used here

Presence and fall detection

82.3% held-out temporal-triplet accuracy on the published encoder, roughly 30 s of ambient calibration per room. Falls via phase-acceleration threshold with a 3-frame debounce, under 200 ms.

Excluded

17-keypoint skeletal pose

The on-device checkpoint sits at PCK@20 = 3.0%, well below its own ≥35% target, and its runtime path still returns confidence zero. The strong MM-Fi pose numbers come from multi-antenna research NICs, not a single ESP32. A ward interface has no business drawing a skeleton it cannot justify.

Excluded

Identity recognition

Per-channel identity matching is experimental upstream and measured as not separable on WiFi alone. Vigil identifies roles by position — the body on the bed footprint is the patient — and never claims to know who someone is.

Regulatory reality: nothing here is a cleared medical device. Contactless vitals of this kind would sit as a supplementary alerting layer under clinical supervision, not as a replacement for monitoring a patient is actually prescribed. The privacy argument is the genuinely strong one — no pixel of video ever exists, so there is no imaging record to govern in the first place.
07

Design notes

Interaction model

A night-shift nurse covering a dozen beds does not want a dashboard, they want to know which door to walk through next. So the floor plan is the primary surface and the per-room detail is secondary — rooms surface themselves by changing color, and the vitals panel is what you look at after a room has already earned your attention. Nothing in the interface rewards continuous watching.

Why fusion beats a better model

The tempting path is to train a bigger network on the radio signal until it separates patient from staff on its own. The cheaper and far more defensible path is a $45 thermal array that answers the same question geometrically. Most of the difficulty in single-modality WiFi sensing is ambiguity, not resolution, and ambiguity is usually better dissolved with a second sensor than with more parameters.

The failure mode that matters

A missed fall is bad; a false fall alert at 3am is how a system gets muted and then ignored. Vigil therefore treats abstaining as a first-class output — when motion swamps the vitals band the panel says so instead of interpolating, and confidence is reported per-state rather than as one number that hides which part is guessing.

Next step

The honest next milestone is empirical, not architectural: a paired capture rig recording thermal ground truth alongside CSI in a real room, to measure how much the infrared channel actually improves person-count and bed-exit precision over radio alone. Every fusion claim on this page is a design argument until that number exists.