RTX 5090 16-pin connector thermal watchdog (Pi Pico)#

Status: Proposal (draft): designed and bench-simulated, not yet built on a node Scope: one watchdog per RTX 5090 service node (PC1, PC2, future nodes) Code: ../connector-watchdog/: Pico firmware main.py, host connector_watchdog.py, connector-watchdog.service Why: connector-melt evidence (connector melts are silent until damage is done) and the PSU decision

What it does#

A thin-film temperature sensor sits between the wires just behind the GPU-end 16-pin plug, and a second sensor stands on the board in the case air as a reference. A Raspberry Pi Pico reads both once a second and reports to the node over USB. The GPU-plug sensor drives every action:

Layer Trigger (GPU-plug sensor) Action Depends on
Rate of rise climbing ≥ RISE_C_PER_MIN (default 4 °C/min) after GPU power has been steady for 5 min stop the ComfyUI worker, nvidia-smi -pl 400, alert Linux + host service
Warn ≥ WARN_C (baseline + 10–15 °C, max 85 °C) for 10 s same as above Linux + host service
Host cut-off ≥ 95 °C for 5 s alert, systemctl poweroff Linux + host service
Hardware cut-off ≥ 100 °C for 5 s Pico holds the power switch 6 s: forced ATX off, then latches Pico only (works if Linux or the GPU driver has hung)

The host also alerts on:

It adds no connection to the power path: the sensor only touches the outside of the wire insulation.

What it can and cannot catch#

Parts (per node)#

Part Qty Notes
Raspberry Pi Pico H (RP2040) 1 "H" has headers pre-soldered. Plain Pico, not Pico W, unless you change the onboard LED pin.
GPU-plug sensor: MF5B thin-film NTC, 100K, B3950, 1%, 25 mm strip 1 (+ spares) The yellow polyimide strip; the sensing element is the dark dot at the tip. Rated −30 to 125 °C, 5 s time constant in air. It has only short bare legs: you solder leads on (below). Sold in packs of 10.
Air sensor: bare glass-bead NTC, 100K, B3950 1 (+ spares) About RM1. Stands on the board on its own legs. The legs are hair-thin; handle gently.
10 kΩ resistor, 1% metal film 2 The divider resistors. Use 10k, not 100k: see why 10k.
330 Ω resistor 1 Current limit for the optocoupler LED, about 6 mA.
PC817 optocoupler, DIP-4 (any 817 part: PC817, PS817, EL817; any gain letter A–D) 1 (+ spares) The letter is only the gain grade; every grade has far more than this circuit needs.
100 nF ceramic capacitor 2 Optional; smooths noise on the readings.
Half-size 400-point breadboard 1 For building and testing. A 170-point board is too short: the Pico needs 20 columns.
5 × 7 cm double-sided perfboard (green FR4, plated holes) 1 Optional, for the permanent version. Avoid single-sided brown boards; their pads lift easily.
2 × 20-pin female header strips (2.54 mm) 2 Perfboard only: the Pico H plugs in, so it's never soldered.
2-pin male header (2.54 mm) 1–2 For the film sensor's Dupont plug (and a spare for a future PSU-end sensor).
Female-female Dupont jumpers a few Sensor leads, and the link to the power-switch header.
2-pin front-panel "power switch" Y-splitter 1 So the case button and the Pico both drive the same header pins.
Heat-shrink assortment 1 (shared) For the film sensor's leg joints.
Kapton (polyimide) tape, 10 mm 1 roll (shared) Real polyimide, rated 260 °C or more.
Micro-USB cable, or an internal USB-2 header to micro-USB cable 1 The internal version keeps the Pico inside the case.
Soldering iron, solder, tweezers shared For the film-sensor leads (and perfboard, if used).
Multimeter 1 (shared) To find the power-switch pins and to check resistor and sensor values.
IR thermometer 1 (shared) For commissioning, the PSU-end check, and periodic checks.

Buying tips:

