LD-PAY-003  ·  v1.0.0  ·  published  ·  2026-03-30  ·  CC BY-SA 4.0
docs  /  payloads  /  "libdrone — PSB-1 Payload Shield Board: Perfboard Build Guide"

About

Step-by-step guide to building the PSB-1 Payload Shield Board on 2.54mm perfboard. No PCB design skills required. Estimated time: one evening. This is the prototype build — the circuit is proven, tested, and documented. A formal KiCad PCB comes later. Build this first.


What the PSB-1 does

Every libdrone payload currently hand-wires the same five components: MOSFET, two diodes, LDO regulator, and pull-up resistors. You make one mistake per build and spend an evening debugging. The PSB-1 builds these once, correctly.

After this build, a payload is: 1. Plug the two GX12 pigtails into the PSB-1 headers 2. Plug the ESP32-S3 dev board into the MCU headers 3. Connect your sensor to the I2C or UART header 4. Flash libdrone.py + your sensor code 5. Done


Tools required

  • Soldering iron (fine tip, 350°C)
  • Solder (0.6mm, leaded or lead-free)
  • Side cutters
  • Multimeter
  • 2.54mm perfboard (at least 20×15 holes — a standard 7×5cm board is fine)
  • Helping hands or small vice

Bill of materials

Qty Part Value / Part number Where to get ~Cost
2 N-ch MOSFET IRLML6344 SOT-23 Mouser / LCSC €0.30 ea
2 Signal diode 1N4148 Any electronics supplier €0.05 ea
1 LDO regulator MCP1700-3302E SOT-23 Mouser / Farnell €0.40
1 Resistor 10kΩ 1/4W through-hole Any €0.02
2 Resistor 10kΩ 1/4W through-hole Any €0.02 ea
1 Capacitor 100nF ceramic Any €0.05
1 Capacitor 10µF electrolytic or ceramic Any €0.10
1 LED Any colour Any €0.05
1 Resistor 1kΩ (LED current limiter) Any €0.02
1 Switch Latching SPDT miniature Any €0.50
2 Header 2.54mm 6-pin female Any €0.20 ea
1 Header 2.54mm dual-row 20-pin female Any €0.30
1 Perfboard 2.54mm, 7×5cm Any €0.50
2m Wire 28 AWG, several colours Any €1.00
2 GX12-7 female Cable mount AliExpress €1.50 ea

Total component cost: approximately €8

Note on SOT-23 packages: these are small (3mm × 1.5mm) but hand-solderable with a fine tip. If uncomfortable with SMD, use through-hole equivalents: - MOSFET: 2N7000 (TO-92) instead of IRLML6344 - LDO: MCP1700-3302E is available in TO-92 package — specify when ordering


Circuit description (read before soldering)

The PSB-1 implements four things:

1. Master enable (MOSFET + diode-OR)

Conn A PIN 1 (5V) ──────────────────── MOSFET Drain
                                        MOSFET Source ──► 5V_SW (payload rail)
Physical switch ──┐
                  ├──► Diode ──► 10 ──► MOSFET Gate
AUX GPIO1 ────────┘──► Diode ──┘

Pull-down 10 from Gate to GND ensures MOSFET is OFF when both inputs are LOW.

Either the physical switch OR the radio GPIO can turn the payload on. Both OFF = MOSFET OFF = zero current draw from drone battery.

2. 3.3V regulation

5V_SW ──► 100nF ──► MCP1700 IN ──► MCP1700 OUT ──► 10µF ──► 3V3
                                                              
                                                    ESP32-S3, sensors

The LDO is downstream of the MOSFET — when master enable is OFF, the LDO has no input, the ESP32-S3 is unpowered. Zero standby current.

3. Status LED

5V_SW ──► 1 ──► LED ──► GND

When master enable is active, the LED illuminates. Pre-flight visual check.

4. GPIO protection

AUX GPIO1 (Conn B PIN 5) ──► 10kΩ ──► GPIO1 header pin
AUX GPIO2 (Conn B PIN 6) ──► 10kΩ ──► GPIO2 header pin

Protects the FC's GPIO output from any wiring mistakes on the payload side.


Build sequence

Step 1 — Cut and prepare the perfboard

Cut a piece approximately 20×15 holes (50mm × 38mm). File the edges smooth. Mark the top surface with a permanent marker: "TOP — components this side."

Step 2 — Plan your layout

Before soldering anything, lay out all components dry on the board. Suggested layout zones (left to right):

[GX12-A header] [MOSFET circuit] [LDO + caps] [MCU headers] [GX12-B header]
     6 pins      IRLML6344 ×2      MCP1700      2×10 pins       6 pins
                 1N4148 ×2
                 10kΩ ×3

The GX12 pigtail wires will be soldered directly to the header pins — these are the first and last columns of the board.

Step 3 — Install GX12-A header (J1, left)

Solder a 6-pin female header at the left edge of the board. Label pins 1–6 top to bottom: 5V, GND, UART4TX, UART4RX, SCL, SDA.

