techmannih/nema34-mounted-stepper-controller
A 48 V USB‑C PD 3.1 EPR NEMA‑34 stepper controller PCB combining STM32/TMC5160 control, external MOSFET motor bridges, protected power and regenerative braking, USB data, telemetry, diagnostics, status LEDs, and buzzer alarms.
- Version
- 0.3.92
- License
- unset
- Stars
- 1
hardware-contract.json
{
"name": "PD1180-EPR \u2014 NEMA 34 Smart Motor-Mounted Stepper Controller with USB-C PD 3.1 EPR",
"revision": "0.4.1-ECO",
"controller": "STM32G0B1CEU6",
"motor_driver": "TMC5160A with eight CSD19534Q5A MOSFETs",
"usb_pd": "TPS26750 + TPD4S480, sink-only EPR",
"usb_ports": {
"J1": "Dedicated 48 V / 5 A USB-C PD 3.1 EPR POWER sink; no USB data",
"J10": "USB 2.0 DATA plus independent, current-limited logic power; two 5.1k CC Rd; no PD negotiation and no connection to VMOTOR"
},
"mechanical": {
"board_mm": [
85.9,
85.9
],
"mounting_holes": [
{
"name": "H1",
"diameter_mm": 4.2,
"x_mm": 67.397132,
"y_mm": 4.575689,
"centered_x_mm": 24.447132,
"centered_y_mm": -38.374311
},
{
"name": "H2",
"diameter_mm": 4.2,
"x_mm": 81.324311,
"y_mm": 67.397132,
"centered_x_mm": 38.374311,
"centered_y_mm": 24.447132
},
{
"name": "H3",
"diameter_mm": 4.2,
"x_mm": 18.502868,
"y_mm": 81.324311,
"centered_x_mm": -24.447132,
"centered_y_mm": 38.374311
},
{
"name": "H4",
"diameter_mm": 4.2,
"x_mm": 4.575689,
"y_mm": 18.502868,
"centered_x_mm": -38.374311,
"centered_y_mm": -24.447132
}
],
"outline": "TMCM-1180 V1.1 stepped perimeter with four 5.9 mm concave corner arcs",
"reference": "engineering/mechanical/ordered-motor-pcb-reference.json",
"assembly": "top-side only",
"encoder": {
"reference": "U18",
"assembly_layer": "bottom",
"centered_x_mm": 0,
"centered_y_mm": 0,
"validation": "Optional bottom-side U18 and both bypass capacitors are DNP. Sensor center matches the ordered motor axis at (0,0). The single-shaft motor has no documented rear rotating-shaft interface; no magnet/holder or working gap is qualified.",
"do_not_place": true,
"local_bypass_references": [
"C52",
"C53"
]
},
"motor_assembly": {
"selected_motor": "STEPPERONLINE 34HS31-6004S1; user confirmed Amazon ASIN B091C83HWF on 2026-10-11",
"definition": "engineering/mechanical/assembly.json",
"preview_entrypoint": "motor-assembly.circuit.tsx",
"direct_rear_mount_compatible": null,
"status": "Exact ordered-motor CAD in an alignment preview; unsupported adapter/posts/fasteners removed. Existing four PCB holes unchanged. Rear thread/depth, secure mounting and encoder attachment remain unverified."
}
},
"fabrication": {
"layers": 4,
"finished_thickness_mm": 1.6,
"copper_oz_all_layers": 1,
"minimum_trace_space_mm": 0.09,
"solder_mask": "green",
"surface_finish": "ENIG",
"power_corridor_nominal_width_mm": 2.4,
"power_zone_clearance_mm": 0.16,
"signal_via_mm": {
"diameter": 0.5,
"drill": 0.3
},
"power_via_mm": {
"diameter": 0.6,
"drill": 0.3
},
"via_in_pad": "epoxy filled and copper capped for all 63 recorded via-in-pad locations; see docs/manufacturing-acceptance.md"
},
"rated_targets": {
"pd_contract_v": 48,
"pd_contract_a": 5,
"motor_phase_rms_a": 3.8,
"motor": "34HS31-6004S1",
"motor_rated_phase_a": 6,
"motor_current_note": "Conservative design ceiling for the ordered 6 A/phase motor: 3.8 A RMS target, GLOBALSCALER=139 gives 3.781 A nominal. The full-scale tolerance sensitivity peak is 5.671 A, below 6 A; this is not powered qualification. Initial commissioning uses IRUN=6, about 0.827 A RMS, 10 rpm and no attached load. Motion remains locked."
},
"reset_safe_outputs": {
"POWER_PERMIT": 0,
"MCU_RUN": 0,
"SD_MODE": 0,
"STATUS_GPIO": 0
},
"connectors": {
"J1": "USB PD POWER",
"J10": "USB DATA",
"J2": "Motor A1/A2/B1/B2",
"J3": "External regeneration brake resistor"
},
"logic_power": {
"U5": "PD_VBUS -> V3V3_PD -> U23 -> board V3V3",
"U22": "VMOTOR -> V3V3_MOTOR -> U24 -> board V3V3 (brake backup)",
"motor_power": "J1 only; USB DATA cannot energize VMOTOR",
"reverse_blocking": "Two cascaded status-interlocked LM66100 pairs; DATA and PD VBUS are never connected",
"usb_default_budget": "Startup before enumeration and USB suspend current must be measured and qualified; the current limiter is overload protection, not a USB enumeration policy",
"usb_data_power": "USB DATA alone powers MCU setup/diagnostics. Flash, encoder and sensors require board V3V3. CDC advertises a bus-powered 500 mA configuration.",
"U25": "USB_DATA_VBUS -> TPS2553 U28 -> TLV75533 U25 -> V3V3_USB",
"selection": "U26/U27 + R112: status-interlocked OR of board V3V3 and V3V3_USB into V3V3_MCU",
"board_presence": "R119/R120 10k/10k divider into STM32 PB1; 2.9\u20133.6 V qualified for 20 ms before peripheral access. PD IRQ removed; status remains polled.",
"suspend": "USB suspend disarms, invalidates telemetry, ends I2C, turns status low and enters STOP0. RTC/LSI wakes main every nominal 50 ms to service the 250 ms IWDG and sample DATA VBUS; USB resume/reset wakes normally. Physical current/timing validation remains open.",
"gpio_backfeed": "Chip selects use open-drain release into board-domain pullups; no high drive into unpowered peripherals. Peripheral inputs and I2C pins become analog/high impedance when board power is absent or USB suspended."
},
"diagnostics": {
"temperature": {
"device": "TMP102AIDRLR",
"address": 72,
"hardware_inhibit": "TEMP_OK -> U33 AND -> RUN_SAFE",
"trip_c": 70,
"manual_rearm_max_c": 55,
"derating_starts_c": 60,
"stale_limit_ms": 500,
"validation": "Board temperature only; MOSFET junction correlation and thresholds require load testing"
},
"phase_current": {
"device": "INA240A1DR x2",
"shunt_milliohm": 5,
"shunt_nominal_watts": 1,
"gain_v_per_v": 20,
"output_offset_v": 1.65,
"output_volts_per_ampere": 0.1,
"mcu_channels": [
"PA0",
"PA1"
],
"output_filter": {
"series_ohm": 1000,
"shunt_f": 1e-08
},
"validation": "Instantaneous diagnostics; nominal VDDA and offset require calibration. Not a short-circuit trip or an RMS estimate."
},
"bus_monitors": {
"device": "ADS1115IDGSR",
"address": 73,
"ain0": "VMON_ADC",
"ain1": "IIN_MON",
"reference_range_v": 4.096,
"sample_rate_sps": 128,
"ain2": "BRAKE_FB",
"brake_preflight": {
"divider_ohm": [
4700,
4700,
510
],
"filter_f": 1e-08,
"required_fresh_samples": 3,
"valid_bus_mv": [
44000,
50400
],
"return_ratio": [
0.9,
1.1
],
"scope": "Continuity before each power-permit cycle, latched only while RUN. Not a proof of brake current, Q16 turn-on, heatsink capacity or runtime cable integrity."
}
},
"indicators": {
"gpio_expander": "PCA9538PWR",
"i2c_address": 112,
"supply": "PD_3V3, shared with PD_SCL/PD_SDA pull-ups and reset buffer U37",
"reset": "PC13 / STATUS_GPIO with R132 10k pulldown drives U37 SN74LVC1G17DBVR input. PD_3V3-powered output U35_RESET_N has R137 47k pulldown. Assert low on MCU reset, rail loss, USB suspend or indicator bus failure; no direct MCU-rail drive into PCA9538 RESET.",
"ports": {
"P0": "RGB red cathode through 1k",
"P1": "RGB green cathode through 330 ohm",
"P2": "RGB blue cathode through 330 ohm",
"P3": "Buzzer MOSFET gate through 1k; 100k gate pulldown",
"P4-P7": "grounded inputs"
},
"power_indicator": "D17 red LED + 4.7k from board V3V3; does not indicate USB-only MCU power",
"alarm": "FUET-9650B-3V active buzzer; AO3400A low-side switch; BAV21W flyback diode",
"firmware_states": {
"blue": "commissioning lock",
"amber": "waiting for qualified telemetry/power after qualification",
"green": "qualified supply/telemetry; RUN reported separately over USB",
"red": "latched motor fault, reported driver fault or overtemperature; 200 ms alarm every 2 s"
},
"budget_status": "design allocation, not measured; buzzer max 30 mA specified at 3 V only, allow 60 mA at board-rail extremes pending qualification",
"gate_drive": "R126 1k limits charging to <3.7 mA at 3.6 V; R127 100k pulls Q26 gate low when expander is reset",
"qualification": "Current, sound, brightness, reset silence and source transitions require first-article measurements",
"incremental_logic_rail_budget_ma": 75
}
},
"motor_harness": {
"definition": "engineering/motor-harness.json",
"reference": "J2",
"header": "B4P-VH(LF)(SN)",
"pitch_mm": 3.96,
"mate": "VHR-4N",
"contacts": "SVH-41T-P1.1",
"contact_quantity": 4,
"termination_wire_awg": 16,
"wire_insulation_diameter_mm": [
1.7,
3.0
],
"rating_a_at_specified_wire": 10,
"rating_v": 250,
"wire_colours": [
"black",
"green",
"red",
"blue"
],
"pin_to_net": {
"1": "MOTOR_A1_OUT",
"2": "MOTOR_A2",
"3": "MOTOR_B1_OUT",
"4": "MOTOR_B2"
},
"motor_leads_mm2": 0.75,
"splice": "TE 320559, one 0.75 mm\u00b2 motor conductor to one 16 AWG pigtail per splice; four splices",
"splice_supported_wire_mm2": [
0.3,
1.42
],
"connection_status": "Defined harness; not supplied with PCB assembly. Harness maker must confirm crimp/insulation dimensions and provide continuity/pull-test records.",
"current_note": "JST 10 A applies to the standard header with 16 AWG termination, not directly to the motor factory 0.75 mm\u00b2 wire. Motor current is still governed by its qualification; no 10 A motor rating is implied."
},
"pd_programming": {
"definition": "docs/pd-programming.md",
"switch": "U36 SN74LVC2G66DCUR opens both I2Cc wires when TP_PD_ISO is grounded",
"target_power": "fixed 5 V supplied through J1; no EPR negotiation during fixture programming",
"programmer": "3.3 V open-drain, ground first, VCC output disabled; TP_PD_VREF is sense only",
"programming_status": "TI Full Flash candidate generated and register-reviewed; fixture acceptance, programming/readback, cold boot and fault/PD qualification pending"
},
"local_control": {
"start_stop": "SW2, PC6 / USER_BUTTON_N, active-low with R133 10k pullup to V3V3_MCU",
"reset": "SW1 / NRST",
"motion_mode": "TMC5160 internal SPI ramp; SD_MODE low; unused U7 pins 17,18,23,24,25 grounded",
"qualification": "Motion inhibited until TI configuration and powered bridge validation exist",
"external_command_interfaces": "None; J7 and STEP/DIR/ENABLE/home/limit conditioning removed",
"protection": "U10/U11/U33 and DRV_EN_N pullup retained; Q14 emitter grounded after removal of external-enable transistor Q15"
},
"input_protection": {
"reference": "U6",
"mpn": "TPS26630RGER",
"lcsc": "C1850276",
"mode": "1x active current limiting; MODE open latches faults",
"current_set_resistor": {
"reference": "R25",
"ohm": 4990,
"mpn": "RN73R1JTTD4991B25",
"lcsc": "C7293210",
"initial_tolerance_fraction": 0.001,
"tcr_ppm_per_c": 25,
"temperature_excursion_c": 100
},
"upstream_input_current_allocation_a": 0.25,
"upstream_allocation_status": "Design allocation including upstream logic and controller consumption; not a measured upper bound",
"limiting_status": "No 25.5 ms 2x pulse allowance; finite loop response and fast-trip transient remain subject to source/cable qualification",
"hardware_qualified": false
},
"brake_protection": {
"cutoff_resistor": {
"reference": "R66",
"ohm": 1200,
"mpn": "RT0603BRD071K2L",
"lcsc": "C136970",
"tolerance_fraction": 0.001,
"tcr_ppm_per_c": 25
},
"nominal_motor_cutoff_v": 53.20754716981132,
"scope": "Restricted, unloaded rotor commissioning screen only; motion remains inhibited",
"brake_continuity_detection_implemented": true,
"brake_fault_hardware_qualified": false,
"full_current_operation_authorized": false,
"brake_divider_resistor": {
"reference": "R61",
"ohm": 16200,
"mpn": "RT0603BRD0716K2L",
"lcsc": "C728583",
"tolerance_fraction": 0.001,
"tcr_ppm_per_c": 25
},
"continuity_scope": "Startup: three fresh distinct bus/return pairs. RUN: both ADC timestamps checked; mismatches get one fixed 100 ms retry window for multiplexed sampling skew, with stale ADC and hard bus range faults immediate at the next check. Physical detection/inhibit latency is unqualified; no brake-current, resistance or backup energy proof."
}
}