Skip to content

Troubleshooting

Symptoms you may see while bringing up a TMC5160 or TMC5130, their causes and the fix for each.

Start with the cheapest check: read the chip version with io.ReadIcVersion(). 0x30 (TMC5160) or 0x11 (TMC5130) proves the bus, the straps and the supplies at once. Then build with logging on (the default) and read what Initialize() and printer.PrintAll() report.

The chip does not answer

Symptom Cause Fix
Every read returns 0x00000000 MISO not connected, VCC_IO missing, or the chip held in UART mode Check SDO wiring and VCC_IO; SPI_MODE must be high (it has an internal pull-down)
Every read returns 0xFFFFFFFF MISO floating high, wrong chip select, or VS / VSA off (the chip stays in reset below about 4 V on VSA) Check CSN, and that VS is in range
Values shifted by a few bits Wrong SPI mode Use mode 3 (CPOL = 1, CPHA = 1)
Random errors at higher clock rates SCK above 4 MHz on the internal clock, or long wires Lower the clock; 1 MHz is a safe start
Second chip in a chain reads wrong values Chain length unknown or wrong, or SDO / SDI order swapped SetDaisyChainLength(n); position 0 is the chip on MOSI (Multi-chip)
UART: every read fails with COMM_ERROR The echo of the request is returned as the reply, or a CRC error Discard the echo in UartSend(); check the baud rate (9000 to fCLK/16)
UART: a node does not answer at its address NODECONF lost after a power cycle, or NAO not driven low Re-run the addressing after every power-up (TMC51x0MultiNode::ProgramSequentially() drives NAO low for you)

The motor does not move

Symptom Cause Fix
Ramp calls return INVALID_STATE SD_MODE is high: the chip expects STEP/DIR Strap SD_MODE low for the internal ramp generator
Calls return NOT_INITIALIZED Initialize() failed or was not called Check its result and ErrorMessage()
Enable() returns an error Your GpioSet(EN, ...) failed; UNSUPPORTED (pin not wired) is accepted Map EN in your port, or return UNSUPPORTED when DRV_ENN is hard-wired low
No holding torque after Enable() DRV_ENN not low: the active level of EN is wrong, or the pin is not wired and not tied low Check io.ReadInputStatus().Value().drv_enn is false after Enable()
Holding torque but no motion VMAX or AMAX is 0, or the target equals the current position Set a speed and an acceleration before the target
Motion calls in mm return INVALID_VALUE Unit::Mm without a lead screw or belt in mechanical Configure DriverConfig::mechanical (Motion and units)
GSTAT.uv_cp set Charge pump undervoltage VS below 10 V, or the charge-pump capacitors (22 nF CPI–CPO, 100 nF VCP–VS) missing

The motor moves badly

Symptom Cause Fix
Vibrates, loses steps, weak Current too low, or sense_resistor_mohm wrong Check the motor and board values; LogDerivedInitSummary() shows the currents
Runs hot Current too high, or hold current too high Lower run_current_ma / hold_current_ma; check sense_resistor_mohm
Jerks or stalls at the first move after power-up StealthChop automatic tuning has not run Make the first move at moderate speed with IRUN ≥ 8
Loud at low speed SpreadCycle Enable StealthChop below TPWMTHRS (Current and chopper)
Speeds off by a few percent Internal oscillator tolerance (12 MHz ± 0.5 MHz) Feed an external clock and set external_clk_config.frequency_hz
Short-to-GND flags (s2ga, s2gb) Shorted motor wire, or a gate-drive problem Fix the wiring; the bridge stays off until DRV_ENN or TOFF = 0 resets it

StallGuard and homing

Symptom Cause Fix
SG_RESULT always 0 or always 1023 StealthChop active, or speed below TCOOLTHRS Use SpreadCycle and move above TCOOLTHRS
Stall reported without a load SGT too low, or speed too low Raise SGT; home faster; run tuning.AutoTuneStallGuard()
Hits the stop without detecting it SGT too high, or current too high Lower SGT; reduce the current during homing
Homing results vary Search speed or current differ from those used for tuning Tune and home with the same speed and current

Building

Symptom Cause Fix
tmc51x0_version.h not found The header is generated by CMake Link the hf_tmc51x0 target (or the ESP-IDF component) instead of adding include paths by hand
SetTargetPosition(int32_t) is private The raw overload is internal Use SetTargetPosition(value, Unit::Steps)