Skip to the content
2 layers71 × 46 mmMeshthingy, the printed circuit board in 3D

KiCad 10 · 2-layer · 71 × 46 mm · ESP32-S3 + SX1262 LoRa · USB-C · Li-Ion · hardware rev R1

Size
71 × 46 mm
Copper layers
2
Thickness
1.6 mm
Parts
96
Nets
84
Pads
353
Tracks, vias
808, 378
Pours
227
Routed
Yes
KiCad
KiCad 10.0 (file 20260206)
Created
10 Aug 2026
Updated
15 Oct 2026

Overview

Meshthingy is an open-source printed circuit board by luthfai, from the luthfai/meshthingy repository on GitHub. It is a 2-layer board of 71 × 46 mm with 96 parts on 84 nets, routed with 808 tracks and 378 vias.

It is built around the ESP32-S3-WROOM-1-N8, BME280 and TPS62046DGQR, with the AT24C32AN/HG, BQ24072RGTR and 1N4148WS among its other parts. Its parts include 24 resistors, 23 capacitors, 10 ICs, 8 diodes and 4 transistors. It belongs with the ESP32 boards of this library.

Main components

10

README

README.md

meshthingy

An off-grid LoRa mesh communicator — a pocket-sized ESP32-S3 node that sends text and GPS position over kilometres of open ground, with no cell tower, no SIM, no subscription, and no internet.

KiCad 10 · 2-layer · 71 × 46 mm · ESP32-S3 + SX1262 LoRa · USB-C · Li-Ion · hardware rev R1

meshthingy board, front view

[!WARNING] Rev R1 is currently in fabrication — nothing here has been tested yet. The schematic and layout are finished and pass DRC, but no board has been assembled or powered up. Everything in this README (pin map, charger settings, power latch behaviour, assembly notes) describes the design as intended and may change after bring-up. Build one at your own risk.

Project status

StageStatus
Schematic✅ Done
PCB layout✅ Done — 0 DRC violations, 0 unconnected items
BOM✅ Done — a few part variants still to pick (see Bill of materials)
PCB fabrication⏳ In progress
Assembly⬜ Not started
Bring-up and testing⬜ Not started
Firmware🚧 Work in progress

What this board is for

Phones stop working the moment you leave coverage. meshthingy doesn't need coverage — it is the network.

Each board is one node in a self-healing Meshtastic mesh. Nodes talk directly to each other over licence-free LoRa radio, and every node automatically relays traffic for its neighbours. Two units give you a private long-range walkie-talkie for text; a handful scattered across a valley, a campsite, a ridgeline, or a city block give everyone in that area a shared messaging network that keeps working when nothing else does.

Because LoRa trades bandwidth for range and power, a node runs for days on a small Li-Ion cell and reaches several kilometres line-of-sight — far past Wi-Fi or Bluetooth, and without the power budget a cellular radio demands.

Typical uses: hiking and backcountry trips, sailing, off-road convoys, festival and event crews, neighbourhood emergency preparedness, and as a low-cost long-range telemetry link for remote sensors.

The onboard GPS, environmental and motion sensors mean a node is useful even with nobody holding it — drop one on a hilltop as a solar-powered repeater and it becomes a weather station that also extends everyone's range.

Features

  • ESP32-S3-WROOM-1 — dual-core MCU with Wi-Fi and Bluetooth LE for phone pairing, native USB
  • HT-RA62 LoRa module (SX1262) — long-range sub-GHz radio on an SMA edge-mount connector
  • ATGM336H GNSS — position reporting on a U.FL active antenna, with a rechargeable backup cell for warm starts
  • 0.96" OLED — read messages without a phone
  • BME280 — temperature, humidity, barometric pressure, on a slotted island away from board heat
  • LIS3DSH accelerometer — wake-on-motion and orientation, with interrupt to the MCU
  • USB-C charging — BQ24072 Li-Ion charger with power-path, so it runs while charging
  • Soft power switch — the lever's push turns the node on; firmware holds power and can turn itself off
  • JST-PH battery connector — standard single-cell Li-Ion / LiPo, polarity marked on the silkscreen
  • Vibration motor driver — SI2302 low-side switch with flyback diode, for silent alerts in a pocket
  • Buzzer, status LED, and a side lever switch (CW / CCW / push) for headless operation
  • Test points on every bus for bring-up and debugging