Route wires from your two GX12-A female connector pigtails to these pins: - GX12-A PIN 1 (red, 22AWG) → header pin 1 (5V) - GX12-A PIN 2 (black, 22AWG) → header pin 2 (GND) - GX12-A PIN 3 (blue, 28AWG) → header pin 3 (UART4TX) - GX12-A PIN 4 (blue, 28AWG) → header pin 4 (UART4RX) - GX12-A PIN 5 (green, 28AWG) → header pin 5 (SCL) - GX12-A PIN 6 (green, 28AWG) → header pin 6 (SDA)

Strain relief: zip-tie the cable to the board edge before soldering.

Step 4 — Install GX12-B header (J2, right)

Solder a 6-pin female header at the right edge. Label: GND, GPS, UART5TX, UART5RX, GPIO1, GPIO2.

Route wires from GX12-B female connector pigtails: - GX12-B PIN 1 (black, 28AWG) → GND (joins main GND) - GX12-B PIN 2 (green, 28AWG) → header pin 2 (GPS) - GX12-B PIN 3 (blue, 28AWG) → header pin 3 (UART5TX) - GX12-B PIN 4 (blue, 28AWG) → header pin 4 (UART5RX) - GX12-B PIN 5 (blue, 28AWG) → 10kΩ → header pin 5 (GPIO1) - GX12-B PIN 6 (blue, 28AWG) → 10kΩ → header pin 6 (GPIO2)

Step 5 — MOSFET master enable circuit

If using IRLML6344 SOT-23: Solder the SOT-23 onto three perfboard pads using fine tip and thin solder. SOT-23 pinout: PIN 1 = Gate, PIN 2 = Source, PIN 3 = Drain. The tab/flat face of the package faces up.

Solder small pieces of wire to each pin immediately after soldering the package — SOT-23 pads are tiny, easier to work with connections made before routing.

MOSFET wiring: - Drain → 5V from GX12-A PIN 1 - Source → 5V_SW rail (internal power rail) - Gate → junction of two 1N4148 cathodes + 10kΩ pull-down to GND

Diode-OR: - 1N4148 diode 1: Anode to physical switch output, Cathode to Gate - 1N4148 diode 2: Anode to GPIO1 (after 10kΩ protection resistor), Cathode to Gate - 10kΩ pull-down: Gate to GND

Physical switch: - Wire from GND to switch common - Wire from switch NO to 1N4148 anode - Mount switch to mast body — not to the perfboard itself

Step 6 — LDO 3.3V regulator

MCP1700-3302E SOT-23 pinout: PIN 1 = GND, PIN 2 = OUT (3.3V), PIN 3 = IN.

  • IN → 5V_SW rail
  • GND → main GND plane
  • OUT → 3V3 rail
  • 100nF ceramic cap between IN and GND (as close to LDO as possible)
  • 10µF cap between OUT and GND

Step 7 — Status LED

  • 5V_SW → 1kΩ resistor → LED anode → LED cathode → GND
  • Mount LED so it is visible on the mast exterior

Step 8 — MCU headers

Solder a 2×10 (20-pin) dual-row female header for the ESP32-S3 dev board. The ESP32-S3 mini dev board is approximately 25×20mm — verify your specific board's pin spacing before soldering.

Route traces from the header pins to the appropriate signal sources: - ESP32 GPIO17 → UART4TX header pin (Conn A PIN 3) - ESP32 GPIO18 → UART4RX header pin (Conn A PIN 4) - ESP32 GPIO16 → GPS header pin (Conn B PIN 2) - ESP32 GPIO4 → GPIO1 header pin (Conn B PIN 5, after 10kΩ) - ESP32 GPIO5 → GPIO2 header pin (Conn B PIN 6, after 10kΩ) - ESP32 GPIO9 → SCL header pin (Conn A PIN 5) - ESP32 GPIO8 → SDA header pin (Conn A PIN 6) - ESP32 3V3 in → 3V3 rail from LDO - ESP32 GND → main GND

Use the PSB1_PINS dict in libdrone.py — if you wire differently, update those pin numbers. The library adapts to any mapping.


Test sequence (before connecting to drone)

Test 1 — No shorts With no battery and no components powered, measure resistance between 5V rail and GND rail. Must be > 10kΩ. Any lower = short circuit. Find and fix before proceeding.

Test 2 — MOSFET logic (bench power supply, 5V, 500mA max) Connect 5V bench supply to GX12-A PIN 1/2 (not the drone — bench supply). - Physical switch OFF, GPIO1 LOW (leave unconnected): LED must be OFF. Measure 5V_SW rail — must be 0V or near 0V (MOSFET off). - Physical switch ON: LED must illuminate. Measure 5V_SW = 5V. - Switch OFF, connect GPIO1 to 3.3V: LED must illuminate. 5V_SW = 5V. - Both OFF again: LED off.

