Since 2014 I have recorded hundreds of data-rich heartbeat recordings with low-cost software and hardware for a long-term heart rate variability biofeedback project. Originally I wanted to pursue neurofeedback (and still do) but in 2012 I got a tip from the biohacker community that the heart provided a dense but hackable biosignal with comparable personal value.
The first iteration of the project and the data is available on github at joegle/hrv-biofeedback/ but my newer work and data will be private.
Heart rate variability (HRV) is the physiological phenomenon of variation in the time interval between heartbeats . The heart rate changes from moment to moment and provides a rich signal that integrates local emotional arrousal and broad physiological activity. More below
Biofeedback is the process of gaining greater awareness and influence of physiological functions by using electrical sensors to connect us to the activity of those systems. Here I outline my data set analysis and demo real-time visual feedback. More below
Collecting HRV with Arduino
The hardware stack to get the heart beat signal to the computer is simple:
- Microcontroller/Arduino with firmware
- 5V Pulse Sensor Amped analog sensor
- Pulse Sensor clipped to ear lobe
- USB cord to computer for serial output
Since 2014 heart rate monitoring devices have become more popular but I still can't find many options to satisfy my use case:
- RR interval data is not collected
- Raw data is not easily viewable if at all
- Private health data is shared
- Heart beat events arn't able to be transmitted live
Connecting the Pulse Sensor to your ear while connected to a grounded computer could be dangerous but I do it all the time.
The Pulse Sensor Amped is an photoplethysmogram  made for the Arduino. The Pulse Sensor site has well-documented and concise firmware  that will allow you to extract live heart beat signal. I simply modified the code to send the interbeat interval, IBI variable, in milliseconds over the USB serial port:
Reading Arduino Serial with Python
Every time a pulse is detected the time delay from the last beat is pushed through a serial device like
joe@joegle $ stty -F /dev/ttyUSB0 cs7 cstopb -ixon raw speed 115200 joe@joegle $ cat /dev/ttyUSB0 642 606 648 620 648 ...
My first biofeedback server was written in Python as a module with an extendenble class 'Heart_Monitor' and used pySerial python module to read the serial device. The class has the following usual methods that can be reimplemented:
- __ini___ constructor
- start to begin scanning the device
- listen_for_beat for waiting for next heart beat
- on_beat for handling each heart beat events
- on_quit for stopping the monitor
The feedback server built with a Python HTTPServer and extending Heart_Monitor class to send data to a website rendering a live updating graph using D3.js.
The Python server was a great "minimum viable product" that I mostly used to passively archive my data to disk. I have rewritten the server in Go and have gained nanosecond resolution on event times which should increase the signal-to-noise ratio. I will continue to enjoy Python for informatics and prototyping but after you learn exactly what you want and demand speed I have found Go to be phenomenally productive.
Datamining and Feedback
After collecting a large sample of heart beat signals I can start to do some sensemaking. I primarily use Python for the data processing environment; NumPy handles the statistics and the graphs are generated with matplotlib.
For a quick overview of the data I plot the mean and variances of each session (without taking into acount the session length).
FFT for Heart Rate Variability
To inspect deeper into each session we can use the Fourier transform which SciPy provides. Running a time series session through the Fast Fourier Transform (FFT) will return an interesting graph of its frequency domain. The peaks show us where "energy" is located. Most of the heart beat is generated by a regular ticking from the sinoatrial node but it also appears to have a secondary rhythms from other influences.
FFT graphs might show us activities in the parasympathetic nervous system, "rest-and-digest" and the sympathetic nervous system, "Fight-or-flight". For example, in a relaxed state your heartbeat will slow down during inhalation and speed up durring exhalation. Durring a stressor, such as excersize, the heartrate will be strong and steady.
Here are 2 different sessions to show how specgram qualities and features can be seen (click to enlarge):
After getting a big picture of the data you can streamline the processing to display metrics to the user in near real-time. When the delay is short and the representation is intuitive the user can begin understanding the signal as an experience and not as numbers.
The first proof of concept was this simple D3.js plot of rolling standard deviation and averages.
The current iteration is a React app that interacts with a historical data API and live data WebSocket. React is a refreshing web framework for composing responsive and reusable web components. A demo is available here.
The main modal of the HRV dashboard is a set of horizon graphs  that I implemented in D3 inside the React components. The horizon graphs (or charts) have a high return on investment because they are easy to code and can be stacked to compare any number of metrics over time.
Mapping an information dense signal into another modality is a wonderfully intimidating, open-ended and multidisciplinary art. The RR interval sequence may have a relatively small dimensionality but still demands quite a bit of engineering overhead. To increase development speed I have been studying OpenGL Shader Language as a powerful medium to iterate through high fidelity mappings of the live signal.
Improvements / Ideas / Todo
- Portable monitoring
- Passively recording breathing and heart through video
- Adding blood O2 measurements
- Recording the raw arduino diode signal
- Measure noise and latency
- On-board FFT
- More accurate clock
1. The Pulse Sensor Amped works by photoplethysmography where it shines a light into thin body tissue to illuminate the blood flowing through capillaries and the Pulse Sensor Amped firmware finds spikes in the photodiode samples to derive heart beat events. More specifications found on their store page.
2. The Arduino project has a beginner-friendly IDE for developing and uploading firmware. The arduino/ folder of my repo has more information with Ardiuno code and self-contained c++ code with a Makefile for compiling and uploading the code to your board.
3. Sizing the Horizon: The Effects of Chart Size and Layering on the Graphical Perception of Time Series Visualizations - Jeffrey Heer, Nicholas Kong, Maneesh Agrawala