System architecture

mermaid
flowchart TB
    subgraph RF["📡 Radio"]
        LORA["<b>U4 · HT-RA62</b><br/>SX1262 LoRa"]
        SMA["J4 · SMA<br/>edge mount"]
        LORA --- SMA
    end

    subgraph CORE["🧠 Core"]
        MCU["<b>U7 · ESP32-S3-WROOM-1</b><br/>Wi-Fi · BLE · dual core"]
    end

    subgraph NAV["🛰️ Navigation"]
        GPS["<b>U2 · ATGM336H</b><br/>GNSS receiver"]
        UFL["J3 · U.FL<br/>active antenna"]
        EEP["U8 · AT24CS32<br/>EEPROM"]
        BAT2["C13 · XH414H<br/>backup cell"]
        UFL --- GPS
        GPS -->|"private I²C"| EEP
        BAT2 -.->|"keeps time"| GPS
    end

    subgraph IO["🔌 I²C peripherals"]
        OLED["U1 · 0.96in OLED"]
        BME["U9 · BME280<br/>temp · humidity · pressure"]

Power path

USB-C and the battery both feed a power-path charger, so the node keeps running while it charges and switches over seamlessly when USB is unplugged. The 3.3 V buck converter is only enabled while something holds the power latch on.

mermaid
flowchart LR
    USB["<b>J1</b><br/>USB-C<br/>5 V in"] -->|VBUS| CHG
    BATT["<b>J2</b><br/>Li-Ion cell<br/>JST-PH"] <-->|charge / discharge| CHG
    CHG["<b>U6 · BQ24072</b><br/>Li-Ion charger<br/>+ power path"] -->|VSYS| BUCK
    LATCH["<b>Power latch</b><br/>Q2 · Q3"] -->|BUCK_EN| BUCK
    BUCK["<b>U3 · TPS62046</b><br/>3.3 V step-down<br/>via L2"] -->|"+3V3"| RAIL

    BTN["Lever push"] -.-> LATCH
    PG["USB present<br/>(PGOOD)"] -.-> LATCH
    HOLD["IO9 · SYS_EN<br/>(firmware hold)"] -.-> LATCH

    RAIL["<b>+3V3 rail</b>"] --> M1["ESP32-S3"]
    RAIL --> M2["LoRa"]
    RAIL --> M3["GNSS"]
    RAIL --> M4["Sensors + OLED"]
    RAIL --> M5["Buzzer + vib motor"]

    classDef src fill:#dc2626,stroke:#991b1b,color:#fff,stroke-width:2px
    classDef conv fill:#ea580c,stroke:#c2410c,color:#fff,stroke-width:2px
    classDef rail fill:#16a34a,stroke:#15803d,color:#fff,stroke-width:2px
    classDef load fill:#475569,stroke:#334155,color:#fff
    classDef ctl fill:#64748b,stroke:#475569,color:#fff
    class USB,BATT src
    class CHG,BUCK conv

Turning on and off

The buck converter's enable is driven by a PNP switch (Q2) from a latch node that is pulled low by any one of three sources, each isolated by a 1N4148WS:

  1. Lever push (U5, D7) — pressing it powers the board up.
  2. USB present (PGOOD from U6, D4) — the node is always on while plugged in.
  3. Firmware hold (IO9 / SYS_EN through Q3) — firmware must drive IO9 high early in boot, or the board switches off again when the lever is released. Driving IO9 low (with USB unplugged) powers the node down.

The MCU can read the lever push on IO10 and USB presence on IO17 (both through diodes, active low, use internal pull-ups). The latch diodes must stay low-leakage silicon parts — Schottkys leak enough to half-enable the buck when off.

Charger settings (U6 · BQ24072)