Test 3 — LDO output With 5V_SW active (switch or GPIO): measure 3V3 rail = 3.3V ± 0.1V.

Test 4 — Install ESP32-S3, flash libdrone test Flash the minimal test sketch below. Open serial monitor at 115200 baud. Expected output every second: libdrone OK | GPS: waiting | GPIO1: 0 | GPIO2: 0

Test 5 — GPS test Connect GX12-B to a live drone (powered, no arming required). Serial monitor should show: GPS: 50.123456, 14.456789, 312m, 14 sats

Test 6 — OSD test Connect GX12-A to a live drone. Verify text appears in HDZero goggles. Expected OSD line 1: PSB-1 TEST OK


Minimal test sketch (flash before first drone connection)

# psb1_test.py — Flash this to verify PSB-1 hardware before payload code
from libdrone import OSD, GPS, AUX, Power, version
import time

version()

osd = OSD()
gps = GPS()
aux = AUX()
pwr = Power(aux=aux)

count = 0

while True:
    fix = gps.read()
    g1 = aux.switch1()
    g2 = aux.switch2()

    if fix.valid:
        gps_str = f'GPS:{fix.lat:.4f},{fix.lon:.4f} {fix.sats}S'
    else:
        gps_str = 'GPS: waiting...'

    status = f'PSB1 OK {count:04d}'

    # Print to serial monitor
    print(f'libdrone OK | {gps_str} | GPIO1:{int(g1)} | GPIO2:{int(g2)}')

    # Send to OSD (only works when connected to drone)
    osd.write(status,   row=1)
    osd.write(gps_str,  row=2)
    osd.write(f'G1:{int(g1)} G2:{int(g2)} EN:{int(pwr.is_enabled())}', row=3)

    count += 1
    time.sleep(1)

Minimal sensor payload template

Copy this and replace the read_sensor() function with your hardware.

# my_payload.py — Minimal compliant payload template
# Replace read_sensor() with your sensor code.
# Everything else — GPS, OSD, logging, command handling — is handled.

from libdrone import OSD, GPS, Command, AUX, Power, Logger
import time

# ── Hardware init ──────────────────────────
osd = OSD()
gps = GPS()
cmd = Command(osd=osd)   # shares UART4 with OSD
aux = AUX()
pwr = Power(aux=aux)
log = Logger('/sd/flight.csv')

# ── Your sensor init goes here ─────────────
# Example: from machine import I2C
# i2c = I2C(0, scl=Pin(9), sda=Pin(8), freq=400000)
# sensor = MySensor(i2c)

def read_sensor():
    """Replace with your sensor reading code. Return a dict."""
    return {
        'value_1': 0.0,   # e.g. 'PM25': 34.2
        'value_2': 0.0,   # e.g. 'CO2': 412
    }

# ── Main loop ──────────────────────────────
logging_active = False
log_open = False

while True:

    # 1. Read GPS (non-blocking)
    fix = gps.read()

    # 2. Handle commands from FC
    action = cmd.poll()
    if action == 'ENABLE':
        cmd.respond('OK')
    elif action == 'DISABLE':
        cmd.respond('OK')
    elif action == 'LOG_START':
        if not log_open:
            log.open()
            log_open = True
        logging_active = True
        cmd.respond('LOG_OK')
    elif action == 'LOG_STOP':
        logging_active = False
        cmd.respond('OK')
    elif action == 'STATUS':
        state = 'LOG' if logging_active else 'IDLE'
        cmd.respond(f'STATUS:{state},{log.row_count}rows')

    # 3. Check AUX GPIO (radio switches)
    if aux.switch1() and not logging_active:
        if not log_open:
            log.open()
            log_open = True
        logging_active = True

    # 4. Read sensor
    if pwr.is_enabled():
        readings = read_sensor()

        # 5. Write to OSD
        osd.write(f"V1: {readings['value_1']:.1f}", row=1)
        osd.write(f"V2: {readings['value_2']:.1f}", row=2)
        osd.write(f"LOG:{'REC' if logging_active else 'OFF'} {log.row_count}", row=3)
        if fix.valid:
            osd.write(f"GPS:{fix.sats}S {fix.alt:.0f}m", row=4)

        # 6. Log to SD card
        if logging_active and log_open:
            log.write(fix, readings)

    time.sleep(1)

What to build next

Once the PSB-1 perfboard is proven across 10+ flights:

  1. KiCad design brief — Document this exact circuit with component footprints, trace routing rules, and board dimensions. Brief is the input to fabrication.
  2. JLCPCB order — Upload Gerbers + BOM for PCBA (assembled) option. At qty 10 with PCBA: approximately €12/board delivered.
  3. PSB-1 v1.0 release — KiCad files in GitHub /hardware/psb-1/. Any payload builder in the world orders boards, plugs in ESP32-S3, done.

Revision History

Version Date Author Summary
1.0.0 2026-03-29 JS Initial release. Perfboard build guide, test sequence, minimal payload template.