
This week's pick is OpenHRStrap, Milos Rasic's open-source ECG chest strap: an AD8232 front end and a XIAO ESP32 run the Pan–Tompkins detector on the board and report heart rate over standard Bluetooth, for roughly $50 and a beginner weekend.
D0, and the sketch named ESP32_HR_Tracker.ino carries the full Pan–Tompkins QRS detector so the detection runs entirely on the board. The chain is a low-pass filter, a high-pass filter, a five-point derivative, a squaring stage, and a 30-sample moving-window integration — 150 ms of the signal — followed by an adaptive threshold that tracks the signal and noise peaks separately. A 300 ms refractory period blocks a second detection inside the same beat, and a width gate accepts only peaks whose half-height width falls between 80 and 200 ms. 40x180D) with the Heart Rate Measurement characteristic (0x2A37), advertises the heart-rate-sensor appearance code 832, and identifies itself as ESP32 HRM. Software that already expects a chest belt finds it directly, which is what makes the Strava comparison in this project possible at all. 4| Qty | Part | Specification | Role in build | Planning cost |
|---|---|---|---|---|
| 1 | Chest strap | Commercial strap with two snap studs, Polar pattern | Carries two electrodes against the chest | $15–25 |
| 1 | Reference electrode | Steel press stud, sewn into the strap backing | Third electrode the AD8232 needs for a clean baseline | $1–2 |
| 2 | Electrode studs | Steel press studs matched to the strap snaps | Solder points for the two signal wires | $1–2 |
| Qty | Part | Specification | Role in build | Planning cost |
|---|---|---|---|---|
| 1 | Microcontroller board | Seeed Studio XIAO ESP32 (the README says XIAO ESP32S3; the sketch banner prints ESP32C3) | ECG sampling, Pan–Tompkins detection, BLE reporting | $8–12 |
| 1 | ECG front end | AD8232 heart-rate monitor module | Instrumentation amplifier and filters for the electrode signal | $8–22 |
| 1 | Boost converter | 5 V step-up module, MT3608 class | Raises the single cell to the board's 5 V input | $1–3 |
| 1 | Battery | 1S lithium-ion cell, 500–1000 mAh pouch | Untethered power while the strap is on your chest | $5–9 |
| 1 | Slide switch | SK-12D02-VG5 or equivalent SPDT | Cuts the cell from the boost converter | $0.50–1 |
| 1 | Charge header | 2-pin 2.54 mm header or JST | Exposes the cell terminals for an external charger | $0.30 |
| Qty | Part | Specification | Role in build | Planning cost |
|---|---|---|---|---|
| 1 | Case | PLA and TPU, printed from your own model | Houses board, front end, boost converter and cell | $2–4 |
| 1 | Hookup wire | 26–30 AWG stranded, silicone jacket | Electrode wires and board interconnect | $2–3 |
| 1 | Consumables | Solder, heat-shrink, tape | Assembly and strain relief | $2–3 |

D0, and its shutdown pin is tied high so the front end stays awake. The load-output pins, LO+ and LO-, carry no connection in V1, which means leads-off detection sits unused on this build. Power runs from the cell through the slide switch into the boost converter, out at 5 V to the board's 5V pin, and a two-pin header puts the raw cell terminals within reach of an external charger. 3| Signal | AD8232 module side | XIAO ESP32 side | Note |
|---|---|---|---|
| Analogue output | OUTPUT | D0 | The firmware's ECG_PIN constant; sampled by the 12-bit ADC |
| Supply | 3.3V | 3V3 | Front end runs at 3.3 V |
| Enable | !SDN | 3V3 | Held high to keep the front end enabled |
| Ground | GND | GND | Common ground with the boost converter |
| Electrodes | RA, LA, RL | — | Wired to the strap studs |
| Board power | — | 5V | From the boost converter output |
| Cell | — | — | Cell → slide switch → boost converter input |

D0, the shutdown pin is tied to 3.3 V, LO+ and LO- are marked unconnected, and header H9 is the charge point for the cell. 3ESP Codes/V1, and knowing which one you are flashing matters more than any build step on this page.ESP32_HR_Tracker.ino is the real firmware. It samples D0 from an esp_timer callback at 200 Hz into a 1000-sample ring buffer, runs the filter and detector chain on each sample, and notifies the derived rate over Bluetooth only once a rate exists and a phone is connected. Keep an eye on the startup banner: it prints ESP32C3 while the README names the XIAO ESP32S3 board, so set your board target from what the banner and your hardware agree on, and treat the analogue pin name D0 as the thing both variants share. 4XIAO_WorkingBLE_HR.ino is a Bluetooth test. It advertises the same Heart Rate Service and then transmits a fixed sawtooth between 50 and 60 bpm, once a second, whatever the electrodes are doing. The author wrote it to confirm a phone would accept the device as a heart-rate belt. Flash it first if you like, and expect that number, because that number is hard-coded. 8SamplingScript.ino captures rather than reports. It grabs 20,000 samples at the same 200 Hz — a little over a hundred seconds — and prints the lot to the serial port for you to paste into the Python notebook. 9DETECTION_MODE, shipped at 3, which pairs reactive detection with a rate limit of one bpm of change per second — raise MAX_BPM_DELTA_PER_SEC if the displayed number feels sluggish. And the sketch carries a SIM_USE branch for replaying recorded ECG instead of the ADC; it ships set to false with the sample-loading line commented out, so a builder who wants to exercise the detector with the electrodes disconnected has to supply a data header and re-enable that line themselves. 4PanTompkins.ipynb walks a captured trace through each filter stage with scipy.signal.lfilter, and StravaDataAnalysis.ipynb pulls an activity export and overlays the device against a reference. Both are worth running before you solder anything, because they show you what a good trace looks like on this hardware. 610

ESP32_HR_Tracker.ino on a bare XIAO board, watch the tick: samples= line climb to confirm you are sampling at 200 Hz, then run the sampling sketch with the electrodes on your chest and paste the trace into PanTompkins.ipynb. If the R-peaks on your own trace land where they should, ordering the rest of the bill of materials is the next move. 49hackaday.com
github.com
github.com
github.com
robots.ox.ac.uk
github.com
github.com
github.com
github.com
github.com
This story was produced automatically by a channel. One sentence is all it takes for Neodrop to keep producing for you.