← AXA-008

Circuit review & bench-test guide

AXA-008 — ULN2003A low-side driver pack PMOD module

Design-stage — board not yet fabricated

Document purpose#

This document explains the axa-008-lowside prototype at component level and turns the design evidence into a practical manual-review and bench-test plan. It is based on the generated schematic (generate_design.py), the module README, the actuator-line overview in ../README.md, and the TI ULN2003A datasheet (SLRS027T, revised March 2025).

This board has never been fabricated. Repository status is: schematic generated, ERC clean (0/0), netlist reviewed, PCB layout not started, BOM not exported, not released. There is no board, no assembly, and no bench evidence of any kind. Every number below is either a datasheet value, a design target, or a marked estimate — none of them is proof that a built board will behave. When a board exists, this guide becomes the plan for producing that proof.

1. What the board does#

The board is a four-channel low-side switch for small inductive and resistive loads: relays, solenoids, small pumps, and vibration motors. A single ULN2003A seven-channel Darlington array does all the work. Four of its inputs are driven directly by 3.3 V host GPIO through the PMOD connector (the internal 2.7 kΩ base resistors make external parts unnecessary); the corresponding open-collector outputs sink the low side of each load to ground. The load supply, VLOAD, up to 24 V, enters only on a screw terminal and never touches the PMOD. The array's COM pin ties to VLOAD so the internal clamp diodes freewheel inductive turn-off current back into the load supply.

It does not provide current sensing, fault feedback, high-side switching, PWM shaping, reverse-polarity protection on VLOAD, or channel status LEDs. A channel that is "on" is simply a saturated Darlington; nothing on the board reports whether the load actually energized.

Functional block diagram#

PMOD host (3.3 V logic)                        Load supply 5-24 V
        │                                              │
        v                                              v
   J1 PMOD plug                                J3 screw terminal
   1 CH1 ──────────────┐                        1 VLOAD ──┬───────────┐
   2 CH2 ─────────────┐│                        2 GND ─┐  │           │
   3 CH3 ────────────┐││                               │  │        C1 100 nF
   4 CH4 ───────────┐│││                               │  │           │
   5/11 GND ───┐    ││││                               │  └── COM (9) │
   6/12 3V3    │    vvvv                               │       │      │
   (unused     │  ULN2003A U1 ── clamp diodes ─────────│───────┘      │
    on-module) │  1B-4B in, 1C-4C out                  │              │
               │  5B/6B/7B tied to GND (spares off)    │              │
               │  5C/6C/7C no-connect                  │              │
               │    │││└ OUT4 ──> J4.4 ── load ── VLOAD│              │
               │    ││└─ OUT3 ──> J4.3 ── load ── VLOAD│              │
               │    │└── OUT2 ──> J4.2 ── load ── VLOAD│              │
               │    └─── OUT1 ──> J4.1 ── load ── VLOAD│              │
               └──────── E (8) ── GND ─────────────────┴──────────────┘
                          (grounds join on this module)

Each load wires from VLOAD to an OUTx terminal on J4; the channel pulls the low side to GND. At turn-off, the collapsing field drives OUTx above VLOAD until the internal clamp diode (OUTx to COM) conducts into the supply.

2. Safety and scope boundaries — actuators move#

This module differs from a sensor board in one fundamental way: its loads store energy and produce mechanical motion. Relays snap, solenoid plungers slam, valves actuate, pumps spin. Treat every first energization as a mechanical event, not just an electrical one.

3. Power and control sequence#

  1. Host 3.3 V comes up; PMOD pins 1–4 (CH1–CH4) are driven low by the host. All four Darlingtons are off. Inputs 5B–7B are hard-wired to GND, so the three spare channels can never turn on.
  2. VLOAD is applied at J3. C1 charges; COM sits at VLOAD; every OUTx floats at approximately VLOAD through its load (minus load resistance drop at the ~50 µA max collector leakage, i.e. essentially VLOAD).
  3. The host drives a CHx input high (3.3 V). Current flows through the internal 2.7 kΩ base resistor into the Darlington pair; the output saturates and pulls OUTx down to VCE(sat) — datasheet 0.9 V typical at 100 mA rising to 1.2 V typical / 1.6 V max at 350 mA. The load sees VLOAD − VCE(sat) and actuates.
  4. The host drives CHx low. The Darlington turns off in about 0.25 µs (1 µs max propagation), but the coil current cannot stop: OUTx rises above VLOAD until the internal clamp diode (VF 1.7 V typical, 2 V max at 350 mA) conducts, and the stored energy freewheels into the VLOAD supply and C1 until the current decays.
  5. Grounds join on the module: the PMOD GND pins (5, 11), U1's emitter pin E (8), C1, and J3 pin 2 share one GND net. Load current returns through J3 pin 2, not through the PMOD — a layout obligation, since layout has not started (see section 8).