SettingPartValue
Fast-charge currentR4 = 1k (1%)≈ 890 mA
USB input current limitR5 = 1k2, EN2 = 1 / EN1 = 0≈ 1.34 A
Safety timersR6 = 47kpre-charge ≈ 38 min, fast charge ≈ 6.3 h
TerminationTD tied lowenabled
Battery temperatureR3 = 10k fixed on TSno thermistor, sensing disabled
Charge enableIO18 (R7 pull-down)low = charging allowed

VSYS follows the battery (and tracks VBAT + 225 mV while charging). IO8 reads VSYS / 2 through R16/R17 — that is the battery voltage when running on battery.

Board

Dimensions71.0 × 46.0 mm, cut-out under the ESP32 antenna, milled slots isolating the BME280
Stackup2 layers (F.Cu / B.Cu), 1.6 mm
Components96 footprints, 353 pads (329 SMD, 22 through-hole, 2 NPTH), 378 vias
Density66% front, 9% back — almost everything lives on the front
CopperGND pour on both layers, pour cut back under the RF connectors and antennas
Design rules0.175 mm clearance, 0.2 mm minimum track, 0.6 / 0.3 mm vias
AssemblySMD on the front, 0805 passives; through-hole only for J2, the OLED header and the USB-C shell tabs

Everything routes on two layers, which keeps this a cheap board to order from any prototype fab at standard tolerances.

Assembled views

Front, populated
Front — LoRa and GNSS modules, ESP32-S3, USB-C, buzzer, GPS backup cell, motor driver
Back, populated
Back — labelled test points for every bus, vibration motor pads (JP1, silkscreen VBR), repo QR code

PCB layer views

Copper, silkscreen and board outline, plotted straight from the layout. The back view is mirrored so its silkscreen reads the right way round.

Front copper and silkscreen
F.Cu + F.SilkS — signal routing over the front ground pour; B/R are the boot and reset pads
Back copper and silkscreen
B.Cu + B.SilkS — mirrored; back pour with the test-point field and motor pads

The RF section is deliberately sparse: the pours are cut back under the antenna connectors, the ESP32's PCB antenna hangs over a board cut-out, and the GPS keepout is marked on the silkscreen so nothing gets placed under it during assembly.

Regenerate the 3D renders and layer plots after any layout change (the renders are trimmed with ImageMagick):

bash
kicad-cli pcb render --output /tmp/f.png --side top    --quality high --width 2000 --height 1300 meshthingy.kicad_pcb
kicad-cli pcb render --output /tmp/b.png --side bottom --quality high --width 2000 --height 1300 meshthingy.kicad_pcb
magick /tmp/f.png -trim +repage -bordercolor none -border 24 docs/meshthingy-f.png
magick /tmp/b.png -trim +repage -bordercolor none -border 24 docs/meshthingy-b.png

kicad-cli pcb export svg --output docs/layers-front.svg \
  --layers "F.Cu,F.SilkS,Edge.Cuts" \
  --page-size-mode 2 --exclude-drawing-sheet --check-zones --mode-single \
  meshthingy.kicad_pcb

kicad-cli pcb export svg --output docs/layers-back.svg \
  --layers "B.Cu,B.SilkS,Edge.Cuts" --mirror \
  --page-size-mode 2 --exclude-drawing-sheet --check-zones --mode-single \
  meshthingy.kicad_pcb

Pin map

