Skip to the content
2 layersFitnessMotionDevice, the printed circuit board in 3D

FitnessMotionDevice

h2dakhil/RepSense

IMU-based Wearable Exercise Repetition Monitor

Copper layers
2
Thickness
1.6 mm
Parts
59
Nets
87
Pads
256
Tracks, vias
658, 144
Pours
12
Routed
Yes
KiCad
KiCad 9.0 (file 20241229)
Created
13 May 2026
Updated
15 May 2026

Overview

FitnessMotionDevice is an open-source printed circuit board by h2dakhil, from the h2dakhil/RepSense repository on GitHub. It is a 2-layer board with 59 parts on 87 nets, routed with 658 tracks and 144 vias.

It is built around the BQ24074RGTR and USBLC6-2SC6. Its parts include 26 capacitors, 13 resistors, 4 ICs, 4 connectors and 3 inductors. It belongs with the sensors and measurement and wearables boards and the nRF52 and nRF5x boards of this library.

Main components

2

README

README.md

Wrist Fitness Tracker — Custom PCB

A wrist-mounted, watch-form wearable that detects and counts gym exercise reps in real time using an IMU and sensor fusion. Built around a circular 42 mm custom PCB designed for low power, low cost, and size-constrained wearable use.

Inspired by the Apple Watch workout detection feature but built from scratch — custom hardware, custom firmware, no cloud dependency.


Overview

The device sits on the wrist like a watch. It reads 6-axis motion data from an IMU, runs an Extended Kalman Filter (EKF) to fuse accelerometer and gyroscope data into a clean orientation estimate, and uses that to detect and count repetitions for exercises including:

  • Bicep curl
  • Shoulder press
  • Bench press
  • Lateral raise
  • Squat
  • Deadlift
  • Overhead press

Rep count and exercise type are displayed in real time on a small OLED screen. The entire signal processing pipeline runs on-device with no wireless transmission required in v1.


Hardware

System block diagram

Screenshot 2026-05-14 at 12 40 06 PM

MCU — nRF52840 QIAA QFN73

Nordic's nRF52840 was selected because it satisfies every constraint in a single chip with no external LDO required:

  • Cortex-M4F at 64 MHz with hardware floating point — needed for EKF math
  • Native USB (D+/D−) — drag-and-drop UF2 firmware flashing, no UART bridge chip
  • BLE 5.0 built in — phone integration ready for v2 with no extra hardware
  • Internal DC-DC converter (DCDCEN0) — steps VDDH down to 3.3V internally, powers entire board via EXTSUPPLY rail
  • 1.5 µA deep sleep with wake-on-interrupt — critical for wearable battery life
  • VDDH accepts up to 5.5V — direct PMIC output connection, no external LDO needed
  • Same chip as the Seeed XIAO nRF52840 Sense used for firmware feasibility validation

Circuit configuration: Nordic Config 4 (High Voltage mode, DCDCEN0 enabled, USB enabled, NFC disabled). The PMIC SYS output feeds VDDH directly. The chip's internal REG0 DC-DC produces a stable 3.3V on VDD which is exposed as the board's entire 3.3V supply rail via EXTSUPPLY. One 10 µH inductor on DCCH is the only passive required for this configuration.

Programming: First-time bootloader flash via SWD using a J-Link EDU Mini and Tag-Connect TC2030-IDC-NL pads on the PCB. After the Adafruit UF2 bootloader is installed, all subsequent firmware updates are drag-and-drop .uf2 over USB — identical to the Seeed dev board experience.

Package selection: QFN48 was considered and rejected. The QFN48 does not expose D+, D−, or VBUS — USB is physically absent. QFN73 is required. The 1 mm size difference per side is irrelevant at 42 mm PCB diameter.

IMU — LSM6DSVTR