Why 3.3 V drive is the module's tightest spec#

The ULN2003A electrical table specifies ON-state input voltage VI(on) at VCE = 2 V as 2.4 V max at IC = 200 mA, 2.7 V max at 250 mA, and 3.0 V max at 300 mA. The datasheet gives no VI(on) figure at 350 or 500 mA for the ULN2003A. Driving from 3.3 V GPIO therefore guarantees saturation by the table only up to about 300 mA per channel, with 0.3 V of margin. The headline "500 mA-rated collector current" is an absolute-maximum single- output rating, not a promise at 3.3 V drive. Treat ~300 mA as the per- channel design ceiling for guaranteed behavior and verify anything higher on the bench (section 9.E). The actual GPIO high level of the specific FPGA bank matters too.

4. Interfaces#

ReferencePins/signalsIntended use
J1PMOD Type 1: 1 CH1, 2 CH2, 3 CH3, 4 CH4, 5 GND, 6 3V3, 7–10 NC, 11 GND, 12 3V3Host logic connection; all four lines host-driven GPIO
J31 VLOAD (max 24 V), 2 GNDLoad supply input, screw terminal; grounds join here
J41 OUT1, 2 OUT2, 3 OUT3, 4 OUT4Low-side load terminals; each load wires VLOAD-to-OUTx

Notes:

5. Component-by-component review#

Every schematic reference designator is covered. #FLG01–#FLG03 are ERC power flags on 3V3, GND, and VLOAD — schematic bookkeeping only, no physical parts.

5.1 Active and connector parts#

Ref.Part / datasheet summaryFunction and why neededIf absent/openIf shorted, wrong, or misassembled
U1TI ULN2003ADR, SOIC-16, seven NPN Darlington pairs, 50 V outputs, 500 mA peak per collector, internal 2.7 kΩ base resistors, common-cathode clamp diodes to COMThe entire function: four GPIO-driven low-side switches plus the flyback pathNo switching at allRotated package puts VLOAD-side pins on GPIO nets — can feed up to 24 V toward the host; a collector-emitter short holds a load permanently on; a wrong family member changes input thresholds (ULN2002A needs up to 13 V input; ULN2004A needs 6–15 V logic — neither works from 3.3 V)
J1PMOD 12-pin plug, Type 1 GPIOHost logic and logic ground; carries no load currentNo control; loads stay offOff-by-one insertion into the host puts 3V3/GND on signal pins; miswired harness can drive an unintended channel
J3Phoenix MKDS 1,5/2-5,08 class screw terminal (MPN marked TBD in schematic)Load supply entry; the only permitted path for VLOAD; GND lug is the load-current returnNo load power; if only GND is open, load current has no return except (destructively) the PMOD ground pinsReversed VLOAD/GND applies −24 V across the clamp diodes and C1 — there is no reverse-polarity protection; the diodes conduct hard and U1 dies. Terminal current rating must be checked against the Phoenix datasheet before assigning a total-load budget
J4Phoenix MKDS 1,5/4-5,08 class screw terminal (MPN TBD)Four low-side output lugsAffected channel has no load pathAdjacent-lug short parallels two loads onto one channel (overcurrent); OUTx accidentally strapped to GND holds that load permanently on and bypasses the switch; loose screws under vibration are an arc/kickback source with inductive loads

5.2 Passives and schematic bookkeeping#

Refs.Value / partPurposeIf omitted or wrong
C1100 nF 50 V X7R 0603 (Murata GRM188R71H104KA93D)VLOAD–GND decoupling at the array; snubs the fast edge when the clamp diodes commutate kickback current into the supply lead inductanceOmitted: the flyback current returns only through the (possibly long) J3 supply leads, and COM/VLOAD rings at every turn-off. Wrong (low) voltage rating fails on a 24 V rail — the 50 V rating is deliberate. A shorted C1 is a VLOAD–GND short: the bench supply current limit is the only protection
#FLG01–#FLG03ERC power flags (3V3, GND, VLOAD)Tell ERC these nets are externally poweredSchematic-only; no physical failure mode