FunctionESP32-S3 pinGoes to
LoRa SCKGPIO43 (TXD0)U4 pin 12 SCK
LoRa MOSIIO1U4 pin 14 MOSI
LoRa MISOIO2U4 pin 13 MISO
LoRa CSIO6U4 pin 15 NSS
LoRa DIO1IO4U4 pin 6 (IRQ)
LoRa RESETIO5U4 pin 4
LoRa BUSYGPIO44 (RXD0)U4 pin 10
GPS TX → MCU RXIO42U2 TXD
GPS RX ← MCU TXIO41U2 RXD
GPS 1PPSIO40U2 1PPS
GPS resetIO38U2 nRESET
GPS on/offIO39U2 ON/OFF
I²C SDA / SCLIO13 / IO14OLED (0x3C), BME280 (0x76), LIS3DSH (0x1D)
Accelerometer INTIO48U10 INT1
Lever pushIO10U5 push, via D6 (active low)
Lever CCW / CWIO11 / IO12U5 (active low, 100 nF debounce)
Power holdIO9Q3 via R9 — drive high to stay on
USB presentIO17U6 PGOOD via D3 (active low)
Charge enableIO18U6 CE (low = charge)
Battery senseIO8 (ADC1_CH7)VSYS / 2
Vibration motorIO15Q4 gate (10k pull-down R23)
BuzzerIO16Q1 gate (10k pull-down R11)
Status LEDIO21D2 via R22
USB D− / D+IO19 / IO20J1 (native USB)
Boot / resetIO0 / ENB / R pads
Spare / testIO7, IO47back-side test points IO07, IO47

IO3, IO35–37, IO45 and IO46 are left unconnected (strapping pins and the octal-PSRAM pins on R8 module variants).

Schematic layout

The design is hierarchical — root sheet meshthingy.kicad_sch:

SheetContents
Power ManagementBQ24072 charger, TPS62046 buck, power latch, battery sense
MicrocontrollerESP32-S3-WROOM-1, boot and reset pads
LORAHT-RA62 module and SMA antenna path
GPSATGM336H, U.FL antenna input, EEPROM, backup cell
Display0.96" OLED and its pinout-select jumpers
Air SensorsBME280
AccelerometerLIS3DSH
PeripheralsBuzzer and vibration motor drivers, status LED, test points
ConnectorsUSB-C receptacle, JST-PH battery

Bill of materials

The curated BOM is bom/meshthingy-bom.csv: 36 board lines / 76 placed parts, plus the off-board items (battery, antennas, vibration motor). It adds manufacturer part numbers where the footprint fixes the part, and a notes column with ratings and the reason behind each value.

Still to pin down before ordering parts:

  • U7 — pick the module variant (e.g. -N8R2, -N16R8). Avoid the 1.8 V …V variants: IO47 and IO48 are in use.
  • C16, C25 — voltage rating (≥ 10 V low-ESR tantalum).
  • U4 — HT-RA62-HF for 863–928 MHz, HT-RA62-LF for 433/470 MHz.

Test points and solder jumpers are left out — they are PCB features, not parts.

A print-ready A4 copy with kitting checkboxes and the open items highlighted is rendered from the CSV with python bom/render_bom_pdf.py (needs pip install weasyprint) and written to bom/meshthingy-bom.pdf. For hand assembly, open bom/ibom.html in a browser — an interactive BOM that highlights each part's position on the board.

Building it

Open meshthingy.kicad_pro in KiCad 10 or newer. All custom symbols and footprints live in libs/ and are referenced through ${KIPRJMOD}, so the project is self-contained — clone and open, nothing else to install.

Generate fabrication files from the command line:

bash
# Gerbers + drill, ready to zip and upload to a fab
kicad-cli pcb export gerbers --output fab/ meshthingy.kicad_pcb
kicad-cli pcb export drill   --output fab/ meshthingy.kicad_pcb

# Raw schematic BOM and pick-and-place
kicad-cli sch export bom       --output fab/bom-raw.csv meshthingy.kicad_sch
kicad-cli pcb export pos       --output fab/pos.csv meshthingy.kicad_pcb

# Design rules check
kicad-cli pcb drc --output fab/drc.rpt meshthingy.kicad_pcb

Generated outputs are gitignored — regenerate them, or attach them to a release tag.

Assembly notes

U3 (TPS62046) has a PowerPAD that must be soldered to the ground pad under it. The pad is a copper shape on the board rather than part of the footprint, so it has no paste aperture — tin it by hand, or add paste to the stencil, before reflowing U3.

