Wrist Health Tracker
Public Unreviewedby TylerK
A wrist-worn nRF52840 health tracker for sleep-quality scoring: heart rate, HRV, SpO2, steps and skin temperature, logged to flash and synced over BLE to a home server. Four-layer 32 x 30 mm KiCad board with single-sided assembly, a 3D-printed 35.7 x 33.9 x 9.95 mm case and a magnetic pogo-pin dock.
| Name | Last updated |
|---|---|
| docs | 7h ago |
| hardware | 7h ago |
| kicad | 7h ago |
| mechanical | 7h ago |
| package.json | 7h ago |
| page.json | 7h ago |
| README.md | 7h ago |
Wrist Health Tracker
A wrist-worn health tracker for scoring sleep quality.
- What it measures: a Nordic nRF52840 BLE module reads heart rate, heart-rate variability, blood oxygen (SpO₂), steps and skin temperature from three sensors on one I²C bus.
- What it does with the data: it logs everything to on-board flash and syncs in batches over Bluetooth Low Energy to a home server.
- What the server does: the analysis — HRV statistics, sleep/wake and sleep-stage estimation, temperature trends and desaturation events.
| Board | 32 × 30 mm, 4 layers, 0.8 mm. Every part is on the skin side, so the board takes single-sided assembly. |
| Case | 35.7 × 33.9 × 9.95 mm, 41.3 mm lug to lug. Takes standard 20 mm quick-release bands. |
| Battery | 302025 Li-Po, about 110 mAh. Estimated at about 5.4 mAh a day, against a 3-day minimum. |
| Charging and data | Magnetic pogo-pin dock (USB power and data) |
| Status | Designed and verified (ERC, DRC, schematic parity, enclosure fit). Not yet fabricated. |
Hardware
| Top (skin side) | Bottom (battery side) |
|---|---|
The circuit has six blocks:
- Dock and charging: four pogo landing pads (VBUS, D−, D+, GND), USBLC6 ESD protection, and an MCP73831 Li-Po charger at 83 mA with a red charge LED.
- 1.8 V power: a TPS62840 buck with 60 nA quiescent current runs the whole system. A 1 M / 470 k divider feeds the battery voltage to the ADC.
- MCU and radio: an Ebyte E73-2G4M08S1C (nRF52840) with a ceramic antenna at the board edge, under a copper keep-out on every layer. Plus a 32.768 kHz crystal.
- Sensors:
- a MAX30101 optical sensor (green, red and IR LEDs);
- a BMI270 IMU with an on-chip step counter;
- a TMP117 ±0.1 °C skin-temperature sensor.
- Data log: a W25Q64JW, 8 MB of 1.8 V QSPI flash.
- User interface: a side-push button and a white status LED.
| Metric | Sensor | Why it matters for sleep |
|---|---|---|
| Heart rate | MAX30101 green PPG | Resting HR, the nightly HR dip |
| HRV (RMSSD, SDNN, LF/HF) | Inter-beat intervals from the PPG | Deep and REM sleep, recovery |
| SpO₂ | MAX30101 red + IR | Desaturation events |
| Respiratory rate | PPG modulation | Sleep-stage input, illness flag |
| Steps / actigraphy | BMI270 step counter, activity counts per 30 s epoch | Sleep/wake detection (Cole-Kripke) |
| Skin temperature | TMP117 through an aluminium contact post | Nightly temperature deviation |
Layout.
- In1 is a solid ground plane, and In2 is the +1V8 plane.
- Signals run on the outer layers, each with a ground pour.
- Buck converter: its input loop is 0.31 mm².
- Thermal and current: a four-layer current and thermal solve puts the peak at 27 A/mm². The hottest part is the charger, with a 20.5 °C rise while charging.
- TMP117: it sits in a no-pour area, so it reads the skin rather than the board.
Further reading:
docs/design.md: the power design, the full MCU pin map, the stack-up, the analysis results and the bring-up order.hardware/schematic.pdf: the schematic.docs/routing.svg: a plot of the routed layers.
Enclosure and dock
![]()
The case is a 3D-printed tub with a skin-side back plate. The stack, from the wrist outward, is: back plate, board (parts facing the skin), cell, case top.
Optics.
- Two 3 mm acrylic light pipes carry the PPG light. They sit in an IR-opaque holder with a barrier between the LEDs and the photodiode.
- The holder is part of the back plate, on a boss 0.65 mm proud of the skin face.
- An aluminium post conducts skin temperature to the TMP117.
Assembly.
- Four M1.2 corner screws close the case.
- The board is located by crush ribs against datum pads.
- The side button is a printed cap over the TS24CA switch.
Dock.
- The device drops into a recess in the cradle, which has a channel so the band can stay on.
- A tongue on the cradle enters a well in the back plate and carries four pogo pins onto the dock pads. Each pin compresses 0.6 mm.
- Two pairs of magnets, with opposite poles, pull the device down and let it seat only one way round.
- Grooves in the cradle carry the charge LED's light out beside the device.
- A 100 µF electrolytic across the dock's VBUS and GND pins damps the hot-plug ring.
Fit check. mechanical/check_fit.py checks every printed and cut part against the board's 3D model. It covers:
- interference;
- the board's insertion path;
- the button travel;
- a maximum-size cell;
- the battery lead route;
- the rework pry slots;
- the wall thickness round each screw;
- the device seated on the dock, including pogo alignment against the pad positions in the
.kicad_pcb; - the LED windows and the magnet pockets.
The current design is CLEAN. mechanical/README.md has the parts list, the materials and the build order.
| Skin side | Dock |
|---|---|
Verification
| Check | Result |
|---|---|
| ERC | 0 errors, 0 warnings |
| DRC (clearance, shorts, holes, dangling copper, mask bridges) | 0 errors |
| DRC unconnected items | 0 |
| Schematic parity | 0 issues |
| Module footprint against the vendor land pattern | 43 / 43 pads |
| Enclosure and dock fit check | CLEAN |
Ordering
Board (JLCPCB).
- Upload
hardware/gerbers_jlcpcb.zip, with these settings:- 4 layers, 0.8 mm thick, ENIG finish;
- minimum track and space 0.09 mm;
- minimum via hole 0.2 mm, tented.
- For assembly, use standard PCBA, top side only, with
hardware/bom_jlcpcb.csvandhardware/cpl_jlcpcb.csv. - Every BOM line has an LCSC part number.
- Parts cost about $58 for two boards, plus a $30 loading fee for the extended parts.
Enclosure.
- The body and back plate are printed in MJF PA12 nylon; the back plate must be black.
- The button cap is printed in SLA resin.
- The light pipes are laser-cut from 3 mm clear cast acrylic.
- The cradle can be printed in any light-coloured filament.
Firmware notes
- All I/O is 1.8 V. A debug probe must support 1.8 V targets, such as an nRF52840 DK or STLINK-V3MINIE.
- Programming is over the SWD pads on the battery side, then over USB through the dock.
- The PPG is disabled below a battery voltage of about 3.4 V, because the MAX30101's LED supply comes straight from the battery.
- The full pin map and the I²C addresses are in
docs/design.md.
Repository
README.md
docs/
design.md hardware design: power, pin map, stack-up, analysis, ordering, bring-up
board-top.png, board-bottom.png, routing.svg, hero.png
hardware/
schematic.pdf
health-tracker.step board 3D model (KiCad export, origin at the board's top-left corner)
health-tracker.glb
gerbers_jlcpcb.zip, bom_jlcpcb.csv, cpl_jlcpcb.csv
kicad/
health-tracker.kicad_pro / .kicad_sch / .kicad_pcb
lib/ project symbols, footprints and 3D models
mechanical/
README.md enclosure and dock: design, parts list, build order
enclosure.py parametric CadQuery model of every printed part and the dock
check_fit.py interference, build-path and dock checks against the board's 3D model
assembly.py, render.py full assembly (GLB) and renders
out/ STEP and STL for each part, full_assembly.glb, renders
adom-wiki repo clone tylerk/wrist-health-tracker