Also review as if they were components:

ItemDesign decisionFailure if wrong
U1 inputs 5B/6B/7BTied to GND so the spare Darlingtons stay hard offIf left floating instead, leakage or coupling could half-enable a spare channel whose output is a no-connect — invisible until it heats
U1 outputs 5C/6C/7COpen (no-connect)If a layout error nets one to anything, an unused grounded-input channel would clamp it via its collector-COM diode to VLOAD
COM (U1 pin 9) → VLOADThe line's flyback rule, implemented with the array's internal diodesOpen COM = no flyback path = channel destruction at first inductive turn-off (section 2). COM to GND instead of VLOAD would forward-bias every clamp diode whenever OUTx sits at VLOAD — a dead short through the diodes

6. Datasheet summary and design interpretation#

Source: TI SLRS027T "ULN200x, ULQ200x High-Voltage, High-Current Darlington Transistor Arrays", December 1976, revised March 2025. Product page · Datasheet PDF. The exact variant in the schematic is ULN2003ADR (D = SOIC-16, R = reel).

Manufacturer fact (SLRS027T)ValueBoard-specific interpretation
Collector-emitter voltage, abs max50 V24 V VLOAD plus a clamped spike of VLOAD + ~2 V fits comfortably; an unclamped spike does not
Clamp diode reverse voltage, abs max50 VDiodes block VLOAD ≤ 24 V with margin when the channel is on
Peak collector current, abs max500 mA (single output)Absolute maximum, not a continuous 4-channel rating; see thermal math below
Output clamp current IOK, abs max500 mAThe clamp diode can carry the full channel current at turn-off — matched by design
Total emitter-terminal current, abs max−2.5 A4 × 500 mA = 2.0 A worst case is inside this limit; thermals bind first
Input voltage, abs max30 V3.3 V GPIO trivially safe; also survives accidental 24 V contact to an input, once
VI(on) max at VCE = 2 V (ULN2003A)2.4 V @ 200 mA; 2.7 V @ 250 mA; 3.0 V @ 300 mAWith 3.3 V drive, guaranteed saturation only to ~300 mA/channel (section 3)
VCE(sat) typ/max0.9/1.1 V @ 100 mA; 1.0/1.3 V @ 200 mA; 1.2/1.6 V @ 350 mAThe table stops at 350 mA. The 500 mA value must be read from the datasheet's typical-characteristics curves (section 5.14) or measured — expect above 1.2 V typical. Do not assume; measure (section 9.E)
Clamp diode VF1.7 V typ / 2.0 V max at IF = 350 mAKickback clamps to about VLOAD + 1.7–2 V; the scope target in section 9.D
Collector cutoff ICEX50 µA max at VCE = 50 VOff-state loads see essentially full VLOAD; no ghost actuation
Input current II0.93 mA typ / 1.35 mA max at VI = 3.85 VPer-pin GPIO load at 3.3 V is roughly 0.8–1 mA (slightly below the 3.85 V test point) — fine for any FPGA bank
Switching tPLH/tPHL0.25 µs typ / 1 µs maxFast enough for relay/solenoid work and low-kHz PWM on pumps/motors
RθJA, D (SOIC-16) package88.6 °C/WGoverns the multi-channel budget below
TJ max150 °C (abs max); 125 °C recommended operatingThermal ceiling for the arithmetic below
ESD±2000 V HBM, ±500 V CDMHandling-level only; no system-level (IEC) rating — the screw terminals have no external ESD/transient protection

The datasheet does not state a single "package power dissipation" number for the D package; it must be derived from RθJA (next section). It also does not specify VCE(sat) or VI(on) at IC = 500 mA in the ULN2003A tables — both are open items that only the typical-characteristic curves and the bench can answer.

Total-package thermal math (the real channel-count limit)#

Derived allowable dissipation in SOIC-16, still air, from datasheet thermal data (these are derived values, not datasheet statements):

P_max = (TJ − TA) / RθJA
At TA = 25 °C, TJ = 150 °C (abs max):   (150 − 25) / 88.6 = 1.41 W
At TA = 25 °C, TJ = 125 °C (rec. op.):  (125 − 25) / 88.6 = 1.13 W
At TA = 50 °C, TJ = 125 °C:             (125 − 50) / 88.6 = 0.85 W

Per-channel dissipation is IC × VCE(sat). A Darlington saturates at about a volt, so every 500 mA channel burns about half a watt:

