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段階の動作をしているのがはっきりと見ることができます。
モータが回転している様子の動画です。