Skip to the content
PCBKitNew board
4 layers45 × 30 mmPmd tracker, the printed circuit board in 3D

Wearable rugby performance tracker: nRF52840 + Zephyr firmware, React Native companion app

Size
45 × 30 mm
Copper layers
4
Thickness
1.6 mm
Parts
31
Nets
82
Pads
199
Tracks, vias
340, 82
Pours
4
Routed
Yes
KiCad
KiCad 10.0 (file 20260206)
Created
9 Oct 2026
Updated
9 Oct 2026

Overview

Pmd tracker is an open-source printed circuit board by ollielarkins, from the ollielarkins/pmd-tracker repository on GitHub. It is a 4-layer board of 45 × 30 mm with 31 parts on 82 nets, routed with 340 tracks and 82 vias.

It is built around the MAX-M10S-00B, MDBT50Q-1MV2 and ADXL372BCCZ-RL7, with the AP2112K-3.3TRG1, LSM6DSO and MCP73831T-2ACI/OT-HXY among its other parts. Its parts include 12 capacitors, 7 resistors, 6 ICs, 4 connectors and 2 diodes. It belongs with the wearables boards and the nRF52 and nRF5x boards of this library.

Main components

9

README

README.md

PMD Tracker

A wearable performance tracker for rugby. It sits in a jersey pouch between the shoulder blades, records a player's match, and syncs the results to a companion app for review after the game.

PCB render, top

KiCad 3D render of the 45 x 30 mm 4-layer board (not yet fabricated).

System block diagram

What it measures

AreaMetrics
Locomotiondistance, max speed, sprint count and sprint distance
Contact loadimpact count, peak g, total load, impacts by intensity band
Positiontime-on-pitch heatmap (10 m cells), work rate in m/min

How it works

  1. Sensing. A u-blox MAX-M10S GNSS module gives position at 10 Hz. An ADXL372 high-g accelerometer (±200 g) catches impacts that a normal IMU would clip. An LSM6DSO 6-axis IMU is part of the design but is not used by the metrics yet.
  2. On-device metrics. The nRF52840 runs Zephyr RTOS. Every fix and accel sample goes through firmware/lib/metrics, which is portable C:
    • Position. Each fix is projected to metres from a pitch origin.
    • Distance. Fixes that imply more than 12 m/s are rejected as GNSS glitches. Steps under 0.3 m/s count as standing jitter and add no distance.
    • Speed and sprints. Speed is an exponential moving average. A sprint starts above 7 m/s and ends below 6 m/s. It only counts if it lasts at least 1 s.
    • Impacts. An impact starts when |a| ≥ 8 g. Samples in the next 250 ms count as the same hit, and its peak is the hit's intensity.
    • Heatmap. The time spent at each position is binned into a grid in the pitch frame.
  3. Storage. A summary checkpoint is written to flash (NVS) every 10 s, so a battery pull mid-match keeps the totals.
  4. Sync. The device advertises over Bluetooth LE as PMD. The app reads one 228-byte summary characteristic (layout in metrics.h). It writes the reset characteristic to start a new session.

Every threshold above sits in one pmd_config struct. They are starting values and still need calibrating against real sessions.

Design targets

The device is designed against World Rugby Law 4.3(m), Regulation 12 and the Player Monitoring Device Performance Specification:

  • total mass under 90 g
  • no surface radius below 12 mm
  • enclosure survives the specification's impact test and 2.5 kN compression test without rupture
PartComponent
MCUnRF52840 (BLE 5) in a Raytac MDBT50Q-1MV2 module, on a custom 4-layer PCB
GNSSu-blox MAX-M10S, 10 Hz
High-g accelADXL372
IMULSM6DSO
Battery500 mAh LiPo

The BOM is in hardware/bom.csv.

Hardware

The board is a 45 x 30 mm, 4-layer PCB designed in KiCad 10: hardware/kicad.

LayerUse
F.Cuparts, signals, GND pour
In1.Cusolid GND plane
In2.Cu3V3 plane
B.Cusignals, GND pour

Power. USB-C (5.1 kΩ CC pull-downs, so any USB-C charger works) feeds an MCP73831 charger set to about 213 mA (0.4C for the 500 mAh cell). The cell feeds an AP2112K 3.3 V LDO for everything. The GNSS module can draw up to 100 mA at start-up, more than the nRF52840's internal regulator can supply to external parts. A red LED shows charging, and a 1 MΩ / 1 MΩ divider lets firmware read the battery voltage.

