RaspberryPi

How to control a stepper motor with Raspberry Pi and driver(L6470).

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

-RaspberryPi
-