Skip to the content
PCBKitNew board
2 layers72 × 46 mmGpsspeed, the printed circuit board in 3D

Open-source GPS replacement for the PerfectPass paddlewheel speed sensor (ESP32-C3 + GPS board, firmware, research). Built for a 2008 MasterCraft X2.

Size
72 × 46 mm
Copper layers
2
Thickness
1.6 mm
Parts
67
Nets
39
Pads
240
Tracks, vias
506, 244
Pours
3
Routed
Yes
KiCad
KiCad 10.0 (file 20260206)
Created
8 Oct 2026
Updated
8 Oct 2026

Overview

Gpsspeed is an open-source printed circuit board by bocaj88, from the bocaj88/gpsspeed repository on GitHub, published under the MIT licence. It is a 2-layer board of 72 × 46 mm with 67 parts on 39 nets, routed with 506 tracks and 244 vias.

It is built around the ATGM336H-5N31, ESP32-C3-MINI-1-H4 and USBLC6-2SC6. Its parts include 18 resistors, 16 capacitors, 8 diodes, 4 ICs and 3 connectors. It belongs with the radio and wireless boards and the ESP32 and RISC-V boards of this library.

Main components

3

README

pcb/README.md

GPSSpeed v4 — ESP32-C3 board

GPS → paddlewheel pulse emulator for PerfectPass, rebuilt as a JLCPCB-assembled board. Replaces the Uno + perfboard hat.