JP3 and JP4 are three-way solder jumpers that select which OLED pin gets +3V3 and which gets GND, so the footprint accepts display modules with either pinout. They ship unbridged — bridge them to match the module you source before expecting the display to light up. Never bridge all three pads of one jumper.

JP1 on the back (silkscreen VBR) is not a jumper. It's the pair of solder pads for the vibration motor. Solder a coin or pager-style motor's leads across it: the pad on the +3V3 side takes the red lead and the pad on the Q4 drain side takes the black lead. D9 clamps the motor's flyback, so the motor runs straight off the +3V3 rail.

J2 has + / − marked on both sides. JST-PH battery leads are not wired the same way by every vendor, and there is no reverse-polarity protection — check the plug before connecting a cell.

B and R on the front are the BOOT and RESET pads. To put the ESP32-S3 into the ROM bootloader, short B while you tap R.

Firmware

🚧 Work in progress. There is no firmware for this board yet — it will target Meshtastic on the ESP32-S3 once the first boards are back from the fab and brought up. Until then, the pin map above is the reference for anyone writing a variant.

Repository notes

.history/ is KiCad 10's Local History — a separate nested git repository of autosaves. It is gitignored and should stay that way. Delete it freely if you don't need the local undo history.


Meshtastic® is a registered trademark of Meshtastic LLC. This is an independent hardware design and is not affiliated with or endorsed by Meshtastic LLC.

Parts

96
QtyValueFootprintReferences
10100nCapacitor_SMD:C_0805_2012MetricC1, C7, C8, C10, C11, C19, C21, C22, C23, C24
810kResistor_SMD:R_0805_2012MetricR3, R7, R8, R9, R11, R19, R20, R23
510uCapacitor_SMD:C_0805_2012MetricC2, C9, C14, C18, C20
51N4148WSDiode_SMD:D_SOD-323D1, D3, D4, D6, D7
4100kResistor_SMD:R_0805_2012MetricR15, R16, R17, R18
44k7Resistor_SMD:R_0805_2012MetricR10, R12, R13, R21
4LOGOLOGOG***, G***, G***, G***
31kResistor_SMD:R_0805_2012MetricR4, R22, R24
31uCapacitor_SMD:C_0805_2012MetricC4, C6, C17
21N5819WSDiode_SMD:D_SOD-323D5, D9
222uCapacitor_Tantalum_SMD:CP_EIA-3528-15_AVX-HC16, C25
247kResistor_SMD:R_0805_2012MetricR6, R14
24u7Capacitor_SMD:C_0805_2012MetricC3, C5
25k1Resistor_SMD:R_0805_2012MetricR1, R2
2EN1Jumper:SolderJumper-3_P1.3mm_Open_Pad1.0x1.5mmJP3, JP4
2GNDTestPoint:TestPoint_Pad_1.0x1.0mmG1, G2
2SI2302Package_TO_SOT_SMD:SOT-23Q1, Q4
11k2Resistor_SMD:R_0805_2012MetricR5
13V3TestPoint:TestPoint_Pad_1.0x1.0mm3V3
147nHInductor_SMD:L_0402_1005MetricL1
16.8uHInductor_SMD:L_Changjiang_FNR6045SL2
1AT24C32APackage_SO:TSSOP-8_4.4x3mm_P0.65mmU8
1ATGM336HATGM336H-5N71:ATGM336H-5NU2
1BATT_ConConnector_JST:JST_PH_S2B-PH-K_1x02_P2.00mm_HorizontalJ2
1BME280Package_LGA:Bosch_LGA-8_2.5x2.5mm_P0.65mm_ClockwisePinNumberingU9
1BQ24072RGTPackage_DFN_QFN:VQFN-16-1EP_3x3mm_P0.5mm_EP1.6x1.6mmU6
1BootJumper:SolderJumper-2_P1.3mm_Open_Pad1.0x1.5mmBOOT1
1Buzzer 8.5x8.5x3SMT_0927_S_14_R:XDCR_SMT-0927-S-14-RLS1
1CLKTestPoint:TestPoint_Pad_1.0x1.0mmCLK1
1Conn_CoaxialConnector_Coaxial:U.FL_Hirose_U.FL-R-SMT-1_VerticalJ3
1ESP32-S3-WROOM-1RF_Module:ESP32-S3-WROOM-1U7
1HT-RA62RF_Module:Ai-Thinker-Ra-01-LoRaU4
1IO15TestPoint:TestPoint_Pad_1.0x1.0mmIO07
1IO47TestPoint:TestPoint_Pad_1.0x1.0mmIO47
1LEDLED_SMD:LED_0805_2012MetricD2
1LIS3DSHTRLIS3DSHTR:LGA16R50P5X3_300X300X100NU10
1MISOTestPoint:TestPoint_Pad_1.0x1.0mmMISO1
1MMBT3904Package_TO_SOT_SMD:SOT-23Q3
1MMBT3906Package_TO_SOT_SMD:SOT-23Q2
1MOSITestPoint:TestPoint_Pad_1.0x1.0mmMOSI1
1OLED096DM-OLED096-636:MODULE_DM-OLED096-636U1
1ResetJumper:SolderJumper-2_P1.3mm_Open_Pad1.0x1.5mmRST1
1SCLTestPoint:TestPoint_Pad_1.0x1.0mmSLC1
1SDATestPoint:TestPoint_Pad_1.0x1.0mmSDA1
1SMA_ConConnector_Coaxial:SMA_Amphenol_132289_EdgeMountJ4
1TMHU26TMHU-27:tmhu26U5
1TPS62046DGQRTPS62046DGQR:DGQ10_1P88X1P57U3
1USB_C_16PConnector_USB:USB_C_Receptacle_G-Switch_GT-USB-7010ASVJ1
1VSTestPoint:TestPoint_Pad_1.0x1.0mmVS1
1Vib_Motor_ConnJumper:SolderJumper-2_P1.3mm_Open_Pad1.0x1.5mmJP1
1XH414H-IV01EXH414H-IV01E:CAP_XH414H-IV01EC13