ST's LSM6DSV was selected for its onboard sensor fusion engine and FSM (Finite State Machine) which offload motion processing from the MCU:

  • 6-axis: 3-axis accelerometer (±2 to ±16 g) + 3-axis gyroscope (up to 4000 dps)
  • Onboard sensor fusion reduces MCU interrupt load
  • Programmable FSM enables gesture and motion pattern detection in hardware
  • Large FIFO for buffered data collection, reducing MCU wake frequency
  • Low power always-on mode for wrist-raise and motion-triggered wake
  • I2C interface, address 0x6A (SA0 pulled to GND)
  • INT1 routed to P1.06 — configured as wake-on-motion interrupt

INT1 is the key to efficient battery use. The nRF52840 sleeps at 1.5 µA. When the IMU detects motion above a threshold it pulls INT1 high, waking the MCU instantly. The MCU only runs the rep counting pipeline while the user is actively moving. Between sets and between sessions the system is effectively off.

I2C pin assignment: SDA → P1.04, SCL → P1.05, INT1 → P1.06

PMIC — BQ24074RGTR

TI's BQ24074 handles charging and system power path in a single 3×3 mm QFN:

  • Dynamic Power Path Management (DPPM) — simultaneously powers system and charges battery from USB, reducing battery charge/discharge cycles
  • USB500 mode selected (EN1 high, EN2 low) — 500 mA input limit, leaves ~400 mA headroom for system after 100 mA charge current
  • Charge current set to 100 mA (0.5C for 200 mAh cell) via 9 kΩ ISET resistor
  • Input range 4.35–10.5V — compatible with USB 5V
  • OVP, thermal regulation, reverse current, and short-circuit protection built in
  • TS pin tied to 10 kΩ to GND — battery has no NTC thermistor, this prevents false thermal fault

Display

0.91" SSD1306 OLED, 128×32 monochrome, I2C address 0x78. Shares I2C bus with IMU — no address conflict. Max 30 mA. Soldered directly to 4× 2.54 mm PTH pads on PCB. Onboard module pullup resistors (4.7 kΩ) serve the entire I2C bus.

Battery

302035 LiPo, 3.7V nominal, 200 mAh, JST-PH 2 mm 2-pin. Dimensions 36×20×3 mm. Includes onboard protection PCB (OVP, overdischarge, short circuit). Charge current 100 mA (0.5C).

Battery voltage monitored via 1 MΩ/1 MΩ resistor divider to nRF52840 AIN pin for on-screen battery percentage.


Power budget

Design target: low enough average current draw to sustain multi-hour gym sessions on a 200 mAh cell.

Active current draw (during rep counting)

ComponentCurrentNotes
nRF52840 (active, no BLE)~5 mACortex-M4 running EKF + display update
LSM6DSV IMU~0.35 mA3.3V estimated from 0.65 mA at 1.8V
OLED display~20 mATypical for 128×32 at moderate brightness
PMIC quiescent~0.05 mABQ24074 Iq
Resistor divider~0.002 mA2.1 µA, negligible
Total active~25.4 mA

Sleep current (between sets / idle)

ComponentCurrentNotes
nRF52840 (System ON, wake on RTC)1.5 µANordic spec, no RAM retention
LSM6DSV (low power accel only)~25 µAMotion detection active, waiting for INT1
OLED display (off)~5 µAController standby
Total sleep~32 µA

Runtime estimate

Assuming a typical 1-hour gym session: 20 minutes active (rep counting) + 40 minutes rest (sleep between sets):

text
Active:  20 min × 25.4 mA  = 508 mAh-min
Sleep:   40 min × 0.032 mA = 1.28 mAh-min
Total:   509 mAh-min / 60  = ~8.5 mAh per session

On a 200 mAh cell (usable ~160 mAh accounting for LDO dropout margin):

text
160 mAh / 8.5 mAh per session ≈ ~18 full gym sessions per charge

For all-day wear with occasional active periods, sleep current dominates — 32 µA into 200 mAh gives over 250 days of idle standby. In practice charge weekly.

Battery monitoring

Resistor divider (1 MΩ / 1 MΩ) scales VBAT to half voltage at the ADC pin:

Battery stateVBATAIN voltage12-bit ADC count
Full4.20 V2.10 V2606
75%3.90 V1.95 V2420
50%3.70 V1.85 V2296
25%3.50 V1.75 V2172
Low3.20 V1.60 V1986