Size72 × 46 mm, 2 layers, 1.6 mm, 4× M3 holes
Power12/24 V DC nominal, 32 V continuous max. 60 V polyfuse → 1.5 kW bidirectional TVS (±58 V clamp) → 100 V reverse-polarity Schottky → 22 µF/100 V bulk + 4 × 2.2 µF/100 V → LMR38010 buck (80 V operating, 85 V abs max). USB-C on the bench.
BrainESP32-C3-MINI-1-H4 (WiFi boot window, OTA updates; 105 °C part)
GPSATGM336H-5N31 (GPS+BeiDou, 10 Hz), u.FL for the existing active antenna
OutputZXMS6004FF self-protected low-side switch (60 V, current limit, thermal shutdown, active clamp) behind a series Schottky (swapped +12 V/GND can't back-drive the dash), 33 V TVS on the drain; survives SIGNAL wired to +12 V; optional pull-up to the input rail via JP1 (ships open)
ConnectorJ1 screw terminal: 1 = +12 V, 2 = GND, 3 = SIGNAL (wires enter from the board edge)
LEDsPWR (red), GPS (green), WIFI (green)

top

Rev 1.3 — third EE review (independent)

Review itemChange
Stop-ship: SIGNAL wired to +12 V shorts the supply through D5 and a bare 2N7002K the first time Q1 turns onQ1 → ZXMS6004FF IntelliFET: current limit 0.7–1.7 A, thermal shutdown with auto-restart, short-circuit protected to VDS 36 V. Specified for 3.3 V logic (VIH 3 V, 0.6 Ω max at 3 V)
D4 (53 V max clamp) vs Q1 (60 V) margin thinQ1's own active clamp is 60–70 V / 90 mJ, so a spike past D4 is absorbed by design instead of avalanching a bare MOSFET
(follows from the above)SIGNAL_OUT / SIGNAL_DRAIN routed at 0.5 mm for the 1.7 A fault current

Bench items from that review (not schematic errors): output-low level with D5 in series against the real PerfectPass input; USB-only startup at ~4.6 V into the buck. JP1 stays open on 24 V boats. Q1 switching: ~15 µs on / ~60 µs off. Constant edge delays leave the output frequency unchanged; duty shifts by ~1 % at 60 MPH.

Rev 1.2 — second EE review (reviewed the native KiCad files)

Review itemChange
C16 only 63 V against a 58 V clamp22 µF / 100 V, same series and 6.3 × 7.7 can (RV100V22M6X8)
Battery-sense pin reaches 3.6 V at the clampR1 150k → 220k (×23): 32 V reads 1.4 V, the 58 V clamp 2.5 V. Firmware 4.0.2
Input ceramics borderline after DC-bias derating4th 2.2 µF / 100 V (C17)
24 V pull-up would forward-bias D5 and make D4 clamp continuouslyQ1 → 2N7002K 60 V, D4 → SMF33A (33 V standoff, 53 V clamp < 60 V)
Buck exposed pad: one full paste opening, no thermal pathPaste split into 4 windows (60 %); 2 tented GND vias just past the GND-pin end of the pad; pad tied solid into the pour
(found while re-checking)Two u.FL stitching vias overlapped fanout vias (drill-to-drill). Fanout now avoids existing vias, and drill spacing fails the build

Not changed: L1 stays where it is (SW node ~8.7 mm total; moving it means relocating D2 in the packed input corner — the reviewer rated it optional for prototypes). D2 stays an SS310: it has to block up to ~53 V when USB and boat power are both connected, and USB power is bench-only.

Rev 1.1 — changes from the external EE review

Review itemChange
"12–24 V" label wrong (old TVS conducted ~20 V)Input re-rated; silk now reads 12/24V DC 32V MAX
TVS + PTC too close to the AP63203's 35 V abs maxBuck → LMR38010 (80 V / 85 V abs), TVS → SMCJ36CA 1.5 kW bidirectional, PTC → 60 V, D1/D2 → SS310 100 V, input ceramics → 100 V, + 47 µF/63 V bulk
L2's 1.2 GHz SRF below GPS L1L2 → Murata LQW18AN27NG wirewound, SRF 3.7 GHz
SIGNAL back-drive on reverse wiringD5 SS310 in series at J1 pin 3 (chosen over a resistor so a stiff head-unit pull-up can't break the low level; adds ~0.3 V)
Open via-in-pad under the ESP32Removed; also stripped 4 open vias JLC's footprint put in the buck's exposed pad
Buck loop / u.FL groundingHand-routed C3–VIN–GND loop (~2 mm), SW straight into L1, FB on the quiet side; 8 stitching vias around the u.FL

Not changed (reviewed and accepted): USB diode-OR (verify startup during WiFi TX on the bench), reboot on very deep crank dips (firmware ignores brownouts for rollback), SMF15A on the drain (24.4 V clamp < Q1's 30 V).

Potting: keep resin off the ESP32 antenna end (top edge) — resin detunes the PCB antenna. Leave an air pocket there, or pot only the lower two-thirds of the board.

What fixes the old problems

  • 21 MPH cliff: gone. The square wave comes from the LEDC hardware peripheral off the 40 MHz crystal; no software can stretch it. Measured on the real firmware code: worst frequency error 0.02 % across 1–60 MPH (the Uno drifted up to 2.5 % fast at 30 MPH from its 128 µs rounding).
  • One serial port: the GPS has its own hardware UART; USB-C serial is always free.
  • Tuning at the dock with a laptop: everything is edited from your phone.

Files

text
pcb/
  gpsspeed.kicad_pro / .kicad_sch / .kicad_pcb   open in KiCad 10
  gpsspeed.kicad_dru      two scoped DRC exceptions (explained inside)
  lib/                    exact JLC footprints/symbols/3D (easyeda2kicad)
  gen/                    the generators -- design.py is the netlist source of truth
  out/jlcpcb/             gerbers.zip, bom_jlcpcb.csv, cpl_jlcpcb.csv   <- upload these
  out/                    schematic PDF, assembly PDF, STEP, renders
firmware/gpsspeed_v4/     ESP32-C3 firmware; bin/ has prebuilt images
firmware/test/            host-side tests of the pulse + calibration code

Ordering at JLCPCB

  1. PCB: upload out/jlcpcb/gerbers.zip. Defaults are right: 2 layers, 1.6 mm, HASL lead-free, green. Qty 5 (the minimum).
  2. PCB Assembly: on, Standard, Top side, qty 5. (Economic won't take the ESP32 module -- JLC flags every ESP32-C3-MINI-1 "Standard PCBA only".)
  3. Upload bom_jlcpcb.csv and cpl_jlcpcb.csv.
  4. In the parts review, every line should match an LCSC number. J1 (screw terminal) is through-hole; if Economic won't place it, untick it and solder its 3 pins by hand.
  5. In the placement preview, check polarity/pin-1 on: D1–D5, C16 (+), LED1–3, U1–U4, Q1, J2, J3. Footprints came from JLC's own library, so rotations should already match, but this is the one step a human should eyeball.

Rev 1.1 quote (2026-09-26), for reference: 5 assembled boards $162.84, + UPS ~$37 + US customs duty ~$61 (JLC collects it up front with DDP shipping) − $10 coupon ≈ $251.

Bring-up

  1. Before power: meter +12 V to GND on J1 — must not beep.
  2. USB-C only first. PWR LED on, TP2 = 3.3 V.
  3. Flash once over USB-C:
    text
    esptool.py --chip esp32c3 write_flash 0x0 firmware/gpsspeed_v4/bin/gpsspeed_v4-4.0.8-usb-full.bin
    (or arduino-cli upload — build command is in gpsspeed_v4.ino). If it won't connect, hold BOOT, tap RST, release BOOT.
  4. Serial monitor at 115200: expect chars: climbing and ant:OK once the antenna is on. ant:OPEN = antenna not connected / passive; ant:SHORT = cable fault.
  5. Plug in the antenna, go outside, wait for the GPS LED to go solid.
  6. Then wire the boat: +12 V, GND, SIGNAL to the paddlewheel signal line.

Using it on the boat

  • Power on → join WiFi GPSSpeed-XXXX (open, no password; XXXX is fixed per board) → the page pops up, tap Done → later just open http://gpsspeed.local (Safari; a captive-portal sheet may open on its own).
  • The access point lives 2 minutes after power-on, extends while your phone is connected, then turns the radio off. To get back in: cycle power.
  • Calibrate once: tap Self-test, and at each step type what the dash shows into Dash shows → Save point. One pass gets the dash within ~0.01 MPH at the calibrated speeds (tested against a simulated nonlinear dash).
  • While GPS is searching the output holds a steady 5 MPH (never sweeps).
  • Firmware updates: Firmware → Upload the -ota.bin. A bad build that crash-loops rolls back to the previous one automatically; brownouts from engine cranking do not count as crashes.

Things I could not verify without hardware

  • CASIC config commands ($PCAS01/02/03) follow ZhongKe's documented format. If the module ignores one, the firmware still works at its defaults (9600 baud, 1 Hz) — the web UI shows the actual baud/rate it achieved.
  • Default Hz/MPH is 4.42, the Uno's effective constant at 15–26 MPH. Expect to run the self-test once.
  • Active antenna assumed (GT-U7 kits ship with one). For a passive antenna, remove L2.
  • Wiring polarity: the board survives +12 V/GND swapped (D5 keeps the swap from back-driving the dash input) and SIGNAL wired to +12 V (Q1 current-limits and thermal-cycles). Still meter it before powering.
  • JP1 on 24 V boats: leave it open. Bridged at 28.8 V, R15 (0603) runs near its 0.1 W rating; the dash's own pull-up is the normal case anyway.

Regenerating

text
cd pcb/gen
~/Applications/KiCad/KiCad.app/Contents/Frameworks/Python.framework/Versions/3.9/bin/python3 gen_sch.py
~/Applications/KiCad/KiCad.app/Contents/Frameworks/Python.framework/Versions/3.9/bin/python3 build.py   # place, route, pour, DRC
python3 gen_outputs.py                                                                                  # JLC files

build.py needs Freerouting (~/Applications/freerouting) and Java ≥ 25 (brew install openjdk). Edit design.py for circuit changes, gen_pcb.py for placement.

Parts

67
QtyValueFootprintReferences
610kgpsspeed:R0603R2, R5, R6, R7, R8, R12
4100nFgpsspeed:C0603C4, C7, C9, C12
42.2uF 100Vgpsspeed:C1206C1, C2, C14, C17
4M3MountingHole:MountingHole_3.2mm_M3H1, H2, H3, H4
3100Rgpsspeed:R0603R10, R11, R13
322uFgpsspeed:C0805C5, C6, C15
210uFgpsspeed:C0805C8, C11
25.1kgpsspeed:R0603R3, R4
1100kgpsspeed:R0603R14
1100nF 100Vgpsspeed:C0805C3
112V / GND / SIGgpsspeed:CONN-TH_3P-P5.00_KF301-5.0-3PJ1
115uH 2.2Agpsspeed:IND-SMD_L5.0-W5.0L1
11kgpsspeed:R0603R9
11uFgpsspeed:C0603C10
120kgpsspeed:R0603R18
1220kgpsspeed:R0603R1
122uF 100Vgpsspeed:CAP-SMD_BD6.3-L6.6-W6.6-LS7.4-FDC16
127nH LQW18ANgpsspeed:IND-SMD_L1.6-W0.8-1L2
13V3TestPoint:TestPoint_Pad_D1.5mmTP2
14.7kgpsspeed:R0603R15
147kgpsspeed:R0603R17
1500mA PTC 60Vgpsspeed:F1812F1
151kgpsspeed:R0603R16
1600R@100MHzgpsspeed:L0603FB1
1ATGM336H-5N31gpsspeed:GPSM-SMD_ATGM336H-TRU3
1BOOTgpsspeed:SW-SMD_4P-L5.1-W5.1-P3.70-LS6.5-TL_H1.5SW2
1ESP32-C3-MINI-1-H4gpsspeed:WIFIM-SMD_ESP32-C3-MINI-1U2
1GNDTestPoint:TestPoint_Pad_D1.5mmTP1
1GPS FIX greengpsspeed:LED0603-RDLED2
1GPS_TXTestPoint:TestPoint_Pad_D1.5mmTP4
1IO6TestPoint:TestPoint_Pad_D1.5mmTP5
1IO7TestPoint:TestPoint_Pad_D1.5mmTP6
1LMR38010SDDARgpsspeed:SOIC-8_L4.9-W3.9-P1.27-LS6.0-BL-EP-1U1
1PULLUP (open)Jumper:SolderJumper-2_P1.3mm_Open_RoundedPad1.0x1.5mmJP1
1PULSETestPoint:TestPoint_Pad_D1.5mmTP3
1PWR redgpsspeed:LED-SMD_L1.6-W0.8-R-RDLED1
1RESETgpsspeed:SW-SMD_4P-L5.1-W5.1-P3.70-LS6.5-TL_H1.5SW1
1SMCJ36CA 1.5kWgpsspeed:SMC_L6.9-W5.9-LS7.9-BID3
1SMF33A TVSgpsspeed:SOD-123FL_L2.7-W1.8-LS3.8-RDD4
1SS310 USB ORgpsspeed:SMA_L4.3-W2.6-LS5.0-FDD2
1SS310 rev-polgpsspeed:SMA_L4.3-W2.6-LS5.0-FDD1
1SS310 sig blockgpsspeed:SMA_L4.3-W2.6-LS5.0-FDD5
1USB-Cgpsspeed:USB-C-SMD_TYPE-C-16PIN-2MD-073J3
1USBLC6-2SC6gpsspeed:SOT-23-6_L2.9-W1.6-P0.95-LS2.8-BLU4
1WIFI greengpsspeed:LED0603-RDLED3
1ZXMS6004FF 60V protgpsspeed:SOT-23-3_L2.9-W1.6-P1.90-LS2.8-BRQ1
1u.FL GPS ANTgpsspeed:RF-SMD_FRF05002-JSS103MJ2

Questions

How big is the Gpsspeed PCB?

It measures 72 × 46 mm and has 2 copper layers, 1.6 mm thick.

What parts does the Gpsspeed use?

67 parts, built around the ATGM336H-5N31, ESP32-C3-MINI-1-H4 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 Gpsspeed KiCad files?

From the bocaj88/gpsspeed repository on GitHub, at the commit this page was made from: the board is pcb/gpsspeed.kicad_pcb and its schematic pcb/gpsspeed.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Gpsspeed design in my own project?

Its repository publishes it under the MIT licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).

Similar boards

  • 2 layers43 × 23 mmAmbilight, the printed circuit board in 3D

    Ambilight

    Laxen/ambilight

    Ambilight driver based on ESP32

    33 parts
  • 2 layers86 × 54 mmELECA, the printed circuit board in 3D

    ELECA

    lightcafe-lab/ELECA

    Business card style Arduino compatible board

    71 parts1CC-BY-SA-4.0
  • 2 layers42 × 42 mmOpenJoint V0.1, the printed circuit board in 3D

    OpenJoint V0.1

    Shrijal2410/OpenJoint

    OpenJoint by Shrijal is licensed under CC BY-NC-SA 4.0

    43 parts
  • 2 layers31.2 × 52.3 mmGroundMonitor, the printed circuit board in 3D

    GroundMonitor

    crnicholson/Plant-Monitor

    Plant Monitor is a way to view data from a remote humidity sensor on web interface, which then tells you when you need to water your plants plus the air humidity, soil humidity, air temp, and air pressure.

    26 parts2
  • 2 layers96 × 50 mmPager, the printed circuit board in 3D

    Pager

    justinlindh/bramble

    Privacy-first LoRa mesh networking for ESP32-S3, built with ESP-IDF

    97 parts2MIT
  • 2 layers82 × 56 mmTitan 2026 rev a, the printed circuit board in 3D

    Titan 2026 rev a

    savob/titan_2026

    TITAN Tandem Electronics System for 2026

    87 parts
  • 2 layers60 × 150 mmPhone, the printed circuit board in 3D

    Phone

    TheEinfachFelix/CampPhone

    Warum habe ich mich dagegen entschieden, das Sim Modul selber zu implementieren? Ich habe kein Chip gefunden, der günstiger als das fertige Modul war, und ein Datenblatt in Englischer Sprache hat.

    137 parts