
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

IMU-based Wearable Exercise Repetition Monitor
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.
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.
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:
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.
Nordic's nRF52840 was selected because it satisfies every constraint in a single chip with no external LDO required:
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.
ST's LSM6DSV was selected for its onboard sensor fusion engine and FSM (Finite State Machine) which offload motion processing from the MCU:
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
TI's BQ24074 handles charging and system power path in a single 3×3 mm QFN:
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.
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.
Design target: low enough average current draw to sustain multi-hour gym sessions on a 200 mAh cell.
| Component | Current | Notes |
|---|---|---|
| nRF52840 (active, no BLE) | ~5 mA | Cortex-M4 running EKF + display update |
| LSM6DSV IMU | ~0.35 mA | 3.3V estimated from 0.65 mA at 1.8V |
| OLED display | ~20 mA | Typical for 128×32 at moderate brightness |
| PMIC quiescent | ~0.05 mA | BQ24074 Iq |
| Resistor divider | ~0.002 mA | 2.1 µA, negligible |
| Total active | ~25.4 mA |
| Component | Current | Notes |
|---|---|---|
| nRF52840 (System ON, wake on RTC) | 1.5 µA | Nordic spec, no RAM retention |
| LSM6DSV (low power accel only) | ~25 µA | Motion detection active, waiting for INT1 |
| OLED display (off) | ~5 µA | Controller standby |
| Total sleep | ~32 µA |
Assuming a typical 1-hour gym session: 20 minutes active (rep counting) + 40 minutes rest (sleep between sets):
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 sessionOn a 200 mAh cell (usable ~160 mAh accounting for LDO dropout margin):
160 mAh / 8.5 mAh per session ≈ ~18 full gym sessions per chargeFor 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.
Resistor divider (1 MΩ / 1 MΩ) scales VBAT to half voltage at the ADC pin:
| Battery state | VBAT | AIN voltage | 12-bit ADC count |
|---|---|---|---|
| Full | 4.20 V | 2.10 V | 2606 |
| 75% | 3.90 V | 1.95 V | 2420 |
| 50% | 3.70 V | 1.85 V | 2296 |
| 25% | 3.50 V | 1.75 V | 2172 |
| Low | 3.20 V | 1.60 V | 1986 |
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.
IMU (6-axis raw) → EKF sensor fusion → orientation estimate
│
rep detection algorithm
│
exercise classifier (heuristic v1)
│
display updateRaw accelerometer and gyroscope data are fused using an EKF:
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.
Per rep, the following features are extracted from the EKF orientation output:
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.
Each exercise has a distinct wrist motion signature:
| Exercise | Primary axis | Motion signature |
|---|---|---|
| Bicep curl | Pitch (wrist rotates forward) | Large pitch swing, ~120° ROM, 1–2 s period |
| Shoulder press | Vertical translation dominant | High Z accel, moderate pitch, pressing pattern |
| Bench press | Elbow extension dominant | Moderate pitch, low ROM, bilateral pattern |
| Lateral raise | Roll (arm lifts sideways) | Large roll swing, ~90° ROM |
| Squat | Body pitch with knee flexion | Slow deep pitch oscillation, ~3–4 s |
| Deadlift | Hip hinge dominant | Large pitch, high peak accel on concentric |
| Overhead press | Similar to shoulder press | Higher 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.
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.
Based on JLCPCB pricing at low volume (5 units):
| Item | Est. 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.
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:
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.
/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| Version | Status | Description |
|---|---|---|
| v1 | In progress | Custom PCB, heuristic rep counter, OLED display, 5 exercises |
| v2 | Planned | BLE to iPhone, TinyML classifier, 10+ exercises, OTA firmware updates |
| v3 | Future | Custom enclosure, production-ready assembly, refined form factor |
| Constraint | Approach |
|---|---|
| Size | 42 mm circular PCB, no external LDO, all ICs QFN/LGA |
| Low power | nRF52840 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 |
| Programmability | Native USB UF2 after one-time SWD bootloader flash |
| Sensor accuracy | EKF fusion eliminates gyro drift and gravity confusion on raw accel |
| Qty | Value | Footprint | References |
|---|---|---|---|
| 6 | 100nF | Capacitor_SMD:C_0402_1005Metric | C2, C4, C5, C13, C21, C22 |
| 6 | 4.7uF | Capacitor_SMD:C_0603_1608Metric | C1, C7, C19, C20, C24, C25 |
| 4 | TestPoint_Pad_D1.0mm | TestPoint:TestPoint_Pad_D1.0mm | +3V3, +5V, GND, VBAT |
| 3 | 100nF | Capacitor_SMD:C_0603_1608Metric | C3, C9, C26 |
| 3 | 1uF | Capacitor_SMD:C_0603_1608Metric | C6, C15, C23 |
| 2 | 10uH | Inductor_SMD:L_0603_1608Metric | L2, L3 |
| 2 | 12pF | Capacitor_SMD:C_0402_1005Metric | C17, C18 |
| 2 | 1K | Resistor_SMD:R_0402_1005Metric | R10, R11 |
| 2 | 1M | Resistor_SMD:R_0402_1005Metric | R4, R13 |
| 2 | 22R | Resistor_SMD:R_0402_1005Metric | R2, R3 |
| 2 | 4K7 | Resistor_SMD:R_0402_1005Metric | R1, R5 |
| 2 | 5K1 | Resistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolder | R6, R7 |
| 2 | D | LED_SMD:LED_0805_2012Metric | D1, D2 |
| 2 | N.C | Capacitor_SMD:C_0402_1005Metric | C11, C14 |
| 1 | 10 uF | Capacitor_SMD:C_1206_3216Metric_Pad1.33x1.80mm_HandSolder | C8 |
| 1 | 100pF | Capacitor_SMD:C_0402_1005Metric | C12 |
| 1 | 10K | Resistor_SMD:R_0402_1005Metric | R9 |
| 1 | 15nH | Inductor_SMD:L_0402_1005Metric | L1 |
| 1 | 3K | Resistor_SMD:R_0603_1608Metric | R12 |
| 1 | 47nF | Capacitor_SMD:C_0402_1005Metric | C16 |
| 1 | 820pF | Capacitor_SMD:C_0402_1005Metric | C10 |
| 1 | 9K | Resistor_SMD:R_0805_2012Metric | R8 |
| 1 | BQ24074RGT | Package_DFN_QFN:VQFN-16-1EP_3x3mm_P0.5mm_EP1.6x1.6mm | U2 |
| 1 | Conn_01x02_MountingPin | Connector_JST:JST_PH_S2B-PH-SM4-TB_1x02-1MP_P2.00mm_Horizontal | J2 |
| 1 | Conn_01x04 | Connector:Tag-Connect_TC2030-IDC-NL_2x03_P1.27mm_Vertical | J3 |
| 1 | Conn_01x04 | Connector_PinHeader_2.54mm:PinHeader_1x04_P2.54mm_Vertical | J4 |
| 1 | Crystal_GND23 | Crystal:Crystal_SMD_2016-4Pin_2.0x1.6mm | Y2 |
| 1 | LSM6DSVTR | FitnessMotionDevice:LGA14-L_2P59X3P1X0P5_STM | U7 |
| 1 | USBLC6-2SC6 | Package_TO_SOT_SMD:SOT-23-6 | U3 |
| 1 | USB_C_Receptacle_USB2.0_16P | Connector_USB:USB_C_Receptacle_HRO_TYPE-C-31-M-12 | J1 |
| 1 | nRF52840 | Package_DFN_QFN:Nordic_AQFN-73-1EP_7x7mm_P0.5mm | U1 |
The 57 most common of 59 parts.

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



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.

aliaksei-lameyka/ENKU-Clock
Open, repairable, local-first e-paper alarm clock.

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.

kyrg4z/custom-meshtastic-node
Custom mesh node with an OLED and GNSS module.

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.
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.
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.
Its repository states no licence, so its author keeps all rights: ask h2dakhil before reusing the design.