Firmware reverse calculation: VBAT = ADC_count × 6.6 / 4096

Divider quiescent drain: 2.1 µA — equivalent to 5.4 years of drain on this cell. Negligible.


Firmware architecture

Sensing pipeline

text
IMU (6-axis raw) → EKF sensor fusion → orientation estimate
                                              │
                                    rep detection algorithm
                                              │
                                    exercise classifier (heuristic v1)
                                              │
                                       display update

Extended Kalman Filter (EKF)

Raw accelerometer and gyroscope data are fused using an EKF:

  • Prediction step: gyroscope data integrates orientation forward in time — fast but drifts
  • Correction step: accelerometer gravity vector corrects the drift — slow but absolute
  • Output: clean, drift-free quaternion orientation estimate

On a wrist-mounted IMU, gravity rotates in the body frame throughout each rep. This rotation is both the challenge (it confounds raw accelerometer rep detection) and the signal (it gives the EKF its correction input). The EKF output removes gravity ambiguity and produces a clean tilt signal that reps appear as clear periodic waves in.

The nRF52840 Cortex-M4F with hardware floating point handles EKF math at >500 Hz comfortably.

Rep detection

Per rep, the following features are extracted from the EKF orientation output:

  • Dominant motion axis (principal direction of angular change)
  • Range of motion in degrees
  • Rep duration
  • Peak angular velocity
  • Zero-crossing frequency

v1 — Heuristic classifier: if/else rules on extracted features. Fast, interpretable, no training data required. Handles 5–8 distinct exercises reliably.

v2 — TinyML: TensorFlow Lite Micro CNN/MLP on rep window. Better generalisation across users and subtle exercise variations. Planned once v1 heuristics are validated.

Exercise detection logic

Each exercise has a distinct wrist motion signature:

ExercisePrimary axisMotion signature
Bicep curlPitch (wrist rotates forward)Large pitch swing, ~120° ROM, 1–2 s period
Shoulder pressVertical translation dominantHigh Z accel, moderate pitch, pressing pattern
Bench pressElbow extension dominantModerate pitch, low ROM, bilateral pattern
Lateral raiseRoll (arm lifts sideways)Large roll swing, ~90° ROM
SquatBody pitch with knee flexionSlow deep pitch oscillation, ~3–4 s
DeadliftHip hinge dominantLarge pitch, high peak accel on concentric
Overhead pressSimilar to shoulder pressHigher ROM, full elbow extension signature

The classifier reads the dominant axis, ROM range, and rep cadence. Most exercises are distinct enough that a threshold-based decision tree separates them reliably. Exercises with similar signatures (shoulder press vs overhead press) are disambiguated by ROM magnitude.

Wake-on-motion

IMU INT1 configured as motion-detect interrupt → nRF52840 GPIO wakeup. MCU stays in System ON sleep (1.5 µA) until motion above threshold detected. Eliminates polling entirely.


PCB

  • Form factor: circular, 42 mm diameter
  • Layers: 2
  • Manufacturer: JLCPCB (fabrication + assembly)
  • Assembly: JLCPCB SMT — nRF52840 QFN73, BQ24074 QFN16, LSM6DSV LGA14 all assembled
  • Programming interface: Tag-Connect TC2030-IDC-NL pads (no legs, flush with PCB surface)
  • Reset: SMD momentary button, RESET pin → GND, 10 kΩ pullup, 100 nF filter cap
  • Antenna: unpopulated in v1 (BLE not enabled). RF matching network footprints retained DNP for v2 population without board respin
  • Crystal: 32 MHz SMD2016 (YXC X2016 32MKB4SI, LCSC C718072) mandatory main clock. 32.768 kHz RTC crystal footprint DNP for v2

Estimated unit cost

Based on JLCPCB pricing at low volume (5 units):

