PR

ステッピングモーターの脱調を防ぐ!Pythonで加減速制御(台形駆動)を実装する方法(自作CNC #5)

スポンサーリンク
RaspberryPi

はじめに

「モーターを速く動かそうとすると、ガガガと異音がして止まってしまう……」

これは「脱調」と呼ばれる現象で、静止状態からいきなり高速で回そうとすることが原因です。自作XYテーブルを実用的なスピードで、かつ正確に動かすためには、速度を徐々に変化させる「加減速制御」が欠かせません。

今回は、Pythonを使って「台形駆動(スローアップ・スローダウン)」を実装する方法を解説します。このアルゴリズムをマスターして、あなたの装置をワンランク上の滑らかな動きへと進化させましょう!

加減速の仕組みと「待ち時間」のコントロール

前ステッピングモーターを滑らかに動かす「台形駆動」

停止しているモーターをいきなり高速で回そうとすると、負荷に耐えきれず「脱調(空回り)」して止まってしまいます。これを防ぐために、以下の3つのフェーズに分けて速度を制御します。これを**「台形駆動(速度プロファイル)」**と呼びます。

  • 加速区間(スローアップ): 徐々に速度を上げる
  • 定速区間: 目標の最高速度で維持する
  • 減速区間(スローダウン): 停止に向けて徐々に速度を落とす

台形駆動(速度プロファイル)のイメージ

ステッピングモーターを滑らかに動かす「台形駆動」イメージ

今回作る関数

この制御を実現するために、ステップごとの**「待ち時間(interval)」**を計算する関数 get_intervals() を作成します。

get_intervals()

Pythonの time.sleep(interval) で使うこの値は、**「数値が小さくなるほど、モーターは速く回る」**という性質があります。

フェーズ待ち時間(例)モーターの状態
加速0.005 → 0.003 → 0.001どんどん速くなる
低速0.001 (一定)一定の速さで回る
減速0.001 → 0.003 → 0.005どんどん遅くなる

使用するハードウェアと配線について

「【第4回】XYテーブル化の第一歩|X軸とY軸を2台同時に動かす」と
同じハードウェア構成、配線にて行います

【第4回】XYテーブル化の第一歩|X軸とY軸を2台同時に動かす

Pythonプログラム

X軸のみの実装になります
Y軸は今回の記事では動作させません。

import RPi.GPIO as GPIO
import time

# =====================================================
# GPIO モード設定
# =====================================================
GPIO.setmode(GPIO.BCM)

# ===== PIN設定 =====
X_STEP = 21
X_DIR = 20
X_EN = 16
X_MS1 = 17
X_MS2 = 27
X_MS3 = 22
X_RESET = 5
X_SLEEP = 6

# =====================================================
# モーション設定(将来互換)
# =====================================================
BELT_PITCH = 2.0
PULLEY_TEETH = 32
FULL_STEPS_PER_REV = 200
MICROSTEP = 16

MM_PER_REV = BELT_PITCH * PULLEY_TEETH
STEPS_PER_REV = FULL_STEPS_PER_REV * MICROSTEP
MM_PER_STEP = MM_PER_REV / STEPS_PER_REV

# =====================================================
# GPIO 初期化関数(rev4互換)
# =====================================================
def gpio_init_axis(STEP, DIR, EN, MS1, MS2, MS3, RESET, SLEEP):

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

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

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

# 1/16 マイクロステップ
GPIO.output(MS1, GPIO.HIGH)
GPIO.output(MS2, GPIO.HIGH)
GPIO.output(MS3, GPIO.HIGH)


# ===== 加減速プロファイル作成 =====
def get_intervals(total_steps):

min_delay = 0.003 # 最高速
max_delay = 0.009 # 最低速

accel_steps = total_steps // 3
decel_steps = accel_steps
const_steps = total_steps - accel_steps - decel_steps

intervals = []

# 加速
for i in range(accel_steps):
ratio = i / accel_steps
delay = max_delay - (max_delay - min_delay) * ratio
intervals.append(delay)

# 定速
for i in range(const_steps):
intervals.append(min_delay)

# 減速
for i in range(decel_steps):
ratio = i / decel_steps
delay = min_delay + (max_delay - min_delay) * ratio
intervals.append(delay)

return intervals


# ===== 移動関数(加減速付き) =====
def move_mm(distance_mm, direction):

steps = int(distance_mm / MM_PER_STEP)

GPIO.output(X_DIR, direction)

intervals = get_intervals(steps)

for delay in intervals:

GPIO.output(X_STEP, GPIO.LOW)
time.sleep(delay)

GPIO.output(X_STEP, GPIO.HIGH)
time.sleep(delay)


try:

print("50mm 正転(加速 → 定速 → 減速)")
move_mm(50, GPIO.LOW)

time.sleep(1)

print("50mm 逆転(加速 → 定速 → 減速)")
move_mm(50, GPIO.HIGH)

finally:

GPIO.cleanup()

この記事で使用したコードはこちらからダウンロードできます。

X_Move_acc_dec.py をダウンロード(ZIP)

プログラムのポイント

get_intervals()

この関数が加減速の核心です。

delay = max_delay - (max_delay - min_delay) * ratio

delay = min_delay + (max_delay - min_delay) * ratio

ratioを使って徐々に待ち時間を短くしています。

実行するとどうなる?

モーターの動きが次のように変わります。

以前

一定速度
ガガガガガガ

今回

ゆっくり → 速く → ゆっくり

動きがかなり滑らかになります。

XYテーブル製作シリーズの現在地

現在のシリーズの進行状況です。

内容
第1回LEDを光らせる
第2回モーターを回す
第3回A4988でモーター制御
第4回XYの2軸制御
第5回加減速制御 ← 今回

次回予告

次回はいよいよ

XY同時制御(直線補間)

を実装します。

これができると

斜め移動
円弧
図形描画

などが可能になります。

XYテーブル制御の核心部分です。

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

スポンサーリンク

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

コメント