1 ch × 500 mA × ~1.2 V (typ, extrapolated) ≈ 0.60 W    → fine alone
2 ch × 500 mA                              ≈ 1.20 W    → at the 125 °C budget at 25 °C ambient
4 ch × 500 mA                              ≈ 2.40 W    → 2.4 W × 88.6 °C/W = 213 °C rise: impossible
4 ch × 350 mA × 1.2 V typ                  ≈ 1.68 W    → 149 °C rise: still over budget
4 ch × 300 mA × ~1.1 V (interp. typ)       ≈ 1.32 W    → 117 °C rise, TJ ≈ 142 °C at 25 °C: marginal
4 ch × 250 mA × ~1.05 V (interp. typ)      ≈ 1.05 W    → TJ ≈ 118 °C at 25 °C ambient: workable, no margin for enclosure heat

Conclusion: four simultaneous 500 mA channels are thermally impossible in this package. Realistic simultaneous budget is roughly 250 mA per channel on all four, or one heavy channel plus light ones. This matches the README's "derate when ganging" note and must be stated on the silkscreen or in user documentation. Copper pour under the package (RθJB = 49.8 °C/W suggests board conduction helps) is a layout requirement, and the 60-minute soak in section 9.F is the verdict.

7. Expected values before bench testing#

QuantityDesign target / datasheet valueWhat to measure
OUTx off, load connected≈ VLOAD (ICEX ≤ 50 µA)DMM OUTx to GND, input driven low
OUTx on at ≤ 100 mA0.9 V typ, 1.1 V maxDMM OUTx to GND, input at 3.3 V
OUTx on at 350 mA1.2 V typ, 1.6 V maxSame, with resistive test load
OUTx on at 500 mAAbove 1.2 V typ; no datasheet table value — check curves and measureSection 9.E fixture
Kickback clamp levelVLOAD + 1.7 V typ, + 2.0 V maxScope on OUTx at coil turn-off, section 9.D
Input current per channel at 3.3 V≈ 0.8–1 mA (est. from 0.93 mA typ at 3.85 V)Series µA-meter in one input
Turn-on/turn-off delay0.25 µs typ, 1 µs maxScope, input vs OUTx edges
COM to J3 VLOAD continuity0 ΩOhmmeter, unpowered — mandatory before first coil
Four-channel soak at 250 mA each≈ 1.0–1.1 W package, TJ ≈ 115–120 °C at 25 °C ambient (derived)Thermocouple/IR on U1, 60 min
Quiescent VLOAD current, all off≤ ~0.4 mA (7 × 50 µA leakage bound + C1 leakage)Bench supply readout
3V3 current drawn by module~0 (nothing on the module uses 3V3)Bench supply readout, standalone context

8. Manual schematic, layout, and assembly review checklist#

Schematic-stage items (now):

Layout-stage items (before fab):

Assembly-stage items (first article):

9. Ordered bench-test procedure#

Stop at the first abnormal result. Record board serial, load identities (manufacturer, coil voltage, measured coil resistance), supply and scope IDs, ambient temperature, and operator for every step.

Two bench contexts are covered; run A–C in whichever context is available, then D–F preferably in the standalone context first (a mistake costs a bench GPIO fixture, not an FPGA):

Context (a) — PMOD host (ECP5/ULX3S class). The host provides 3.3 V logic levels and logic GND through J1. Grounds: host GND and load-supply GND join on the module; verify the load bench supply is floating or shares ground only at J3.2, so no load current can return through the host's USB or programmer ground. Sequencing: host powered and GPIO configured (outputs driven low — not tri-stated) before VLOAD is applied; VLOAD off before reprogramming the FPGA (bitstream loads tri-state the pins).

Context (b) — standalone. A 3.3 V bench supply or logic-level function generator drives CH inputs through a PMOD breakout; its return ties to the module GND (PMOD pin 5/11 or J3.2). A second, separate, current-limited supply provides VLOAD at J3. The two supplies share ground only at the module. Same sequencing rule: 3.3 V side established and inputs low before VLOAD.

A. Unpowered inspection and resistance tests#

  1. Complete the assembly checklist in section 8.
  2. Ohmmeter, both polarities: VLOAD to GND at J3 (expect high/charging, no hard short), each OUTx to GND (expect open/high — a Darlington junction may read in diode mode from GND to OUTx, that is normal), each OUTx to VLOAD (expect a diode drop OUTx→COM direction only — this is the clamp-diode check).
  3. Mandatory: confirm 0 Ω from U1 pin 9 (COM) to J3 pin 1 (VLOAD). Do not energize any inductive load until this passes.
  4. Confirm PMOD pins 5/11 to J3 pin 2 continuity (the joined ground).

