Modbusの利用 (8) 回すだけ EVALKIT-ROBOT-1ブラシレス・モータ・キット①

 EVALKIT-ROBOT-1は、STMicroelectronicsが用意したマイコン・ボードとエンコーダ付きブラシレスDCモータの開発キットです。マウザーで入手しました。マイコンSTSPIN32F0Aは、600mAの電流能力(シンクおよびソース)でパワーMOSFETを駆動できるトリプルハーフブリッジ・ゲート・ドライバが組み込まれているなど、モータ駆動に適したスペックをもっています。
 デモ用のソース・コードがダウンロードできます。モータを動作させる指令は、Modbus/RTUで行います。

 ここでは、RS-485インターフェースからModbus/RTUのコマンド発行を、Windows10のPython3を使って行います。

モータのおもなスペック

 このキットには、モータが付属します。Maxon EC-i 40にエンコーダENX 16 EASYが取り付けられています。

  • 動作電圧 36V
  • 回転数 3950rpm
  • トルク 207mNm(ストール時3160mNm)
  • 電流 2.72A(ストール時42.2A)
  • エンコーダの電源電圧 5V
  • エンコーダの動作電流 22mA
  • エンコーダの発生パルス数 1024
  • エンコーダの最大回転数 30krpm

制御ボードのおもなスペック

  • 動作電圧 12~45V
  • RS-485 デフォルト19200bps(デバイスは最大20Mbps、ボード上で250kbpsに制限)、8ビット、パリティなし、1ストップ・ビット
  • Modbus/RTU デフォルトのスレーブ・アドレス;1

接続

 モータ用に専用の黒いコネクタJ10、エンコーダ用に専用の赤いコネクタJ4があり、それぞれつなぎます。

 ターミナルJ7は電源をつなぎます。ここでは12Vの電池をつなぎました。ターミナルJ8はRS-485のA+とB-をつなぎます。GNDとターミネートは何もつながずに実験しています。

 USB-RS485アダプタをPCとつなぎます。

 USB-RS485アダプタをPCにつないで、デバイスマネージャを見ます。COM8に接続されたようです。

Getting started with the EVALKIT-ROBOT-1 - User manual

を参照します。

回転させるためにModbusコマンドが用意されている

 Modbusは、Modicon社がPLCに用意した、RS-485およびTCP/IPに対応した制御用のコマンド体系の一つです。

 このモータ・キットでは、Modbusのコマンドは三つ用意されています。

Discrete inputs(02 Read Input Status)

 入力アドレス0 読み取った1バイトの最後の2ビット。

 ALIGN(ビット1)は、初期位置合わせ手順が成功したかどうかを示す
  •1 =>位置合わせ手順が完了した
  •0 =>位置合わせ手順は完了していない
 DONE(ビット0)は、目標位置に到達したかどうかを示す
  •1 =>目標位置に到達した
  •0=>目標位置に達していない

03 Holding registersで読み出し、06 Preset Single Registerで書き込み

 次のモーションを定義するために使われる3バイト。

0 度(degrees)単位の目標位置(最下位バイト)
1 度単位の目標位置(最上位バイト)
2 ms単位の移動時間(目標移動時間は9の倍数(45、9000、999など))

Coils(05 Force Single Coil)

 MOVE(ビット0)をHighに設定する(0xffを書き込む)と、保持レジスタ(Holding registers)に定義されたモーション・コマンドが実行されます。

モーション・コマンドを送る手順

  • ステップ1 アドレス0の入力ビット0(Done)を読み取り、前のコマンドの動作が完了したかどうかを確認する。
  • ステップ2 目標位置と予想位置決め時間をそれぞれの保持レジスタに書き込む。
  • ステップ3 モーションを開始するには、アドレス0のコイルビット0をHighに設定する。 アドレス0のディスクリート入力ビット0は、動作中に強制的にLowになる

 上記のステップを指定することで、モータは、1;S字加速、2;クルーズ;3;減速の三つのパターンをこなして目標の位置へ回転させます。目標の位置へはPID制御が行われます。デモ・ソフトでは、高速に回転させた場合、オーバランした後設定角度に戻るという動作をしています。

 最初、ステップ1のInput Statusは無視し、動作完了の時間を十分確保してHolding registersの変更コマンドの実行という形でプログラムを作ります。

動作確認プログラム

 Python3とエディタMu関連は連載の4回目を参照ください。Modubus/RTUのアクセスに使うmodbus_tkライブラリは、連載の第5回を参照ください。

 1バイトがunsigned byeであれば0~256度が指定できます。試しに保持レジスタのオフセット0のレジスタに180を設定します。半回転するはずです。

import sys,time
sys.path.append('C:\\Users\\ユーザ名\\AppData\\Local\\Programs\\Python\\Python38\\Lib\\site-packages')

import serial
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu

PORT = 'COM8'
Address = 1
master = modbus_rtu.RtuMaster(serial.Serial(port=PORT, baudrate=19200, bytesize=8, parity='N', stopbits=2, xonxoff=0))
master.set_timeout(1.0)
#master.set_verbose(True)
#print("connected")
a = master.execute(Address, cst.READ_COILS, 0, 1)
print('READ_COILS', a[0])

master.execute(Address, cst.WRITE_SINGLE_REGISTER, 0, output_value=0)
master.execute(Address, cst.WRITE_SINGLE_REGISTER, 1, output_value=0)
master.execute(Address, cst.WRITE_SINGLE_REGISTER, 2, output_value=99)
print('set HOLDING_REGISTERS', master.execute(Address, cst.READ_HOLDING_REGISTERS, 0, 3))

master.execute(Address, cst.WRITE_SINGLE_COIL, 0, output_value=1)
time.sleep(1)
print('READ_COILS', master.execute(Address, cst.READ_COILS, 0, 1)[0])

master.execute(Address, cst.WRITE_SINGLE_REGISTER, 0, output_value=180)
master.execute(Address, cst.WRITE_SINGLE_REGISTER, 1, output_value=0)
master.execute(Address, cst.WRITE_SINGLE_REGISTER, 2, output_value=900)
print('set HOLDING_REGISTERS', master.execute(Address, cst.READ_HOLDING_REGISTERS, 0, 3))
master.execute(Address, cst.WRITE_SINGLE_COIL, 0, output_value=1)
time.sleep(5)
print('READ_COILS', master.execute(Address, cst.READ_COILS, 0, 1)[0])

 実行例です。半回転して静止しました。