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

 前回、保持レジスタの最下位バイト・レジスタに180を入れて動作させると、モータは180度回転して止まりました。

 Modbus規格の保持レジスタは、いくつかあるレジスタの中の一つで、英語の表記はHolding Registerです。計測系などではファンクション04と並んでよく使われます。ファンクション03で読み出し、06で書き込み(変更)をします。

コード 機能名 機能 pythonの対応関数
01 Read Coil Status スレーブのDOのON/OFFを読み出す READ_COILS
02 Read Input Status スレーブのDIのON/OFFを読み出す  
03 Read Holding Register スレーブの保持レジスタの内容を読み出す READ_HOLDING_REGISTERS
04 Read Input Register スレーブの入力レジスタの内容を読み出す  
05 Force Single Coil スレーブのDOをONもしくはOFFする  
06 Preset Single Register スレーブの保持レジスタの内容を変更する WRITE_SINGLE_REGISTER
以下略      

 このモータ・キットでは、次のモーションを定義するために、保持レジスタから3バイトが読み書きできます。

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

 保持レジスタ0(最下位バイト・レジスタ)に180、保持レジスタ1(最上位バイト・レジスタ)に0、保持レジスタ2(目標値までの動作時間ms)に900を入れました。

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)

 保持レジスタ0、1、2を読み出します。

print('set HOLDING_REGISTERS', master.execute(Address, cst.READ_HOLDING_REGISTERS, 0, 3))

 動作指令を出します。

master.execute(Address, cst.WRITE_SINGLE_COIL, 0, output_value=1)

回転する角度を増やす

 保持レジスタ0に180を入れると180度回転しました。900msはちょっと早めに動きます。90msだと瞬間に回転します。1バイトは2^8なので最大値は256です。その値以上の270を指定して実行します。

 270度の位置まで回転しました。つまり、保持レジスタ0は8ビット(1バイト)ではなく16ビット(1ワード)ではないかと思われます。

 360*2 であれば、2回転します。900msのままだと回転速度が速くなります。

 1回転360度を60秒(6000ms)で実行するとすれば、1rpmになります。6000msは9の倍数にならないので、近似値の5994にします。その1/10の時間で回転できれば10rpmです。動作時間は594msを基準に回転させることにしました。

master.execute(Address, cst.WRITE_SINGLE_REGISTER, 0, output_value=360*2)
master.execute(Address, cst.WRITE_SINGLE_REGISTER, 1, output_value=0)
master.execute(Address, cst.WRITE_SINGLE_REGISTER, 2, output_value=594*2)

 この指定で、

  • 10rpmの回転速度
  • 2回

回るはずです。

 正しく動作しました。

ステータスを見て回転させる

 Discrete inputs(02 Read Input Status)を使ってアドレス0を読み取ると、ステータスがわかります。

 DONE(LSB)は、目標位置に到達したかどうかを示す
  •1 =>目標位置に到達した
  •0 =>目標位置に達していない

 実際に読み出してみると、動作中は1で、動作が完了すると0でした。どうも説明と反対のように思えます。

  • 10rpm
  • 10回

回転するプログラムです。最初に0で原点復帰します。この復帰動作は、前回10回回転していれば、10回逆向きに回転します。その復帰のために回転しているとき、ステータスを監視し、

while master.execute(Address, cst.READ_COILS, 0, 1)[0]:
    pass

 1->0に変化したら、動作完了とみなし、予定の10回転をします。10回転しているときもステータスを見ています。

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])

n = 10

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=999*n)
print('set HOLDING_REGISTERS', master.execute(Address, cst.READ_HOLDING_REGISTERS, 0, 3))

master.execute(Address, cst.WRITE_SINGLE_COIL, 0, output_value=1)

while master.execute(Address, cst.READ_COILS, 0, 1)[0]:
#    status = master.execute(Address, cst.READ_COILS, 0, 1)[0]
#    print(status)
#    time.sleep(0.5)
    pass
print('Ready', master.execute(Address, cst.READ_COILS, 0, 1)[0])

master.execute(Address, cst.WRITE_SINGLE_REGISTER, 0, output_value=360*n)
master.execute(Address, cst.WRITE_SINGLE_REGISTER, 1, output_value=0)
master.execute(Address, cst.WRITE_SINGLE_REGISTER, 2, output_value=594*n)
print('set HOLDING_REGISTERS', master.execute(Address, cst.READ_HOLDING_REGISTERS, 0, 3))
master.execute(Address, cst.WRITE_SINGLE_COIL, 0, output_value=1)

while master.execute(Address, cst.READ_COILS, 0, 1)[0]:
#    status = master.execute(Address, cst.READ_COILS, 0, 1)[0]
    print('.')
#    time.sleep(0.5)
time.sleep(1)
print('done')


 この10rpmだと、最初に加速(S字)、定速、減速という3段階の動作をしているのがはっきりと見ることができます。

 モータが回転している様子の動画です。

   IMG_0016.mp4をダウンロード