Why a 10k resistor with a 100k thermistor#

The Pico measures voltage, not resistance, so each thermistor is paired with a fixed resistor as a voltage divider. The divider is most precise where the thermistor's resistance is close to the fixed resistor's. These 100k thermistors fall to about 10 kΩ near 90 °C, the range we care about:

Temperature 10k fixed: voltage 10k: ADC steps per °C 100k fixed: voltage 100k: ADC steps per °C
25 °C 3.00 V 15 1.65 V 45
90 °C 1.59 V 30 0.28 V 9
110 °C 1.14 V 25 0.17 V 5

The sensor self-heats less than 0.5 °C at these currents.

Wiring#

Temperature sensors#

 Pico pin 36  3V3(OUT) ──┬─────────────┐
                         │             │
                      [10k 1%]      [10k 1%]
                         │             │
 Pico pin 31  GP26/ADC0 ─┤             ├─ Pico pin 32  GP27/ADC1
                         │             │
              (100nF)────┤             ├────(100nF)        optional, cap to AGND
                         │             │
                  [film NTC 100k]  [bead NTC 100k]
                  GPU PLUG WIRES     CASE AIR        ← film on Dupont leads; bead on the board
                         │             │
 Pico pin 33  AGND ──────┴─────────────┘

Forced power-off (PC817 across the power-switch header)#

 Pico pin 20  GP15 ──[330R]──► PC817 pin 1 (anode, dot side)
 Pico pin 18  GND  ──────────► PC817 pin 2 (cathode)

 PC817 pin 4 (collector) ──► JFP1 POWER SW  "signal" pin (the one at ~3.3–5 V to ground)
 PC817 pin 3 (emitter)   ──► JFP1 POWER SW  ground pin
                              ▲
 Case power-button leads ─────┘ same two pins, via the Y-splitter (button still works)

 PC817, top view:     1 ● ┌───┐ 4
                          │817│
                      2   └───┘ 3        pins 1–2 = Pico side, 3–4 = motherboard side

Pico pin summary#

Pico pin Function Goes to
36 3V3(OUT) top of both 10 kΩ resistors
31 GP26 / ADC0 GPU-plug divider node (film sensor)
32 GP27 / ADC1 case-air divider node (bead)
34 GP28 / ADC2 free (optional PSU-end sensor later)
33 AGND bottom of both thermistors (and both caps)
20 GP15 330 Ω → PC817 pin 1
18 GND PC817 pin 2
USB power + serial node USB (rear port or internal header)

Board layout#

Breadboard (400-point), for building and testing:

Perfboard (5 × 7 cm), the optional permanent version:

Preparing the thin-film sensor#

The MF5B strip has only short bare legs, so it needs leads. A beginner-friendly method:

  1. Take a 2-wire female-female Dupont jumper pair, 30–50 cm, and cut one end off. The remaining plug end pushes onto the 2-pin header on the board.
  2. Prepare the wire ends: strip about 3 mm, twist the strands, and tin them (melt a little solder in).
  3. Slide a small piece of heat-shrink onto each wire first, and a larger piece over both.
  4. Solder one wire to each leg with a brief touch, 2–3 seconds. Hold the leg with tweezers between the joint and the film, so the heat goes into the tweezers instead of the sensing element.
  5. Shrink the small pieces over each joint, so the two joints can't touch. Then shrink the larger piece over both joints and the base of the strip, for strain relief.
  6. Check with the multimeter: about 100 kΩ at room temperature (98–102 kΩ for the 1% part), falling when you pinch the tip.

