Hi
I am trying to connect the Pololu High-Power Stepper Motor Driver 36v4 with rasperry pi 5. so far not succeed.
i was using 24V for motor supply and programming in Python. I can write the spi register and read from it. but still not hold or mostion from the steppemotor.
Sleep and reset set to high and using jumper between v5 and VOREF.
VM is 24VDC.
The Raspberry Pi 5 is a 3.3V device; it is not 5V tolerant and can be permanently damaged by voltages above 3.3V. So, you should be connecting a 3.3V source to IOREF.
Please note that setting the RESET pin high resets all internal logic, including the indexer and device registers, and disables the driver outputs. I recommend just leaving it disconnected for now, and just driving the nSLEEP pin high as shown in the typical wiring diagram on the product page.
If that does not help, could you post more details about what you have tried? For example, what registers have you tried setting and what did you set them to? Also, please post some pictures of your setup that show all of your connections.
It looks like there are many problems with that code, including the structure of the SPI communication and the data bits you are sending; where did you get it from? I recommend using our High-Power Stepper Motor Driver Arduino Library as a reference for fixing your Python code (HighPowerStepperDriver.h in particular). While it is in a different programming language, the process should be similar.
Hi Brandon,
I have created this script to test it with the driver. But, it doesn’t work. Then I have tried the Arduino Nano with your example. it works fine. However i am not able to get it work with the raspberry pi 5. My last test script as follows: still no luck.
import spidev
import RPi.GPIO as GPIO
import time
print("=== ARDUINO NANO 3.3V SPI EXACT REPLICA ===")
print("Using Pi 5 with 3.3V IOREF - matching Arduino timing exactly")
print("VMOT=24V, IOREF=3.3V, SLEEP=3.3V confirmed")
# Pins (same as your Arduino Nano setup)
SCS_PIN = 22 # Arduino Nano CS pin equivalent
DIR_PIN = 17
STEP_PIN = 27
GPIO.setmode(GPIO.BCM)
GPIO.setup(SCS_PIN, GPIO.OUT)
GPIO.setup(DIR_PIN, GPIO.OUT)
GPIO.setup(STEP_PIN, GPIO.OUT)
# Arduino Nano 3.3V boot sequence
GPIO.output(SCS_PIN, GPIO.HIGH) # CS inactive at start
time.sleep(0.001) # Arduino delay(1)
# Arduino SPI setup - exact equivalent
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 250000 # Arduino Nano typical SPI speed at 16MHz / 64
spi.mode = 0b00
spi.bits_per_word = 8 # Arduino default
def arduino_spi_transfer(data16):
"""EXACT Arduino SPI.transfer16() replica"""
# Arduino sends 16-bit word: high byte first, then low byte
high_byte = (data16 >> 8) & 0xFF
low_byte = data16 & 0xFF
# Arduino: CS HIGH → transfer → CS LOW
GPIO.output(SCS_PIN, GPIO.HIGH)
time.sleep(0.000001) # 1us setup (Arduino overhead)
# Transfer high byte
spi.xfer2([high_byte])
time.sleep(0.000002) # Arduino clock period ~4us at 250kHz
# Transfer low byte
spi.xfer2([low_byte])
time.sleep(0.000001) # 1us hold time
# Arduino: CS LOW after transfer
GPIO.output(SCS_PIN, GPIO.LOW)
time.sleep(0.001) # Arduino delay between transfers
def arduino_write_reg(reg, value):
"""Arduino library writeReg() exact replica"""
data16 = ((reg & 0b111) << 12) | (value & 0xFFF)
arduino_spi_transfer(data16)
def arduino_read_reg(reg):
"""Arduino library readReg() exact replica"""
data16 = ((0x8 | (reg & 0b111)) << 12)
arduino_spi_transfer(data16)
# Arduino reads response during transfer - simulate with delay + read
time.sleep(0.0001)
resp = spi.xfer2([0x00, 0x00])
return ((resp[0] << 8) | resp[1]) & 0xFFF
print("\n=== Arduino Nano 3.3V Initialization Sequence ===")
# 1. Arduino library: sd.resetSettings() + sd.clearStatus()
print("1. Resetting settings and clearing status...")
arduino_write_reg(0x07, 0x000) # Clear STATUS
time.sleep(0.01) # Arduino delay
# 2. Arduino defaults from HighPowerStepperDriver constructor
print("2. Writing Arduino library default registers...")
arduino_write_reg(0x00, 0xC10) # CTRL
time.sleep(0.001)
arduino_write_reg(0x01, 0x1FF) # TORQUE
time.sleep(0.001)
arduino_write_reg(0x02, 0x030) # OFF
time.sleep(0.001)
arduino_write_reg(0x03, 0x080) # BLANK
time.sleep(0.001)
arduino_write_reg(0x04, 0x110) # DECAY
time.sleep(0.001)
arduino_write_reg(0x05, 0x040) # STALL
time.sleep(0.001)
arduino_write_reg(0x06, 0xA59) # DRIVE
# 3. Arduino example configuration: sd.setDecayMode(AutoMixed)
print("3. Setting AutoMixed decay mode...")
decay_val = (0b101 << 8) | 0x10 # bits 10:8 = 101
arduino_write_reg(0x04, decay_val)
# 4. Arduino example: sd.setCurrentMilliamps36v4(1000)
print("4. Setting current limit 1000mA (36v4)...")
# ISGAIN = 3 (11 binary), TORQUE = 0x50 for 1000mA at 3.3V IOREF
arduino_write_reg(0x00, 0xC30) # CTRL with ISGAIN=3
time.sleep(0.01)
arduino_write_reg(0x01, 0x50) # TORQUE for 1000mA
# 5. Arduino example: sd.setStepMode(MicroStep32)
print("5. Setting MicroStep32 mode...")
ctrl_val = arduino_read_reg(0x00) # Read current CTRL
step_mode = 0b0101 # MicroStep32 (bits 6:3)
ctrl_val = (ctrl_val & 0b111110000111) | (step_mode << 3)
arduino_write_reg(0x00, ctrl_val)
# 6. Arduino example: sd.enableDriver()
print("6. ENABLING DRIVER OUTPUTS...")
time.sleep(0.01)
final_ctrl = ctrl_val | 0x001 # Set ENBL bit 0
arduino_write_reg(0x00, final_ctrl)
print("\n=== TORQUE VERIFICATION ===")
print("Motor should IMMEDIATELY resist turning by hand")
print("This matches your working Arduino Nano 3.3V setup exactly")
# Wait for manual test
time.sleep(5)
holding = input("Does motor hold torque? (y/n): ").lower()
if holding == 'y':
print("\n🎉 SUCCESS! Pi 5 + 3.3V IOREF working!")
print("Now testing STEP/DIR motion...")
# Motion test
print("Testing CW 200 steps...")
GPIO.output(DIR_PIN, GPIO.HIGH) # CW
time.sleep(0.001)
for i in range(200):
GPIO.output(STEP_PIN, GPIO.HIGH)
time.sleep(0.002) # Arduino Nano step period / 2
GPIO.output(STEP_PIN, GPIO.LOW)
time.sleep(0.002)
print("CW complete")
time.sleep(1)
print("Testing CCW 200 steps...")
GPIO.output(DIR_PIN, GPIO.LOW) # CCW
time.sleep(0.001)
for i in range(200):
GPIO.output(STEP_PIN, GPIO.HIGH)
time.sleep(0.002)
GPIO.output(STEP_PIN, GPIO.LOW)
time.sleep(0.002)
print("CCW complete - motor should be back to start")
else:
print("\n No torque - Pi 5 SPI still incompatible")
print("Even with exact Arduino 3.3V replication")
print("\nSolutions:")
print("1. Arduino Nano bridge (Pi serial → Arduino SPI)")
print("2. Different Pi model (Pi 4/3)")
print("3. Commercial SPI buffer IC")
# Cleanup
GPIO.output(SCS_PIN, GPIO.HIGH)
spi.close()
GPIO.cleanup()
print("Test complete.")
I still see several errors with the values you are writing to the registers. For example, you are hard-coding the CTRL register to 0xC30 when trying to set the ISGAIN bits to 0x11, but the ISGAIN bits are bits 8 and 9 of the CTRL register, which are both 0 in 0xC30 (0b110000110000). Is there a reason you are hard-coding those values instead of making them like the Arduino library does? It looks like some other portions of your code do it that way.
Also, your TORQUE value also does not seem correct for setting the current limit to 1000mA. However, at this point, instead of continuing to troubleshoot the code line-by-line, I recommend simplifying it down as much as possible by trying to just write to a register and read back the change. Once you can confirm that is working, then we can work out the proper values.
import os
os.environ["RPI_LGPIO_CHIP"] = "0"
import RPi.GPIO as GPIO
import time
from HighPowerStepperDriver import HighPowerStepperDriver, HPSDStepMode, HPSDDecayMode
GPIO.setmode(GPIO.BCM)
CS_PIN = 4 # Chip select pin (use your available output GPIO)
STEP_PERIOD_US = 5 # microseconds
noofsteps = 64000 # steps
# Set up the stepper driver
sd = HighPowerStepperDriver(CS_PIN)
def setup():
time.sleep(0.001) # 1 ms wait for driver power-up
# Reset and clear
sd.reset_settings()
sd.clear_status()
# Set decay mode (AutoMixed is recommended for most)
sd.set_decay_mode(HPSDDecayMode.AutoMixed)
# Set current limit (change value as needed)
sd.set_current_milliamps_36v4(500)
# Microstepping (e.g. 32 microsteps per full step)
sd.set_step_mode(HPSDStepMode.MicroStep32)
# Enable motor outputs
sd.enable_driver()
def loop():
while True:
# Step 1000 times in one direction.
sd.set_direction(False)
for _ in range(noofsteps):
sd.step()
time.sleep(STEP_PERIOD_US / 1_000_000.0)
time.sleep(0.3)
# Step 1000 times in the other direction.
sd.set_direction(True)
for _ in range(noofsteps):
sd.step()
time.sleep(STEP_PERIOD_US / 1_000_000.0)
time.sleep(0.3)
if __name__ == "__main__":
try:
setup()
loop()
except KeyboardInterrupt:
pass
finally:
sd.disable_driver()
GPIO.cleanup()