Measuring Heart Rate Using Wi-Fi
An interesting study recently demonstrated how a person's heart rate can be noninvasively monitored using Wi-Fi signals. It has been getting a lot of attention in the press, so I suspect a lot of people would like to try it out. But the paper is behind a paywall, and even if you do get your hands on it, it is difficult for most people to understand (let alone reproduce) the researchers' methods.
So I decided to take a crack at it. I got a copy of the paper and spent some time digging in and coding up a solution that more or less reproduces the work. Some details are not fully spelled out in the paper, and the team has not released either their code or data, so I cannot guarantee that my method matches it 100%. But while it may not be identical, it is at least quite close, and more importantly, it works. And I suspect most people are more interested in playing with a system that works than they are perfectly reproducing the Pulse-Fi methods to a T.
In the next section, I'll first give an overview of how Pulse-Fi works, then I'll describe my implementation of it.
Important Note: This system is not to be used as a medical device. It could provide false measurements, so it is only for educational use.
Thanks to Pranay Kocheta, Nayan Sanjay Bhatia, and Katia Obraczka for their work on Pulse-Fi, which inspired this project.
How It Works
An overview of Pulse-Fi
![]() |
|---|
| An overview of the Pulse-Fi approach (📷: P. Kocheta et al.) |
To measure heart rate without contact, a person must be positioned between two ESP32 microcontrollers. One of the devices transmits a steady stream of Channel State Information (CSI) packets, while the other receives the packets. The CSI packets provide detailed information that describes how the signal propagates from the transmitter to the receiver. Anything that interrupts the signal, like the movements of a person, alters the signal in measurable ways. This fact has been leveraged for applications like activity recognition in the past.
Heart beats also involve motion, although it is very subtle compared to what is seen in the types of activities, like walking, that activity recognition systems typically target. So to focus in on heart beats, the researchers came up with a multi-step data processing pipeline that looks like this:
| CSI Data Processing |
|---|
| Convert raw CSI data to amplitudes |
| Stationary noise removal |
| Pulse extraction |
| Pulse shaping |
| Data segmentation and normalization |
This processed data is then fed into a multi-layer LSTM network that predicts heart rate.
![]() |
|---|
| The Pulse-Fi LSTM architecture (📷: P. Kocheta et al.) |
My implementation
Predicting heart rate
![]() |
|---|
| Brotha from anotha manufactura |
I have an Adafruit HUZZAH32 and an ESP32-DevKitC v4, both with an ESP32-WROOM-32E microcontroller (these are what I had on hand; other ESP32 boards should work fine). They are placed several feet apart, and the measurement area is between them. One was flashed with the Espressif csi_send code, and the other with the Espressif csi_recv code. The source code was compiled and flashed to the devices using the IDF docker image, e.g.:
git clone https://github.com/espressif/esp-csi.git docker pull espressif/idf # Build csi_send docker run --rm -v $PWD:~/project -w /project -u $UID -e HOME=/tmp -it espressif/idf cd esp-csi/examples/get-started/csi_send idf.py set-target esp32 idf.py flash -b 921600 -p /dev/ttyUSB0 exit # Flash csi_send docker run --rm -v $PWD:~/csi_hr/esp-csi/examples/get-started/csi_send/project -w /project espressif/idf:latest idf.py --port /dev/ttyUSB0 flash # Build csi_recv docker run --rm -v $PWD:~/project -w /project -u $UID -e HOME=/tmp -it espressif/idf cd esp-csi/examples/get-started/csi_recv idf.py set-target esp32 idf.py flash -b 921600 -p /dev/ttyUSB0 exit # Flash csi_recv docker run --rm -v $PWD:~/csi_hr/esp-csi/examples/get-started/csi_recv/project -w /project espressif/idf:latest...Read more »
Nick Bild


Sumit
markwarren.ee
vcazan