One board that connects an ESP32 module to its sensors, its satellite modem, and an off-board solar + battery power system.
An autonomous weather probe sealed inside a Ø200 mm floating sphere. It sleeps almost all the time on a battery, wakes hourly to read sensors, and powers a satellite modem for ~48.5 s [C] a window to transmit: once a day on LAND, every 3 h on SEA. Because it sleeps for months, the electrical design is dominated by one number: the sleeping floor, ~648 µA as built [C] (board 1 read 0.73 mA at JP1 [M]; boards 2–3 are still owed, FW-30, FW-31). Two LEDs left in on purpose are nine-tenths of it: the FireBeetle's at ~500 µA [D] and the gauge breakout's at ~100 µA [C] (decided 2026-11-03). The carrier's own share is a few microamps: the LDO's 1.6 µA [D] and 0.5 µA [D] a switch. Everything hungry (GPS, modem) sits behind its own power switch.
Three copies of the board fly in probes that can never be serviced again; two more are spares, untouched since stage 0. So: five identical boards, boring and reworkable beats clever and dense.
This is the part that most needs saying up front. The solar panels, the battery pack, and the charger are three separate physical assemblies that never touch the PCB you are designing:
THERM pad, one for your board. They are separate parts on purpose
— see the note in §5.THERM pad carries a
10 kΩ NTC in parallel with 200 kΩ and blocks charging in the cold in
hardware. Ice-tested on 2026-11-01/02: charger 1 stops at about −2.3 °C,
charger 2 at about −2.0 °C, charger 3 between −0.4 and −1.0 °C, and all
three resume just above 0 °C [C]; accepted as built on 2026-11-03 (ADR 0018,
decision 3). The gate is proven by ice and the ISET pad falling to zero,
never by the charge LED: charger 1's went dark in a stop and stayed dark while charging [M].
The pad sits behind a printed solder link that is cut with a knife, which is the whole
reason this board replaced the bq25185, whose TS pin has no pad. It has no
boost, so there is nothing to tie off.BATT+ · GND. That is all. The
5 V and EN conductors this brief used to specify were deleted in September
when the modem moved onto the battery rail. No solar wiring, no cell wiring, no
charge current ever crosses the PCB. (Corollary: do not add solar
terminals or OR-ing diodes to the board — an earlier revision had them and they
were deliberately deleted; a second series diode would cost the array real
voltage.)
Functionally the carrier is four things:
BATT+ → Q1 (a P-channel MOSFET that blocks a reversed pack, added
2026-10-02) → F1 polyfuse (1.1 A hold) → MCP1700-3302E LDO
(TO-92, 1.6 µA [D] quiescent — this exact part: its Iq is the carrier's share of the
sleep budget) → JP1 jumper → 3V3 to the MCU pin rows, QW1, SOCK_BARO and SOCK_BME.VBAT
→ U3 TPS22918 → JP2 → the RockBLOCK port, gated by IO26. The
modem rail is tapped ahead of F1, because a 1.1 A polyfuse
carries real resistance and a few hundred mV at 500 mA [C] would eat the
margin against the modem's 3.0 V minimum. The pack lead has already
spent some of it before J5: the pack's T1.6A fuse is soldered inline in its +
lead, the gauge sits inline, and two JST-PH plugs join them, and a resistive fuse
dropped 0.5–1.1 V under load [M] (pack 3, 2026-11-02; five of the twenty fuses
are bad and the part is in question, FW-28). So a fuse goes in with a heat sink on
each leg, metered 0.000 on the 2k range first, and is read for 0.00 V
across it with the board drawing before the hull closes. The gauge sits on the
charger's side of the fuse, so a resistive fuse makes it read the charger, not the
cell (4.23 V over a 3.54 V cell on pack 3 [M]). Both gate lines carry
100 kΩ pull-downs so neither rail can come up during boot, reset,
or with no MCU fitted.SOCK_BME for the
BME280 breakout (decided 2026-10-02, see §10), and two Qwiic (JST-SH) connectors.All wire ports are JST-XH, top-entry, through-hole. The connector sizes double as keying; the two 3-pin sensor ports are additionally keyed by a vacant centre pin.
| Port | Type | Pin order (1→n) | Goes to |
|---|---|---|---|
| Charger | XH-5, three positions vacant | BATT+ · — · — · — · GND | bq24074 board (cable) |
| RockBLOCK | XH-5 | VBAT · GND · RX · TX · On/Off | modem (3.3 V LVTTL UART — direct, no shifter). The sleep pin is now wired: the owned units are v3.D, which takes ordinary 3.3 V logic |
| DS18B20 | XH-3 | DATA · GND · 3V3 — this order is deliberate keying, keep it | waterproof temp probe |
| NTC | XH-3, centre pin vacant | SENSE_EXC (IO13) · — · NTC_SENSE (IO39) | 10 kΩ NTC at battery pack |
| Leak | XH-3, centre pin vacant | sense · — · GND | two pads on the hull wall |
| QW1 / QW2 | JST-SH 4-pin (Qwiic), SMD | standard Qwiic | QW1 → MAX17048 fuel gauge only; QW2 → the GPS, and the second BMP581 (SparkFun SEN-20171) on the GPS's second Qwiic port: I²C1, 0x47, powered only while the GPS rail is up (decided 2026-11-03; whether it stays on that rail is FW-29). The BME280 is a header board, not Qwiic — see §10 |
| JP1 / JP2 | 2-pin 2.54 header + shunt | in-line in 3V3 / in the switched modem rail | metering + interlock (below) |
| J10 service | 1×5 male 2.54 header | VBAT · GND · 3V3 · IO0 · RST | not a cable port: meter points, and boot/reset for a seated module whose own buttons face the board (added 2026-10-02). With the BMP581 seated it cannot be reached: the breakout overhangs it by ~2.5 mm [C] to its pin tips, so rev. 4 pulls the sensor to use it; a rev. 5 would move J10 clear (FW-18, parked) |
The keying above is only as good as the table that checks it. Re-derived
2026-09-09 for the port sizes as they stand after ADR 0014; it
supersedes the residual cross-plug matrix in the rev. 3 order
spec, which was computed when J5 was a populated XH-5 and
J6 was XH-4. Both moved.
✕ can’t fit — bigger housing, smaller shroud ○ open — a contact lands on nothing ◆ passive — connects, nothing damaged ▲ damage — a part is over its rating
| Harness ↓ into port → | J5 chargerXH-5 · live 1, 5 | J6 modemXH-5 · all live | J7 NTCXH-3 · centre vacant | J8 DS18B20XH-3 · all live | J9 leakXH-3 · centre vacant |
|---|---|---|---|---|---|
| SolarXH-2 · up to ≈ 8.5 V [C] | ○ Open1 and 5 never adjacent | ▲ Damage≈ 8.5 V [C] on the modem rail, or IO16/IO17 | ○ Openone contact on the dead centre | ▲ Damage≈ 8.5 V [C] on IO4 or the 3V3 rail | ○ Openone contact on the dead centre |
| ChargerXH-5 · 3.0–4.2 V | —its own port | ◆ Passivepack onto the modem rail, which normally carries it; GND onto IO14. Unverified: the audit of 2026-10-15 asks whether U3 conducts backwards when off, returning through IO14 (FW-25, finding 16) | ✕ Can't fit5-position body | ✕ Can't fit5-position body | ✕ Can't fit5-position body |
| ModemXH-5 · 5 wires | ◆ Passivesupply wire to BATT+, On/Off to GND, the rest on vacant pins | —its own port | ✕ Can't fit5-position body | ✕ Can't fit5-position body | ✕ Can't fit5-position body |
| NTCXH-3 · contacts 1, 3 | ○ Openat most one live pin reached | ◆ Passivea 10 kΩ thermistor bridging two pins; microamps | —its own port | ◆ Passive3V3 at both ends through R3 — no static current | ◆ Passivea misread; both nets are gated dividers |
| DS18B20XH-3 · all three | ○ Openno return path through the vacant pins | ◆ Passivesensor rated to 5.5 V; the rail is 4.2 V | ◆ Passivesensor ground on the vacant pin — unpowered | —its own port | ◆ Passivesensor ground on the vacant pin — unpowered |
| LeakXH-3 · contacts 1, 3 | ○ Openat most one live pin reached | ◆ Passivetwo hull pads with no source behind them | ◆ Passivea misread; both nets are gated dividers | ◆ Passive~0 V across the pads — no electrolysis | —its own port |
J5. Sizing the
charger port closes every cross that involves it and stops the charger harness reaching
any sensor port. What it does not touch is the solar line.
Opt. Cap holes,
VBUS and GND, and its one XH-2 plug mates at the combiner board. The plan soldered the panels to the combiner,
so that a plug pulled off it carried no panel voltage and the loose housing the Solar row of the
table assumes did not exist. As built, every panel lead ends in an XH plug into a socket on
the combiner’s pad pair, on all three combiner boards — a set of three crimped
red-to-minus was caught by the sign check — so a parted panel plug is a live XH-2 at up to ≈ 8.5 V [C].
Whether the plugs stay or are soldered is open (FW-29). The thermistor lead also has a 2-pin XH break
near the charger, labelled, not keyed, since the solar lead’s XHP-2 fits it too. Either way,
do not put a connector at the charger end.
| Net | From | To | Notes |
|---|---|---|---|
VBAT | Q1 (from charger port pin 1, see the VBAT_IN row) | F1 and U3 VIN, C7, J10 pin 1 | battery voltage behind the reverse-pack MOSFET, 3.0–4.2 V. The modem rail taps here, before F1 — see §4 |
VBAT_F | F1 | MCP1700 VIN, C1 (1 µF) | fused battery rail |
3V3_RAW | MCP1700 VOUT | C2 (1 µF), C3 (10 µF), JP1.1 | |
3V3 | JP1.2 | FireBeetle 3V3 (both pins) · QW1 VCC · SOCK_BARO, SOCK_BME · R6 → DS18B20 port · TPS22918 VIN, C10 (1 µF) · J10 pin 3 | the board rail |
3V3_GPS | TPS22918 VOUT | QW2 VCC | on ~18 min/day on SEA (a fix at every hourly wake) [C], one fix a day on LAND |
GPS_EN | MCU IO25 | TPS22918 ON + R1 100k→GND | rail off at boot / MCU absent |
RB_EN | MCU IO26 | U3 ON + R2 100k→GND | modem rail must not rise in reset |
SDA0/SCL0 | MCU IO21/IO22 | QW1, SOCK_BARO, SOCK_BME | always-on I²C: BME280 0x77, MAX17048 0x36, BMP581 0x47 |
SDA1/SCL1 | MCU IO18/IO19 | QW2 only — the GPS and, on its second Qwiic port, the second BMP581 (0x47) | switched GPS bus — no series parts |
OW_DATA | MCU IO4 | R7 → DS18B20 port DATA; R3 4.7k→3V3 on the MCU side | 1-Wire |
SENSE_EXC | MCU IO13 | NTC port pin 1 · R5 100k | output; high only during reads |
NTC_SENSE | MCU IO39 | NTC port pin 3 / R4 10k→GND junction | input-only ADC1. Moved from IO34 on 2026-10-02: the FireBeetle ties IO34 to its own battery tap through a 1 MΩ divider |
LEAK_SENSE | MCU IO35 | R5 / leak port pin 1 junction + C6 100 nF→GND | input-only ADC1; C6 fixes source impedance (τ = 10 ms) |
VBAT_RB | U3 VOUT | JP2 pin 1 | switched modem rail; on ~48.5 s a window [C], eight a day on SEA (every 3 h), one on LAND |
VBAT_RB_SW | JP2 pin 2 | RockBLOCK port pin 1 | to the modem's pin 8: 3.0–5.4 V straight from the pack. No bulk capacitor — the module's own supercapacitors buffer the transmit burst and must never be removed |
RB_ONOFF | MCU IO14 | RockBLOCK port pin 5 | the modem's sleep input; v3.D takes ordinary 3.3 V logic, so the GPIO drives it directly |
RB_RX / RB_TX | MCU IO17 / IO16 | RockBLOCK port 3 / 4 | ESP32 transmits on IO17 |
VBAT → C7 | U3 VIN | C7 1 µF → GND | added 2026-10-02: the load switch's input capacitor |
VBAT_IN → Q1 → VBAT | charger port pin 1 | Q1 drain → source; gate on GND | added 2026-10-02 after the reviews: reverse-battery protection. A swapped crimp no longer puts the pack backwards across the board — the modem's feed bypasses F1, so the fuse never covered that |
GPS_CT, RB_CT | U2 pin 4, U3 pin 4 | C8, C9 4.7 nF → GND | added 2026-10-02: soft start, a few ms instead of ~0.1 ms, so a breakout's capacitors cannot drag the 3V3 rail toward the ESP32's brown-out when a rail switches on |
OW_3V3, OW_DATA_J | R6, R7 (100 Ω) | DS18B20 port pins 3 and 1 | added 2026-10-02: the one cable that carries the always-on rail into sea water; a flooded probe costs a thermometer, not the station |
FB_VCC | JP3 (solder jumper, open) | MCU VCC pin | added 2026-10-02: the fallback feed through the module's own regulator, if the undocumented back-feed into its 3V3 pins proves costly. Measured since: the module's VCC node reads 3.29 / 3.14 / 3.24 → 3.02 V on three modules [M], following the module, not the board; whether to close JP3 is open, and energy does not decide it (FW-19) |
VBAT, GND, 3V3, FB_IO0, FB_RST | The rails, then the MCU's IO0 and RST pins | J10, 1×5 service header | added 2026-10-02: the seated module's own buttons face the carrier; each rail sits beside GND so a slipped probe never bridges the pack onto 3V3 (second review round, same day) |
GND | single net, poured on both layers | the charger port's pin 5, the Qwiic shells, every ground pin | |
Spare MCU pins after this map: IO23 (bidirectional), IO36 (input-only ADC1), and IO34 only with its on-board 1 MΩ divider in mind — IO14 left the spare list when the modem's sleep pin was wired. Nothing uses ADC2 — that's deliberate (ADC2 dies when the radio is on).
VBAT → U3 → JP2 → RockBLOCK port. The 1.3 A [D] figure in
circulation is the bare 9603N module's burst; the RockBLOCK board hides it
behind its own supercapacitors and the supply never sees more than
470 mA [D] (0.45 A measured across JP2 [M]). Size the run for that and keep it short — the whole
point of tapping ahead of F1 is voltage margin, and trace
resistance spends the same margin the polyfuse would have.SOCK_BME seat, on every board. Found 2026-09-09 and
it touches your layout. The owned board is SparkFun SEN-13905,
with 0.1 in headers — not the Qwiic SEN-15440 formerly
recorded here, a different board. Nothing electrical moves — same sensor,
same 0x77, same I²C0 — but it cannot plug into QW1, which
now carries the MAX17048 alone. Either a Qwiic-to-header cable off that
chain (no board change, but it gives up the keying Qwiic was chosen for),
or a SOCK_BME female header alongside
SOCK_BARO — the same treatment the BMP581 already gets. The
socket was chosen, and it is on the fabbed board.This is how every board gets verified — worth knowing while placing parts, because it defines what must be probeable:
GPS_EN and RB_EN read 0 V
(pull-downs working).OK came at 7.0–12.0 s [M]
(12.0 s, 7.0 s, then 9.0 s on both modems outdoors) and the meter read 0.45 A for
~13 s, then 0.13 A for ~10 s [M] — the module charging its supercapacitors before
the Iridium side will do anything. The pack's low end is still unmeasured (FW-02).Part of SouthPing — southping.org. This page is licensed CC BY 4.0: reuse it, adapt it, publish it, with credit to SouthPing and a link back. Source code in the project is Apache-2.0. Manufacturers' datasheets and product photographs remain theirs and are not covered by this grant.