ItemEst. cost (USD)
PCB fabrication (5× circular 42 mm, 2-layer)~$2.00/unit
nRF52840 QIAA QFN73 (LCSC C190794)~$6.50
LSM6DSVTR IMU~$3.50
BQ24074RGTR PMIC~$2.50
32 MHz crystal~$0.10
10 µH inductor (DCCH)~$0.15
Passives (caps, resistors, ESD)~$0.50
USB-C connector~$0.30
JST-PH battery connector~$0.20
OLED display module~$3.00
LiPo 302035 200 mAh~$3.00
JLCPCB SMT assembly fee (est.)~$8.00
Total per unit (5-unit run)~$29.75

Cost drops significantly at higher volumes — MCU and PMIC pricing improves at 50+ units and assembly amortises across more boards.


Feasibility validation

Before committing to the custom PCB, the full sensing pipeline was prototyped and validated on a Seeed XIAO nRF52840 Sense development board. This board uses the same nRF52840 MCU and includes an onboard LSM6DS3 IMU (predecessor to the LSM6DSV used in the final design).

Validation confirmed:

  • IMU data acquisition over I2C at the required sample rate
  • Raw accelerometer and gyroscope signal quality for rep detection
  • Wrist-mounted motion signatures are clearly periodic and distinguishable per exercise
  • nRF52840 toolchain (Adafruit nRF52 Arduino framework) workflow — compile, UF2 drag-and-drop flash, serial monitor
  • EKF algorithm correctness on real motion data before hardware commitment

The custom PCB is a direct hardware consolidation of the validated dev board pipeline — same MCU, same firmware framework, same IMU family — into a circular wearable form factor.


Repository structure

text
/firmware          nRF52840 Arduino/PlatformIO firmware
/hardware          KiCad schematic and PCB layout files
/docs              design notes, component datasheets, calculations
/data              CSV motion logs from feasibility phase
README.md

Roadmap

VersionStatusDescription
v1In progressCustom PCB, heuristic rep counter, OLED display, 5 exercises
v2PlannedBLE to iPhone, TinyML classifier, 10+ exercises, OTA firmware updates
v3FutureCustom enclosure, production-ready assembly, refined form factor

Design constraints summary

ConstraintApproach
Size42 mm circular PCB, no external LDO, all ICs QFN/LGA
Low powernRF52840 1.5 µA sleep, IMU wake-on-motion INT1, display off between updates
Low cost~$30/unit at 5 units, ~$18 at volume; single-sided JLCPCB assembly
ProgrammabilityNative USB UF2 after one-time SWD bootloader flash
Sensor accuracyEKF fusion eliminates gyro drift and gravity confusion on raw accel

Parts

59
QtyValueFootprintReferences
6100nFCapacitor_SMD:C_0402_1005MetricC2, C4, C5, C13, C21, C22
64.7uFCapacitor_SMD:C_0603_1608MetricC1, C7, C19, C20, C24, C25
4TestPoint_Pad_D1.0mmTestPoint:TestPoint_Pad_D1.0mm+3V3, +5V, GND, VBAT
3100nFCapacitor_SMD:C_0603_1608MetricC3, C9, C26
31uFCapacitor_SMD:C_0603_1608MetricC6, C15, C23
210uHInductor_SMD:L_0603_1608MetricL2, L3
212pFCapacitor_SMD:C_0402_1005MetricC17, C18
21KResistor_SMD:R_0402_1005MetricR10, R11
21MResistor_SMD:R_0402_1005MetricR4, R13
222RResistor_SMD:R_0402_1005MetricR2, R3
24K7Resistor_SMD:R_0402_1005MetricR1, R5
25K1Resistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolderR6, R7
2DLED_SMD:LED_0805_2012MetricD1, D2
2N.CCapacitor_SMD:C_0402_1005MetricC11, C14
110 uFCapacitor_SMD:C_1206_3216Metric_Pad1.33x1.80mm_HandSolderC8
1100pFCapacitor_SMD:C_0402_1005MetricC12
110KResistor_SMD:R_0402_1005MetricR9
115nHInductor_SMD:L_0402_1005MetricL1
13KResistor_SMD:R_0603_1608MetricR12
147nFCapacitor_SMD:C_0402_1005MetricC16
1820pFCapacitor_SMD:C_0402_1005MetricC10
19KResistor_SMD:R_0805_2012MetricR8
1BQ24074RGTPackage_DFN_QFN:VQFN-16-1EP_3x3mm_P0.5mm_EP1.6x1.6mmU2
1Conn_01x02_MountingPinConnector_JST:JST_PH_S2B-PH-SM4-TB_1x02-1MP_P2.00mm_HorizontalJ2
1Conn_01x04Connector:Tag-Connect_TC2030-IDC-NL_2x03_P1.27mm_VerticalJ3
1Conn_01x04Connector_PinHeader_2.54mm:PinHeader_1x04_P2.54mm_VerticalJ4
1Crystal_GND23Crystal:Crystal_SMD_2016-4Pin_2.0x1.6mmY2
1LSM6DSVTRFitnessMotionDevice:LGA14-L_2P59X3P1X0P5_STMU7
1USBLC6-2SC6Package_TO_SOT_SMD:SOT-23-6U3
1USB_C_Receptacle_USB2.0_16PConnector_USB:USB_C_Receptacle_HRO_TYPE-C-31-M-12J1
1nRF52840Package_DFN_QFN:Nordic_AQFN-73-1EP_7x7mm_P0.5mmU1

