Skip to content

About

Smartwatch heart rate for treadmills built before Bluetooth — transmits the 5.4 kHz pulse of a Polar chest strap

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HR Bridge — coil

Buy Me a Coffee

Puts a smartwatch's heart rate onto a treadmill built before Bluetooth existed, by transmitting the 5 kHz magnetic pulse those machines were designed to listen for. The console thinks it's a Polar chest strap.

The finished unit, green light showing


Why

Plenty of good gym equipment predates Bluetooth completely. There's a coil behind the front panel waiting for a short burst of magnetic field, one per heartbeat — the signal an uncoded Polar T31 or H10 puts out. No ID, no pairing, no handshake, which is exactly why any uncoded strap works with any machine of that era, and why two people on adjacent treadmills occasionally read each other's pulse.

If you own one of these, your options today are a chest strap or nothing. This is for people who'd rather wear the watch they're already wearing.

It solves comfort, not capability. The machine already works fine with a strap.

Different problem from my other bridge. If your machine has Bluetooth but refuses to talk to anything that isn't an approved brand, you want hr-bridge instead — that one impersonates a strap over BLE. This one is for machines with no radio at all.

How it works

A XIAO ESP32-C6 connects to the watch as a standard Bluetooth heart-rate client, then drives a ferrite rod through a single resistor to produce one 5.4 kHz burst per beat. That's the whole idea.

watch ──BLE──► ESP32-C6 ──► 220 Ω ──► ferrite rod ──► 1 µF ──► GND
                                          │
                                    5.4 kHz burst
                                          ▼
                                  the console's coil

The GPIO pin is the power source — it swings 0 to 3.3 V at 5.4 kHz and the 220 Ω sets the current at about 9 mA. There's no amplifier and no supply rail feeding the coil. The capacitor is a DC block, not a resonator: the resistor damps the LC flat on purpose, so output doesn't depend on frequency, temperature, or which coil happens to be fitted.

What a real chest strap actually transmits

This is the part I couldn't find written down anywhere, so I measured it. A working Polar T31 was recorded through a coil pickup — a pair of headphones in a mic jack, which works because a headphone driver is a voice coil run backwards — alongside this transmitter in the same file:

this bridge a real T31
carrier 5400 Hz 5410 Hz
burst length 15.0 ms 14.9 ms
3rd harmonic −2.5 dB −38 dB
beat interval 857.13 ms, sd 0.10 ms irregular
output −10.6 dB vs the strap

The carrier is 5410 Hz, not the 5 kHz everyone quotes. The burst is about 15 ms, not the 5 ms I'd assumed. Both defaults in the firmware come from that measurement rather than from folklore.

The harmonic column is the interesting one. A strap's 3rd harmonic is 38 dB down — a clean sine, because Polar drives a tuned tank. Mine is 2.5 dB down, which is what a square wave through a damped coil looks like. Same fundamental, completely different drive topology, and you can read that difference straight off a spectrum.

The strap's burst also rings: about 6 ms of drive followed by 8 ms of decay, which works out to a tank Q of roughly 37. Mine can't ring — Q is 0.14 by design — so the field stops when the PWM stops. Leading edge and duration match; the tail doesn't. A console timing burst arrivals shouldn't care, and that's the last known difference between the two signals.

Full working in docs/measurements.md, including how the coil's inductance fell out of a multimeter reading and an audio ring-down without an LCR meter ever being involved.

The coil

It's the ferrite rod out of a dead Polar T31. The board had failed, but a rod is copper on a core and didn't care.

That wasn't sentiment. A transmit coil has an optimum inductance — below it every turn is free, above it the coil's own reactance chokes the current faster than turns add field. With 220 Ω in series that crossover sits at 6.7 mH, and Polar landed just under it, because they were designing a transmitter too. A small axial choke measured 18 dB worse in the same circuit.

docs/harvesting-the-rod.md covers getting it off the board without snapping the hair-fine enamel leads, which is the only part that can't be undone.

Building one

XIAO ESP32-C6 not a C3
220 Ω resistor the entire output stage
ferrite rod from a dead T31, ~3.2 mH
1 µF capacitor DC block
WS2812B status light, on 3V3
perfboard 60 × 40 mm

Wiring is four nets and fits on a postcard: docs/wiring.svg. Bring-up order, the meter checks, and how to prove it radiates using nothing but Audacity are in docs/build.md.

Firmware needs the Arduino IDE, arduino-esp32 core 3.x and NimBLE-Arduino 2.x. Open firmware/hr_bridge_coil/, pick XIAO_ESP32C6, upload.

There's a test harness that runs on a PC with no hardware attached:

cd firmware/test && make check

It checks that power 0–100 is strictly monotonic in radiated amplitude, that duty never crosses the sin(πD) peak where output starts falling again, and that the beat scheduler holds cadence without accumulating drift. All three were real bugs at some point.

The enclosure

Parametric OpenSCAD in hardware/, with STLs for two ways of mounting the C6 — plugged into female headers, or its pins soldered straight through the perfboard. That choice moves the USB socket by 6 mm and the case height by 3.5 mm, so print the pair that matches your build.

Base prints open side up, lid inner face down. No supports.

The arrow on the lid is not decoration. A rod radiates out of its ends, so the unit has to lie left-to-right across the machine the way a strap sits across a chest. Ninety degrees off is a null — not a weak signal, nothing at all, which looks exactly like a dead unit.

What it can't do

It lags a second or two. A strap fires on your actual heartbeat. This is handed a number by the watch about once a second and paces bursts to match. Invisible at steady effort; noticeable during intervals or on a heart-rate-controlled program.

Output is fixed. The prototype dropped the three-leg attenuator that let it be turned down without a soldering iron, so where you put the box is the only adjustment. Near-field coupling falls off as the cube of distance, which makes that a stronger control than it sounds — but too much signal and too little look identical from the console.

It has never met a real console. Everything here was verified against a measured chest strap and a receiver built from a dead treadmill's own coil. The substitution argument is sound — match a T31 closely enough and any machine that accepts a T31 should accept this — but nobody has yet put one on a treadmill and pressed start. Unit number one is in the post.

And one thing nobody can test from a bench: whether a console quietly rejects heart rates that arrive as steps. A real strap's rate wanders continuously; a watch hands over a fresh integer once a second. If some machine has a plausibility filter that dislikes that, the fix is to interpolate toward each new rate instead of jumping — cheap to do, impossible to know we need until someone reports it.

Repository

firmware/hr_bridge_coil/   the thing that gets built
firmware/coil_bench/       standalone bench harness — no BLE, no watch
firmware/cyd_rx_display/   5 kHz receiver used to measure the strap
firmware/test/             native test harness, runs on a PC
hardware/                  enclosure, parametric + STLs
docs/                      build guide, measurements, receiver design
docs/instructions/         printable cards that ship in the box

coil_tx.h and coil_button.h live at firmware/ and are copied into each sketch folder, because the Arduino IDE insists a sketch's headers sit beside its .ino. Edit the copies at firmware/ and run sync_headers.sh (or .bat) — editing a sketch folder's copy directly is how you end up flashing yesterday's settings and losing an evening to it.

License

MIT. Do whatever you like with it.

Not a medical device, not certified for anything, and assembled on a kitchen table. Don't rely on it for anything that matters.

About

Smartwatch heart rate for treadmills built before Bluetooth — transmits the 5.4 kHz pulse of a Polar chest strap

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages