概要
ArduinoUnoからL6470ドライバーを利用したステッピングモーター制御について投稿したことがあります。
今回はRaspberryPi4 ModelB(ラズパイ)からの制御について調査しました。プログラムは python です。
結果
次の3つの運転モードを確認した動画です。(2倍速再生)
①回転方向・速度を指定するJOG運転
②移動量を指定するステップ運転
③基準に対する絶対位置指定する位置決め運転
画面上にある主な構成機器は次の通りです。
①RaspberryPi Model B (画面左前)
②ステッピングモーター(画面中央)
(秋月電子:SM-42BYG011-25)
③L6470 ドライバー(画面中央奥)
(秋月電子:AE-L6470DRV)
④直流12V電源(画面右奥)
配線接続
配線接続は次の図の通りにしています。
参考に RaspberryPi Model B ピンアサインを掲載します。範囲が狭いので、ピンソケット(2X5=10P [FH-2x5SG] )で接続しました。
ラズパイ側のSPI設定
ラズパイ設定用ウィンドウで SPI 設定を有効にします。
Windowsでいうスタートメニュー(?)から、「設定」ー「Raspberry Piの設定」で設定ウィンドウを開きます。
「インターフェース」タブで SPI を有効にし「OK」します。
ターミナルから「lsmod | grep spi」コマンドで「spi_bcm2835」が表示されれば、SPI接続は有効になっている様です。
次に下記コマンドで「wiringpi」をインストールします。python から SPI 接続する為に使いました。
sudo pip3 install wiringpi
ターミナルからの SPI 有効確認と「wiringpi」インストールの状況を次の図に示します。
プログラム
プログラムです。
import wiringpi as wp
import RPi.GPIO as GPIO
import struct
import time
import sys
SPI_CH = 0 # SPI チャンネル
SPI_HZ = 1000000 # SPI 通信速度
GPIO_Nbr = 25 # GPIO-NO
GPIO.setmode(GPIO.BCM) # GPIO-NO 指定
GPIO.setup(GPIO_Nbr,GPIO.IN) # GPIO INPUT 指定
# L6470初期設定
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 データ送信
def spi_send(spi_dat_ary):
for itm in spi_dat_ary:
tmp=struct.pack("B",itm)
wp.wiringPiSPIDataRW(SPI_CH, tmp)
# JOG (SPEED指定 : 0---30000)
def L6470_run(run_spd):
# 方向検出
if (run_spd > 0):
dir = 0x50
spd = run_spd
else:
dir = 0x51
spd = -1 * run_spd
L6470_SEND_MOVE_CMD( dir , spd )
# 移動量指定移動
def L6470_POSITIONING(MV_DIST):
# 方向検出
if (MV_DIST > 0):
dir = 0x40
else:
dir = 0x41
MV_DIST = -1 * MV_DIST
L6470_SEND_MOVE_CMD( dir , MV_DIST )
# 絶対位置指定移動
def L6470_MOVE_ABS(MV_DIST):
dir = 0x60
if (MV_DIST < 0):
MV_DIST = -1 * MV_DIST
L6470_SEND_MOVE_CMD( dir , MV_DIST )
# データ加工・送信(共通)
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))
spi_send(tmp)
# テスト運転(JOG運転)
def L6470_DEMO():
spd_run = 0
inc_spd = 8000
print("DEMO STARTED")
while True:
rng = 4
for i in range(rng):
inc_spd_d = inc_spd
if i >= int(rng/2):
inc_spd_d = -1 * inc_spd
spd_run = spd_run + inc_spd_d
if spd_run <= 0:
break
L6470_run(spd_run)
print("Speed : %d" % spd_run)
time.sleep(2)
L6470_STOP()
print("DEMO FINISHED")
print("")
time.sleep(1)
break
# 停止指令
def L6470_STOP():
spi_send([0xB0]) # SOFT STOP
time.sleep(0.2)
spi_send([0xA8]) # Hard HiZ
time.sleep(0.2)
# 原点設定
def L6470_SET_ORIGIN():
spi_send([0xD8]) # Reset Position
time.sleep(0.5)
# 原点移動
def L6470_MOVE_ORIGIN():
spi_send([0x70]) # Go Home
time.sleep(0.5)
# ドライバーBUSY解除待ち
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)
##################################
# メインプログラム
##################################
if __name__ == "__main__":
wp.wiringPiSPISetup(SPI_CH,SPI_HZ) # SPI 接続
INIT_L6470() # L6470初期設定
# テスト運転(JOG運転)
L6470_DEMO() # テスト運転(JOG運転)
# 移動量指定移動
print("STEP ROTATION START")
rng=10
step = int(1600 / rng)
for i in range(rng):
L6470_POSITIONING(step) # 移動量指定移動
wait_until_not_busy() # ドライバーBUSY解除待ち
print("STEP ROTATION FINISHED")
print("")
# 絶対位置指定移動
print("ABS ROTATION START")
L6470_SET_ORIGIN() # 原点位置設定(0)
rng=10
step = int(3*(1600 / rng))
for i in range(rng):
L6470_MOVE_ABS((i+1)*step) # 絶対位置指定移動
wait_until_not_busy() # ドライバーBUSY解除待ち
L6470_MOVE_ORIGIN() # 原点位置移動
print("ABS ROTATION FINISHED")
GPIO.cleanup()
まとめ
最初、「spidev」というライブラリを試したところ、正確に動かなかったので「wiringpi」を使ってみました。 データ形式等が異なるのだと思いますが、基礎知識欠如により対応できませんでした。時間があればまた試してみたいと思います。
一方、ラズパイは多用途で利用できるので、組み合せた使い方も検討していきたいと思います。
「ラズパイ4 ステップモーターを動かす(L6470 SPI接続)」への1件のフィードバック