The 57 most common of 59 parts.

Similar boards

  • 4 layers150 × 95 mmSkysweep32 rev c, the printed circuit board in 3D

    Skysweep32 rev c

    bobberdolle1/SkySweep32

    Open-source passive multi-band RF monitoring system | 855–925 MHz, 2.4 GHz, 5.8 GHz | Rev C first prototype

    103 parts33GPL-3.0
  • 2 layers50.2 × 95.2 mmCheetoPet, the printed circuit board in 3D

    CheetoPet

    Cheet0sDelet0s/cheetoPet

    an esp32 s3 based tamagotchi

    104 parts3GPL-2.0
  • 4 layers61 × 88.9 mmStm32-battery, the printed circuit board in 3D

    Stm32-battery

    agrif/bluegrass

    an STM32 board with on-board battery charging

    117 parts2
  • 4 layers36 × 34 mmUClock ESP32C3, the printed circuit board in 3D

    UClock ESP32C3

    SirioGuy/uClock

    Powered by the ESP32-C3, μClock includes an ultra-precise real-time clock that automatically corrects itself via NTP servers, ensuring it's always perfectly on time.

    68 parts2MIT
  • 4 layers88 × 48 mmMainboard reva, the printed circuit board in 3D

    Mainboard reva

    aliaksei-lameyka/ENKU-Clock

    Open, repairable, local-first e-paper alarm clock.

    82 parts1
  • 4 layers246.5 × 95 mmViaggio, the printed circuit board in 3D

    Viaggio

    dataehora/beatconfused

    A small web studio of fast, elegant, install-free music tools. Every tool is plain HTML, CSS and vanilla JavaScript with the Web Audio API — no build step, no dependencies, no accounts, works offline after first load.

    215 parts1
  • 2 layers100 × 50 mmCustom meshtastic node, the printed circuit board in 3D

    Custom meshtastic node

    kyrg4z/custom-meshtastic-node

    Custom mesh node with an OLED and GNSS module.

    52 parts1CC-BY-SA-4.0
  • 4 layers30 × 51 mmEnv sensor b, the printed circuit board in 3D

    Env sensor b

    marcelpetrick/sensorly-unhinged

    My very first PCB: an ESP32-C6 temperature/humidity sensor prototype, exploring compact and thermally isolated layouts from one shared electrical design.

    64 parts1GPL-3.0

Questions

What parts does the FitnessMotionDevice use?

59 parts, built around the BQ24074RGTR and USBLC6-2SC6. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the FitnessMotionDevice KiCad files?

From the h2dakhil/RepSense repository on GitHub, at the commit this page was made from: the board is Hardware/PCB/FitnessMotionDevice.kicad_pcb and its schematic Hardware/PCB/FitnessMotionDevice.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the FitnessMotionDevice design in my own project?

Its repository states no licence, so its author keeps all rights: ask h2dakhil before reusing the design.