PR

【第6回】Raspberry PiでXYテーブル制御|Pythonでステッピングモーターを2軸同時に動かす(XYテーブル製作シリーズ)

スポンサーリンク
RaspberryPi

はじめに

この記事では XYテーブルの2軸を同時に動かす方法 を解説します。

前回の記事では
・X軸単体
・Y軸単体
を動かしました。

しかしXYテーブルでは
・XとYを同時に動かす
・斜め移動などを実現する
必要があります。

そこで今回は Pythonのスレッド(threading) を使って
2つのモーターを同時に動作させる方法 を解説します。

今回のゴール

今回のプログラムで出来ること

X軸 → 50mm
Y軸 → 30mm

X軸とY軸を同時に動作させる
つまり
斜め移動ができる
が実現できます

これは XYテーブル制御の基本動作 になります。

ハードウェア構成

今回使用する部品は以下です。

部品型番
マイコンRaspberry Pi 3 Model A+
モータードライバA4988
モーターNema17
電源12V 5A

GPIO ピン設定

今回のピン配置です。

X軸
X_STEP = 21
X_DIR = 20
X_EN = 16
X_MS1 = 17
X_MS2 = 27
X_MS3 = 22
X_RESET = 5
X_SLEEP = 6
Y軸
Y_STEP = 2
Y_DIR = 26
Y_EN = 18
Y_MS1 = 23
Y_MS2 = 24
Y_MS3 = 25
Y_RESET = 12
Y_SLEEP = 13

■ハードウェアを結線する際にあると便利なツール

Pythonで同時制御する方法

Pythonでは

threading

という機能を使うと

複数の処理を同時に動かす

ことができます。

今回のプログラムでは

X軸スレッド
Y軸スレッド

を同時に起動します。

Pythonコード

import RPi.GPIO as GPIO
import time
import threading

GPIO.setmode(GPIO.BCM)

# -------------------------
# X軸
# -------------------------
X_STEP = 21
X_DIR = 20
X_EN = 16
X_MS1 = 17
X_MS2 = 27
X_MS3 = 22
X_RESET = 5
X_SLEEP = 6

# -------------------------
# Y軸
# -------------------------
Y_STEP = 2
Y_DIR = 26
Y_EN = 18
Y_MS1 = 23
Y_MS2 = 24
Y_MS3 = 25
Y_RESET = 12
Y_SLEEP = 13

# -------------------------
# モーション設定
# -------------------------
BELT_PITCH = 2.0
PULLEY_TEETH = 32

MM_PER_REV = BELT_PITCH * PULLEY_TEETH

FULL_STEPS = 200
MICROSTEP = 16

STEPS_PER_REV = FULL_STEPS * MICROSTEP
STEPS_PER_MM = STEPS_PER_REV / MM_PER_REV

ACC_DEC_STEPS = 100


# -------------------------
# GPIO初期化
# -------------------------
def gpio_init_axis(STEP, DIR, EN, MS1, MS2, MS3, RESET, SLEEP):

pins = [STEP, DIR, EN, MS1, MS2, MS3, RESET, SLEEP]

for p in pins:
GPIO.setup(p, GPIO.OUT)

GPIO.output(RESET, GPIO.HIGH)
GPIO.output(SLEEP, GPIO.HIGH)

GPIO.output(MS1, GPIO.HIGH)
GPIO.output(MS2, GPIO.HIGH)
GPIO.output(MS3, GPIO.HIGH)

GPIO.output(EN, GPIO.LOW)


# -------------------------
# 加減速計算
# -------------------------
def get_intervals(total_steps, acc_steps, total_time):

const_steps = max(total_steps - acc_steps*2, 1)

total_ratio = acc_steps*0.5 + const_steps + acc_steps*0.5

base_interval = total_time / total_ratio / 2

intervals = []

for i in range(acc_steps):
intervals.append(base_interval*(acc_steps-i)/acc_steps)

for i in range(const_steps):
intervals.append(base_interval)

for i in range(acc_steps):
intervals.append(base_interval*(i+1)/acc_steps)

return intervals


# -------------------------
# モーター制御
# -------------------------
def run_motor(axis_name,
STEP, DIR, EN,
MS1, MS2, MS3,
RESET, SLEEP,
distance_mm, cycles):

print(axis_name,"開始")

gpio_init_axis(STEP,DIR,EN,MS1,MS2,MS3,RESET,SLEEP)

steps = int(distance_mm * STEPS_PER_MM)

intervals = get_intervals(steps, ACC_DEC_STEPS, 1.5) # 1.5秒で加減速込みの移動を完了させる

for c in range(cycles):

# 正転
if axis_name == "X軸":
GPIO.output(DIR,GPIO.LOW)
else:
GPIO.output(DIR,GPIO.HIGH)

for t in intervals:

GPIO.output(STEP,GPIO.HIGH)
time.sleep(t)

GPIO.output(STEP,GPIO.LOW)
time.sleep(t)

# 逆転
if axis_name == "X軸":
GPIO.output(DIR,GPIO.HIGH)
else:
GPIO.output(DIR,GPIO.LOW)

for t in intervals:

GPIO.output(STEP,GPIO.HIGH)
time.sleep(t)

GPIO.output(STEP,GPIO.LOW)
time.sleep(t)

GPIO.output(EN,GPIO.HIGH)

print(axis_name,"終了")


# -------------------------
# XY同時スタート
# -------------------------
def start_both():

x_dist = 60 # 移動距離(mm)
x_cycle = 1 # 移動回数

y_dist = 30 # 移動距離(mm)#
y_cycle = 2 # 移動回数

tx = threading.Thread(
target=run_motor,
args=("X軸",
X_STEP, X_DIR, X_EN,
X_MS1, X_MS2, X_MS3,
X_RESET, X_SLEEP,
x_dist, x_cycle)
)

ty = threading.Thread(
target=run_motor,
args=("Y軸",
Y_STEP, Y_DIR, Y_EN,
Y_MS1, Y_MS2, Y_MS3,
Y_RESET, Y_SLEEP,
y_dist, y_cycle)
)

tx.start()
ty.start()

tx.join()
ty.join()


# -------------------------
# 実行
# -------------------------
try:

start_both()

finally:

GPIO.cleanup()

実行方法

Raspberry Piで以下を実行します。

python3 XY_both_move.py

すると

X軸 → 50mm
Y軸 → 30mm

同時に動作します。

次回予告

次回はいよいよ

XYテーブルの安全制御

を実装します。

具体的には

  • リミットスイッチ
  • 原点復帰(Homing)
  • 移動範囲制限

を追加します。

これにより

実用レベルのXYテーブル制御

に近づきます。

スポンサーリンク

過去のXYテーブル製作シリーズはこちらから

コメント