RF. The module's antenna sits at the top edge, over the footprint's copper keepout. GNSS uses a passive antenna on a u.FL connector next to the MAX-M10S RF pin. The receiver has its own LNA and SAW filter.

Debug. SWD on a Tag-Connect TC2030-NL footprint, so there's no connector to fit.

SignalnRF52840 pinTo
SPI SCK / MOSI / MISOP0.13 / P0.15 / P0.17ADXL372, LSM6DSO
ADXL372 CS / INT1P0.20 / P0.24U3
LSM6DSO CS / INT1P0.22 / P1.09U4
UART TX / RXP0.06 / P0.08MAX-M10S RXD / TXD
GNSS resetP0.27MAX-M10S RESET_N
Battery senseP0.04 (AIN2)VBAT / 2
Status LEDP0.31D1
USB D+ / D-module USB pinsUSB-C

Everything is generated from one file, hardware/design.py: parts, nets, placement and track widths. hardware/build.sh then runs the pipeline:

  1. Write the schematic.
  2. Run ERC, then check the schematic netlist against design.py.
  3. Place the parts and add the planes.
  4. Autoroute with Freerouting.
  5. Run DRC, including schematic parity.
  6. Export Gerbers, drill files, the BOM and the renders.

Current results:

  • ERC: 0 violations.
  • DRC: 0 errors and 0 unconnected items. The only 2 warnings are cosmetic: the USB-C footprint's silkscreen is clipped where the receptacle sits flush with the board edge.
  • Schematic parity: 0 issues.

Freerouting gives a different result each run, so build.sh retries routing (up to 5 times) until DRC passes, and fails if it never does. The committed board is a checked run.

Off-board parts (not on the BOM):

  • a 500 mAh single-cell LiPo with a JST PH 2-pin plug
  • a passive GNSS patch antenna on a U.FL pigtail
  • a Tag-Connect TC2030-NL cable for programming

Known limits. There's no power switch: the LDO enable is tied to VBAT, and the firmware doesn't yet use System OFF or GNSS standby, so the cell drains between matches. The board hasn't been fabricated, so nothing here is RF-tested or weighed against the 90 g target.

The ADXL372 footprint isn't in the KiCad library. It's drawn from the land pattern in the ADXL372 datasheet (Rev. C, Figure 111).

Fabrication files: hardware/fab/pmd-tracker-gerbers.zip. Design rules are 0.127 mm minimum track and space with 0.6 / 0.3 mm vias, which a standard 4-layer prototype service can make.

Design images

All of these are exported straight from the KiCad project by docs/make_images.sh. The board hasn't been fabricated yet, so they're renders and plots, not photos.

Top Top renderBottom Bottom render
Iso front Isometric, frontIso back Isometric, back
Side Side profileSensors LSM6DSO + ADXL372 close-up
Power Charger + LDO close-upFootprint ADXL372 footprint (from datasheet land pattern)
F.Cu F.Cu (top copper)In1 In1.Cu (GND plane)
In2 In2.Cu (3V3 plane)B.Cu B.Cu (bottom copper)
Fab Assembly drawingBlock Block diagram

Full schematic: docs/images/08-schematic.png

Repository layout

text
firmware/
  lib/metrics/     portable C metrics + host self-test
  src/main.c       Zephyr app: sensors, GNSS, flash checkpoint, BLE service
  boards/          devicetree overlay (nRF52840-DK bring-up wiring)
hardware/
  design.py        parts, nets, placement (single source of truth)
  generate.py      writes the KiCad schematic, libraries and PCB
  build.sh         generate -> ERC -> route -> DRC -> fab outputs
  kicad/           KiCad 10 project (.kicad_sch, .kicad_pcb, custom parts)
  fab/             Gerbers + drill, zipped
  bom.csv
docs/
  block-diagram.svg
  board-top.png, board-bottom.png
  images/          15 design images (renders, schematic, layer plots)
  make_images.sh

Building

Test the metrics on a PC. Any C compiler works:

text
cd firmware/lib/metrics
cc -std=c11 -Wall test_metrics.c metrics.c -lm -o test && ./test

Build the firmware (needs Zephyr 4.x and west). The nRF52840-DK overlay is used for bring-up:

text
west build -b nrf52840dk/nrf52840 firmware
west flash

Status

  • Metrics library with a host self-test
  • Zephyr firmware: GNSS, high-g accel, flash checkpoint, BLE sync (written, not yet built against Zephyr or run on hardware)
  • PCB schematic and layout (KiCad): ERC and DRC clean, autorouted. Not yet fabricated or tested.
  • Gerbers and drill files
  • Zephyr board definition for the custom PCB. The current overlay targets the nRF52840-DK; see the pin map above.
  • Enclosure
  • Companion app