B. Logic-only power (no VLOAD, no loads)#

  1. Apply the 3.3 V context with all inputs low. Nothing should draw more than leakage; the module itself consumes ~0 mA from 3V3.
  2. Drive each CHx high in turn; measure the input-pin current if the fixture allows (expect ≈ 0.8–1 mA into the 2.7 kΩ base network). OUTx will not move — there is no VLOAD yet. Abnormal input current means a wrong device variant or damaged input.

C. First VLOAD, resistive load, one channel#

  1. Set the VLOAD supply to the lowest useful voltage (e.g. 5–12 V) with a current limit of ~150 mA. Connect one resistive dummy load (e.g. 120 Ω power resistor at 12 V ≈ 100 mA) from VLOAD to OUT1.
  2. Inputs low, apply VLOAD. OUT1 should read ≈ VLOAD; supply current ≈ leakage only.
  3. Drive CH1 high. Expect OUT1 to drop to ≈ 0.9 V (1.1 V max at 100 mA) and the load current to appear on the supply. Drive low; OUT1 returns to VLOAD. Repeat for CH2–CH4 on their terminals.
  4. Any channel that does not switch, or a VCE(sat) far above table values: stop and investigate (troubleshooting map, section 10).

D. Inductive load and the kickback capture (board-specific)#

  1. Hands clear of the mechanism. Use a small relay or solenoid whose coil voltage matches VLOAD and whose measured coil current fits the supply limit (set limit ≈ 1.5× coil current). Connect coil from VLOAD to OUT1.
  2. Scope: CH-A on OUT1, CH-B on the CH1 input, ground clip to module GND at J3.2, single-shot trigger on OUT1 rising above VLOAD.
  3. Actuate CH1 for ~1 s, then release. Expected capture with the COM clamp connected: at turn-off, OUT1 rises from VCE(sat) to a flat- topped spike at approximately VLOAD + 1.7 V (typ) to VLOAD + 2.0 V (max) — the clamp diode's VF — holds there while the coil current decays (roughly L/R of the coil, order milliseconds for a relay), then relaxes to VLOAD. Some ringing on the edge is normal; C1 exists to tame it. Save the capture; it is the module's signature waveform and the line's teaching exhibit.
  4. What the waveform would do unclamped — explanation only, do NOT perform this casually: with COM disconnected, nothing conducts until the output pin reaches the Darlington's collector-emitter breakdown above its 50 V rating. The pin would fly from VLOAD to >50 V in well under a microsecond, the transistor would avalanche, and the entire stored coil energy (½LI², easily millijoules) would dissipate in the junction. One event may survive; repeated events destroy the channel. Demonstrating this deliberately requires a sacrificial board, a current-limited setup, and acceptance that U1 will be damaged.
  5. Repeat the clamped capture on each remaining channel with the same coil.
  6. Actuate the coil 50–100 cycles (script it in context (a)); confirm the clamp level and VCE(sat) do not drift and U1 stays cool.

E. VCE(sat) at 500 mA and drive-margin check (board-specific)#

  1. Fixture: current-limited supply and a power resistor sized for ≈ 500 mA (e.g. 24 V with 47 Ω / ≥15 W ≈ 510 mA, or an electronic load in CC mode from VLOAD to OUTx). One channel only.
  2. Drive the input with the true bench context level (measure it — an FPGA bank may deliver 3.2 V, not 3.3 V). Measure OUTx to GND with a DMM at the U1 pin, not the terminal lug.
  3. Datasheet reference: 1.2 V typ / 1.6 V max at 350 mA is the last table entry; the 500 mA value is only on the typical-characteristics curves. Record the measured value. If OUTx sits well above ~1.6 V or the device is clearly out of saturation, the 3.3 V drive margin discussed in section 3 is binding — reduce the per-channel rating in the README to what the measurement supports.
  4. Compute and record P = 0.5 A × VCE(sat)(measured). Expect ≈ 0.6–0.8 W; confirm U1 temperature stabilizes below the section 6 budget for a single channel.

