OpenHRStrap
OpenHRStrap is an open-source DIY chest-strap heart-rate tracker built around the ESP32. It measures real biosignals through electrodes, filters the signal, and applies the Pan–Tompkins algorithm to detect R-peaks and compute heart rate in real time.
Install / Use
/learn @MilosRasic98/OpenHRStrapREADME
OpenHRStrap
OpenHRStrap is an open-source DIY chest-strap heart-rate tracker built around the ESP32. It measures real biosignals through electrodes, filters the signal, and applies the Pan–Tompkins algorithm to detect R-peaks and compute heart rate in real time. The Pan-Tompkins algorithm has been implemented in Python to follow the filter chain as originally described in the paper. The device is programmed so that it is detected as an off-the-shelf BLE device and is recognized by apps like Strava! Below, I will also show how you can extract data from your Strava and analyze it using Python!

Latest Blog on the project: element14 Running Tracker Blog
Link to the latest video on the project: Running Tracker Video Part 1
Original Pan-Tompkins Paper: A Real-Time QRS Detection Algorithm
Table of Contents
- Project Updates
- V1 of the Project
- Pan–Tompkins Algorithm
- Data Filtering Example
- Detection Example
- Strava Data
- Disclaimer
Project Updates
November 2025 — DIY-friendly version made using an XIAO ESP32 board with the AD8232 ECG module. Pan–Tompkins integration tested on static data works great; real-time detection while running is still a WIP. Scroll below for more details!
V2 is currently in progress! This will include a custom PCB with proper data logging and an upgraded AFE. If you have any suggestions for what else you would like to see added, feel free to reach out!
V1 of the Project
The text below covers the V1 of this project. Any new updates on the project after V1 will be placed above this. In this project, I wanted to create a DIY open-source version of a running chest strap sensor. My goals for this project were:
- Module that fits on a commercial chest strap
- Measures the ECG signal and calculates the heart rate from it
- Connects to the phone over BLE like a commercial device
Hardware
The hardware for this version is extremely DIY friendly and is made out of commonly found modules. As an MCU, it relies on an ESP32 XIAO S3 board since it has more than enough power to process the signal, and the BLE is easy to work with. For the analogue front end (AFE), I went with the most popular ECG module, the AD8232. This meant the chest strap needed another electrode added to the chest strap, which I did by sewing an additional button to the back of the strap for a reference electrode. The case for this device was printed out of PLA and TPU, and to interface with the chest strap, I soldered wires directly to steel push buttons. Besides that, you will need a way to power it. I repurposed a small 1S LION cell I had lying around with a small boost converter that stepped up the voltage to 5V; the onboard ESP electronics handled the rest.
Pan-Tompkins Algorithm
For calculating the heart rate, I wanted to go with the Pan-Tompkins algorithm, since it is one of the most significant and widely used methods for ECG signal processing. It originates from a paper titled “A Real-Time QRS Detection Algorithm” that was published by Jiapu Pan and Willis J. Tompkins in 1985. The full paper can be viewed for free on the following link: A Real-Time QRS Detection Algorithm
In the first video that covers the progress of this project, I covered in detail how the whole algorithm works: Running Tracker Video Part 1
I will here briefly explain how the Pan-Tompkins algorithm works with some illustrations and sample data, but I also highly recommend reading through the original paper! The original name of the algorithm now known as the Pan-Tompkins algorithm is the algorithm for real-time QRS detection, and its purpose is to recognise a QRS complex in the signal, or simply said, a heartbeat. The algorithm works by keeping track of a few key parameters:
- SPK - Running Estimate of the Signal Peak
- NPK - Running Estimate of the Noise Peak
- TH1 - Threshold 1 for detecting peaks
- TH2 - Threshold 2 for detecting peaks, usually TH1 / 2 Each of these has variants for both the filtered signal (“F”) and the fully processed integrated signal (“I”).
At the start, all of the parameters are initiated on a few seconds of data that won't be used, by looking at the maximum peak value from that part of the signal, or by looking at the mean and maximum values of the signal. After the initialisation, the signal is analysed in small batches where it is first run through a series of filters and peak detections. Tompkins filtering pipeline:
- Band-pass filtering
- Derivative
- Squaring
- Moving window integration
This produces two sets of peaks:
- FILT peaks – peaks from the band-pass filtered signal
- INT peaks – peaks from the fully processed integrated signal
Going with the INT peaks, the peaks are analysed to check whether they satisfy the condition of being above the value of TH1. If this is the case for a peak, we then search for a peak in FILT peaks that also satisfies its TH1 and is within a small delta t of the INT peak. Only when we find that FILT peak, we can classify that as an R peak and update our running parameters based on the peak value (SPK, NPK, TH1, TH2). If, however, a peak is in any case under TH1, it is classified as a noise peak, and the running parameters are updated with different formulas. What makes Pan-Tompkins such a good algorithm is the search-back part, which is activated if no R peak has been classified for more than 166% of the RR average distance. This means we missed a peak due to noise or some other issue, and the algorithm starts the search back from the last classified R peak, but this time, using the TH2 to categorise a peak as an R peak. The above explains the essence of the algorithm with some more important things like RRR distance tracking, explained in more detail in the drawing and in the video!
Data Filtering Example
In this section, I will show an example of the Pan-Tompkins algorithm working on some data I collected using the setup described above. All of the codes, both for the data acquisition and for data analysis, can be found in the GitHub repo and on the element14 community. If you believe anything is missing, feel free to contact me!
Raw ECG Signal
To begin, let's first take a look at the raw ECG signal and a segment of that signal that we will be looking out throughout the whole analysis.


Band-Pass Filter
The signal is first passed through a band-pass filter. To accomplish this, and to follow the paper, this was implemented as a low-pass filter followed by a high-pass filter. The results of that can be seen below.


Derivative Filter
The signal seen above is the one on which we will detect the peaks, but we also need to filter it further to get to our "INT" signal. The next filter we are passing our signal through is the derivative filter; the results of that are shown below.

Squaring
After the derivative filter, the signal is squared

Moving Window Integration
The last filter we will pass our signal through before running the peak detection algorithm is the Moving Window Integrator.

INT Peaks
Running the peak detection algorithm on a signal with not too much noise, we will usually grab all of the R peaks, some T waves, and a few noise peaks. Example of that below.

FILT Peaks
We also run the same peak detection algorithm on the band-pass filtered signal. That signal and the detected peaks are shown in the figure below.
 model or a full model breakdown. Trigger when asked for model-level usage/cost data from codexbar, or when you need a scriptable per-model summary from codexbar cost JSON.
TrendRadar
49.6k⭐AI-driven public opinion & trend monitor with multi-platform aggregation, RSS, and smart alerts.🎯 告别信息过载,你的 AI 舆情监控助手与热点筛选工具!聚合多平台热点 + RSS 订阅,支持关键词精准筛选。AI 智能筛选新闻 + AI 翻译 + AI 分析简报直推手机,也支持接入 MCP 架构,赋能 AI 自然语言对话分析、情感洞察与趋势预测等。支持 Docker ,数据本地/云端自持。集成微信/飞书/钉钉/Telegram/邮件/ntfy/bark/slack 等渠道智能推送。