Similar boards

  • 2 layers144.9 × 59.8 mmMonkeys, the printed circuit board in 3D

    Monkeys

    PacketChat/MonkeyBadge

    This repository contains the hardware design files, badge code, and backend infrastructure code for the HushCon Winter 2023 badge.

    153 parts21
  • 2 layers50 × 110 mmBasari, the printed circuit board in 3D

    Basari

    lennartquerter/euro-rack-synth

    Lenimal Github for DIY for a Eurorack Synth

    99 parts13
  • 4 layers60 × 60 mmRocket payload, the printed circuit board in 3D

    Rocket payload

    Gupatron/Gupsfirstpcb

    This is the first pcb that I will manufacture and intend to use for teleop usecases in my personal projects.

    138 parts
  • 2 layers90.2 × 128.5 mmVintage Dual VCA v1.0, the printed circuit board in 3D

    Vintage Dual VCA v1.0

    StudioKAT/VintageDualVCA

    If nothing is patched into OUT1, the signal from CH1 is automatically mixed into OUT2.

    113 parts7
  • 2 layers90.2 × 128.5 mmBBO&VCA v1.0, the printed circuit board in 3D

    BBO&VCA v1.0

    StudioKAT/BBO-VCA

    In this oscillator, increasing the Bounce raises the frequency. Narrowing the Bounds further increases the frequency but reduces the amplitude.

    124 parts6
  • 2 layers34 × 88.1 mmHM2-rounded, the printed circuit board in 3D

    HM2-rounded

    kingovchouffe/HM2

    95 parts
  • 2 layers61.1 × 52.3 mmStack lights, the printed circuit board in 3D

    Stack lights

    tpcarlson/synth-diy

    Mostly Eurorack projects

    33 parts107

Questions

How big is the Meshthingy PCB?

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

What parts does the Meshthingy use?

96 parts, built around the ESP32-S3-WROOM-1-N8, BME280, TPS62046DGQR and AT24C32AN/HG. 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 Meshthingy KiCad files?

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

Can I use the Meshthingy design in my own project?

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