This article shows how to control a stepper motor with Raspberry Pi and driver(L6470).
Contents
- Parts required to control a stepper motor
- Connection of each parts
- Commands for controlling motor driver (L6470)
- Python sample code
sponsored link
Parts required to control a stepper motor.
In the beginning, I show parts required to control a stepper motor.
Stepper motor
I used this stepper motor.
( Sorry, link to Japanese shop )
Alternatives on Amazon US.
Motor driver
A drive kit with a built-in motor driver IC (L6470) was bought from Akizuki Denshi Tsusho.
( Sorry, link to Japanese shop )
DC 12V power adapter
The power supply was selected to match the operating voltage of the stepper motor, 12V.
Jumper wire
This product is a set of male-male, male-female, and female-female.
sponsored link
Connection of each parts
From here, I show how to connect each part.
GPIO and the 40-pin Header on Raspberry Pi 4
Here is the pinout of the Raspberry Pi.
quotation : Raspberry Pi Documentation
The pinouts of the Raspberry Pi can also be viewed by using the terminal.
Enter the following command in the terminal and the pinouts of the Raspberry Pi will be displayed.
$ pinout
Connection of each part
SPI communication is used for control between Raspberry Pi and a motor driver(L6470).
Therefore, connect the pins involved in SPI communication together.
sponsored link
Commands for controlling motor driver (L6470)
Refer to the L6470 datasheet to grasp about the commands for controlling the motor driver.
The data sheet can be downloaded here.
The following is a brief introduction to control commands.
As an example, I describe "Run(DIR,SPD)" command for speed specified rotation.
Note that binary numbers must be converted to hexadecimal numbers in order to send control commands.
The following is the result of the conversion from binary to hexadecimal in Excel.
The 0th bit of Run(DIR,SPD) is used to input the direction of rotation.
"0" or "1" is to be entered, in this example "1" is entered.
In this example, "51" in hexadecimal should be sent.
sponsored link
Python sample code
I show Python sample code.
Install the library for SPI communication
The library for SPI communication must be installed in advance.
Install "WiringPi" on Raspberry Pi.
With "WiringPi", GPIO can be easily accessed.
Enter the following command in the terminal to install the library.
$ sudo pip3 install wiringpi
A library called "RPi.GPIO" is also used, which is installed by default in Raspberry Pi if the OS is Raspbian.
Python sample code for controlling a stepping motor
I show python sample code for controlling a stepping motor.
### sample code
import wiringpi as wp
import RPi.GPIO as GPIO
import struct
import time
import sys
### --- Parameters for connection --- ###
SPI_CH = 0 # SPI channel
SPI_HZ = 1000000 # SPI communication speed
GPIO_Nbr = 25 # GPIO-NO
GPIO.setmode(GPIO.BCM) # GPIO-NO mode
GPIO.setup(GPIO_Nbr,GPIO.IN) # GPIO INPUT mode
### --------------------------- ###
# L6470 initialization
def INIT_L6470():
spi_send([0x00,0x00,0x00,0xc0]) # Reset Device
spi_send([0x05,0x00,0x0e]) # Acceleration (12)
spi_send([0x06,0x00,0x0e]) # Deceleration (12)
spi_send([0x07,0x00,0x0e]) # Maximum speed (10)
spi_send([0x08,0x00,0x01]) # Minimum speed (13)
spi_send([0x15,0x03,0xFF]) # Full-step speed (10)
spi_send([0x16,0x03]) # Micro Step (8)
spi_send([0x09,0x50]) # Holding Kval (8)
spi_send([0x0A,0x50]) # Constant Speed Kval (8)
spi_send([0x0B,0x50]) # Acceleration starting Kval (8)
spi_send([0x0C,0x50]) # Deceleration starting Kbal (8)
# SPI data sending
def spi_send(spi_dat_ary):
for itm in spi_dat_ary:
tmp=struct.pack("B",itm)
wp.wiringPiSPIDataRW(SPI_CH, tmp)
# data processing & sending
def L6470_SEND_MOVE_CMD( cmd , DAT ):
tmp=[]
tmp.append(cmd)
tmp.append((0x0F0000 & DAT) >> 16)
tmp.append((0x00FF00 & DAT) >> 8)
tmp.append((0x00FF & DAT))
print(tmp)
spi_send(tmp)
# Constant speed rotation (SPEED : 0---30000)
def L6470_run(run_spd):
# Set the direction of rotation
if (run_spd > 0):
dir = 0x50 #Run & Set the direction of rotation
spd = run_spd
else:
dir = 0x51 #Run & Set the direction of rotation
spd = -1 * run_spd
L6470_SEND_MOVE_CMD( dir , spd )
# Operation by amount of movement
def L6470_POSITIONING(MV_DIST):
# Set the direction of rotation
if (MV_DIST > 0):
dir = 0x40 #Move & Set the direction of rotation
else:
dir = 0x41 #Move & Set the direction of rotation
MV_DIST = -1 * MV_DIST
L6470_SEND_MOVE_CMD( dir , MV_DIST )
# Operation by absolute position
def L6470_MOVE_ABS(MV_DIST):
dir = 0x60 #GoTo
if (MV_DIST < 0):
MV_DIST = -1 * MV_DIST
L6470_SEND_MOVE_CMD( dir , MV_DIST )
# Stopping
def L6470_STOP():
spi_send([0xB0]) # SoftStop
time.sleep(0.2)
spi_send([0xA8]) # HardHiZ
time.sleep(0.2)
# Set origin
def L6470_SET_ORIGIN():
spi_send([0xD8]) # Reset Position
time.sleep(0.5)
# Moving to origin
def L6470_MOVE_ORIGIN():
spi_send([0x70]) # GoHome
time.sleep(0.5)
# Waiting for driver BUSY release
def wait_until_not_busy():
while True:
time.sleep(0.2)
mtr_sts = GPIO.input(GPIO_Nbr)
#print(mtr_sts)
if GPIO.input(GPIO_Nbr) == GPIO.HIGH :
print("L6470 NOT BUSY")
break
time.sleep(0.2)
##################################
# Main
##################################
if __name__ == "__main__":
wp.wiringPiSPISetup(SPI_CH,SPI_HZ) # SPI
INIT_L6470() # L6470 initialization
# Constant speed rotation
print("CONSTANT SPEED ROTATION START")
spd_run = 8000
L6470_run(spd_run)
print("Speed : %d" % spd_run)
time.sleep(5)
L6470_STOP()
print("STOP")
time.sleep(1)
spd_run = -8000
L6470_run(spd_run)
print("Speed : %d" % spd_run)
time.sleep(5)
L6470_STOP()
print("STOP")
time.sleep(1)
print("CONSTANT SPEED ROTATION FINISHED")
print("")
# Operation by amount of movement
print("STEP ROTATION START")
rng=10
step = int(1600 / rng)
for i in range(rng):
L6470_POSITIONING(step) # Operation by amount of movement
wait_until_not_busy() # Waiting for driver BUSY release
print("STEP ROTATION FINISHED")
print("")
# Operation by absolute position
print("ABS ROTATION START")
L6470_SET_ORIGIN() # Set origin
rng=10
step = int(3*(1600 / rng))
for i in range(rng):
L6470_MOVE_ABS((i+1)*step) # Operation by absolute position
wait_until_not_busy() # Waiting for driver BUSY release
L6470_MOVE_ORIGIN() # Moving to origin
print("ABS ROTATION FINISHED")
GPIO.cleanup()
Video of the three modes of operation are shown below.
- Constant speed rotation
- Operation by amount of movement
- Operation by absolute position
sponsored link