Sensor placement#

  1. GPU-plug sensor. Slide the tip of the film strip (the dark dot) between the wires in the middle of the bundle, 5–10 mm behind the back of the plug housing, with the film flat against the wires.
    • Why the middle: the ground-return wires carry the same current as the 12 V wires and heat just as much when a contact fails, so any wire is relevant. The middle of the bundle touches the most.
    • Getting it in: open a gap gently with a plastic spudger or toothpick, without levering.
    • Leave the plug alone: no pulling, pushing or sideways force on it. Sideways force on the plug is itself a known cause of melts. If a cable comb sits right at the plug, work around it.
    • Securing it: hold the sensor with one or two loose turns of Kapton around the bundle, snug but not squeezing the wires. Tie the lead to the cable a few cm further back, so a tug lands there. The polyimide film is insulated on both sides, so touching the wires is safe.
  2. Air sensor: the bead standing on the board. Put the board in moving case air, not a dead corner and not in the path of the PSU or GPU exhaust.
  3. Mounting the board: somewhere cool and non-conductive. The breadboard has an adhesive back. Nothing on it may touch metal.

Software setup#

  1. Pico: flash MicroPython (the official RP2040 .uf2: hold BOOTSEL while plugging in USB, then drag the file onto the drive that appears). Copy main.py with mpremote cp main.py :main.py.
  2. Node: copy connector_watchdog.py to /opt/connector-watchdog/ and connector-watchdog.service to /etc/systemd/system/.
    • Set WATCHDOG_DEVICE from ls /dev/serial/by-id/.
    • Set WORKER_UNIT to the ComfyUI service.
    • Set ALERT_WEBHOOK to a Discord webhook if wanted.
    • Then systemctl enable --now connector-watchdog.
  3. Language: the host script uses only the Python standard library, so a bare node needs nothing installed. That's a deliberate exception to the house TypeScript rule: this is a small on-node daemon, not an operator CLI.

Build, calibration and commissioning (test each stage before the next)#

  1. Pico only. Flash MicroPython and run mpremote repl. The board should respond.
  2. Air bead on the breadboard. Copy main.py; mpremote shows a line every second. air should read room temperature, and gpu shows nan / open until that sensor is fitted.
  3. Film sensor. Prepare its leads and plug it in. Both should now read room temperature within about 1 °C of each other.
  4. Calibration check (5 minutes). Put both sensors, with a kitchen thermometer, in a cup of hot water at around 70–80 °C. Keep the joints and the bead's legs dry: put the sensors in a small sealed plastic bag.
    • Pass: each reading agrees with the thermometer within about 2 °C.
    • If one is off by several °C at 80 °C but fine at room temperature, its B value differs from the listing. Take the r= resistance the Pico prints for that sensor at a known temperature T (in kelvin) and compute B = ln(R25 / R) / (1/298.15 − 1/T). Then set that sensor's B in PROBES in main.py.
  5. PC817. Find the JFP1 signal and ground pins with the multimeter as above, then wire them. With the node idle, send echo TEST > /dev/serial/by-id/...: the node should shut down cleanly. This proves the wiring without the 6 s force.
  6. Fit the sensors in the node as described above, and start the host service.
  7. Baseline. Run the GPU at sustained full load (575 W class) for 30 min. Log the plug-sensor and air plateaus, and check the plug with the IR thermometer. Also note how much the plug reading drifts per minute once it has settled.
    • WARN_C = plug plateau + 10–15 °C, capped at 85 °C.
    • DETACH_DELTA_C = about half of (plug plateau − air plateau).
    • RISE_C_PER_MIN = comfortably above the settled drift; the default 4 °C/min suits a drift under 1 °C/min.
    • If the plug plateau is already above 70 °C, stop and re-check seating and airflow before relying on the connector.
  8. Test the chain end to end. Temporarily set WARN_C 5 °C above the current reading and warm the plug sensor gently (fingers, or a hair-dryer at a distance; never a heat gun on the connector). Confirm the worker stops, the power cap applies and the alert arrives. Restore WARN_C.
  9. Record the node's values in its build record: baseline, WARN_C, DETACH_DELTA_C, RISE_C_PER_MIN, each sensor's B, and a photo of the sensor position.

Ongoing#

Deferred until the above is verified on a node#

These are planned but not built, so that the core watchdog is proven first.

Known limits#