Parts

31
QtyValueFootprintReferences
7100nCapacitor_SMD:C_0402_1005MetricC5, C7, C8, C9, C10, C11, C12
210uCapacitor_SMD:C_0603_1608MetricC4, C6
21MResistor_SMD:R_0402_1005MetricR6, R7
21kResistor_SMD:R_0402_1005MetricR4, R5
24.7uCapacitor_SMD:C_0603_1608MetricC1, C2
25.1kResistor_SMD:R_0402_1005MetricR1, R2
11uCapacitor_SMD:C_0402_1005MetricC3
14.7kResistor_SMD:R_0402_1005MetricR3
1ADXL372pmd:ADI_LGA-16_3x3.25mm_P0.5mmU3
1AP2112K-3.3Package_TO_SOT_SMD:SOT-23-5U6
1GreenLED_SMD:LED_0603_1608MetricD1
1JST PH 2-pin (battery)Connector_JST:JST_PH_S2B-PH-SM4-TB_1x02-1MP_P2.00mm_HorizontalJ3
1LSM6DSOPackage_LGA:LGA-14_3x2.5mm_P0.5mm_LayoutBorder3x4yU4
1MAX-M10SRF_GPS:ublox_MAXU2
1MCP73831-2-OTPackage_TO_SOT_SMD:SOT-23-5U5
1MDBT50Q-1MV2RF_Module:Raytac_MDBT50QU1
1RedLED_SMD:LED_0603_1608MetricD2
1SWDConnector:Tag-Connect_TC2030-IDC-NL_2x03_P1.27mm_VerticalJ4
1U.FLConnector_Coaxial:U.FL_Hirose_U.FL-R-SMT-1_VerticalJ2
1USB-CConnector_USB:USB_C_Receptacle_HRO_TYPE-C-31-M-12J1

Questions

How big is the Pmd tracker PCB?

It measures 45 × 30 mm and has 4 copper layers, 1.6 mm thick.

What parts does the Pmd tracker use?

31 parts, built around the MAX-M10S-00B, MDBT50Q-1MV2, ADXL372BCCZ-RL7 and AP2112K-3.3TRG1. 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 Pmd tracker KiCad files?

From the ollielarkins/pmd-tracker repository on GitHub, at the commit this page was made from: the board is hardware/kicad/pmd-tracker.kicad_pcb and its schematic hardware/kicad/pmd-tracker.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Pmd tracker design in my own project?

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

Similar boards

  • 4 layers60 × 31 mmGarageDoor pro, the printed circuit board in 3D

    GarageDoor pro

    nikolaus018/garageDoor-pro

    ESP32-C3 + GPS board that opens the garage door when you leave and arrive: firmware, KiCad PCB and perfboard build

    46 parts1MIT
  • 2 layers60 × 45 mmTracker lite, the printed circuit board in 3D

    Tracker lite

    Sanu0910/RFMW-ANT

    109 parts
  • 2 layers142.7 × 72 mmBlinky bowtie, the printed circuit board in 3D

    Blinky bowtie

    joshajohnson/bsidescbr2021

    Slides and Design Files for BSides Canberra 2021

    101 parts5GPL-3.0
  • 4 layers54 × 63.4 mmRaceTracker v3, the printed circuit board in 3D

    RaceTracker v3

    jonaschramm/race-tracker

    Custom PCB data logger for motorcycle racing: GPS position + IMU motion data, logged to a microSD card, with an e-Paper status display. Built around an ESP32-S3 (WiFi/BT built in) so it can also stream/sync over WiFi.

    49 parts
  • 4 layers52.8 × 22.9 mmICE40-fpga, the printed circuit board in 3D

    ICE40-fpga

    kitspace-test-repos/kicad6-file-collection

    83 partsMIT
  • 4 layers46 × 86.4 mmOpenCycle, the printed circuit board in 3D

    OpenCycle

    Vishvak365/OpenCycle

    Everything is generated from design.py — do not hand-edit the board and then regenerate, you will lose the edit. If you do route by hand in KiCad, stop using the pipeline for that board and say so in docs/DECISIONS.md.

    79 parts
  • 4 layers83 × 109 mmD4 small pcb panel, the printed circuit board in 3D

    D4 small pcb panel

    unsurv/unsurv-offline

    Offline portable GNSS device based on the ESP32

    522 parts72