F. Multi-channel thermal soak#

  1. Four resistive loads at the derated target (start at 250 mA each, section 6 arithmetic). All four channels on continuously.
  2. Log U1 top-of-package temperature (thermocouple or IR with stated emissivity assumption) every 5 minutes for 60 minutes at worst intended ambient. Estimate TJ via ψJT = 12.4 °C/W: TJ ≈ Tcase-top + P × 12.4.
  3. Pass criterion: TJ estimate stays below 125 °C with margin for the enclosure. If it does not, lower the documented simultaneous rating — do not add "just for the test" airflow and call it a pass.
  4. Only after a clean soak, explore higher per-channel currents stepwise, watching VCE(sat) (it rises as the part heats, which increases dissipation — thermal runaway direction) and stopping at the first sign of drift.

G. Release-only tests#

Hot-cycle endurance with real solenoids/valves, PWM operation of pumps and vibration motors (verify clamp behavior at PWM rates — the diode conducts every cycle), behavior with long load leads (added inductance), screw- terminal torque/retention, and any EMC or product-safety work happen under controlled plans after the above passes. None of it is bench-casual.

10. Troubleshooting map#

SymptomFirst measurementsLikely areas
No channel switches3.3 V at CHx pin during drive; U1 orientation; E-pin to GND continuityWrong device variant (2002A/2004A), rotated U1, open GND
One channel dead, others fineCHx at U1 base pin vs at J1; OUTx at U1 pin vs at J4 lugCold joint at U1, open trace, damaged channel (prior unclamped event?)
Channel stuck onOUTx-to-GND resistance unpowered; is the input actually driven low?Collector-emitter short (kickback damage), OUTx shorted to GND, host pin stuck high or tri-stated
VCE(sat) far above tableInput high level at the pin; current actually in spec?Insufficient 3.3 V drive at this current (section 3), heated die, wrong variant
Kickback spike exceeds VLOAD + ~2 V or rings hardCOM-to-VLOAD continuity; C1 present; supply-lead lengthOpen COM (stop immediately), missing/failed C1, excessive lead inductance
Load chatters or half-actuatesVLOAD at J4 lug under load; coil current vs supply limitSupply current limit too low, undersized VLOAD wiring, VCE(sat) eating headroom on a marginal coil
U1 hot at modest loadPer-channel currents; VCE(sat) each active channel; ambientExceeded thermal budget (section 6), spare channel partially on (check 5B–7B grounding), poor layout copper
Host misbehaves when loads switchWhere does load return current flow? Scope host GND vs module GNDLoad return via PMOD ground (layout/wiring error), missing J3.2 connection, shared-ground loop with bench supplies
Reverse-connected VLOAD survived?Clamp diodes (step A.2), all channels re-testedNo reverse protection exists; assume U1 damage until every channel passes sections C–E again

11. Bench record template#

FieldRecord
Board revision / serial
U1 date code / marking; variant confirmed ULN2003A
J3/J4 final MPNs and lug torque
Bench context (PMOD host / standalone) and grounding sketch
VLOAD supply ID, voltage, current-limit setting
Logic source ID and measured high level at CHx
COM-to-VLOAD continuity result (pre-coil, mandatory)
Load inventory: type, coil V, measured R, computed I per channel
Per-channel VCE(sat) at 100 mA / 350 mA / 500 mA
Kickback captures (file paths), clamp level per channel
60-minute soak: currents, Tcase, TJ estimate, ambient
Quiescent and leakage measurements
Deviations, photos, raw-file paths
Reviewer / date / disposition

12. Review conclusion#

The design is deliberately minimal and internally consistent: one array does the switching and provides its own flyback diodes, the COM-to-VLOAD tie implements the line's flyback rule with zero extra parts, spare inputs are grounded, load power is segregated from the PMOD, and the single 50 V-rated decoupler sits on the rail that actually carries the transient. ERC passes; the netlist review is on record.

The honest caveats are these. First, nothing physical exists — no layout, no board, no measurement; everything above is target, not evidence. Second, the module's advertised 500 mA per channel is an absolute-maximum figure that the ULN2003A's own input table does not guarantee from 3.3 V logic beyond about 300 mA, and the thermal arithmetic caps four simultaneous channels near 250 mA each in SOIC-16 — the bench (sections 9.E and 9.F) must set the real published rating. Third, the safety of every inductive load rests entirely on one net: COM to VLOAD. That continuity check is the one measurement that must never be skipped on a new build. Fourth, the board offers no reverse-polarity protection, no fault feedback to the host, and no status indication — acceptable for an L1 teaching module only if the documentation says so as plainly as this review does.