EPOS4のコントローラには、
- ディジタル入力4ポート、出力2ポート
- アナログ入力2ポート、出力2ポート
が用意されています。オブジェクト・ディクショナリに登録されているので、SDOで読み書きできます。前回ディジタル入出力を利用しました。今回はアナログ入力です。
アナログ入力
Analog I/O (X8)コネクタのピン番号と機能です。
1 white Analog input 1, positive signal
2 brown Analog input 1, negative signal
3 green Analog input 2, positive signal
4 yellow Analog input 2, negative signal
5 grey Analog output 1
6 pink Analog output 2
7 blue Ground
1-2のアナログ入力1、3-4のアナログ入力2を利用します。ともに12ビット、±10Vの差動入力です。
機能を定義する
WizardsのStartupからAnalog Inputを選択します。Analog input1にFunctionalityを画面のようにSet value velocity選択します。
電圧Voltageを速度Velocityに換算することができます。あとでわかったことですが、これはCSVモードで生きるようで、今回のようなProfile Position Modeでは有効なVelocity値が得られませんでした。
Analog input2はNoneのままです。
Finishで終了します。
オブジェクト・ディレクトリでも確認できます。
0x3160にアナログ電圧が入っています。
0x60ffに換算された速度値が入っています。見ていると、値は更新されます。しかし、プログラムでは初期の値しか代入できず、更新された値は反映できませんでした。
ハードウェア
10kΩのボリュームを二つ並べた基板を用意しました。
コネクタX7 Digital I/Oの7番 Vdd(5V)から5Vをもらってきました。ディジタルとアナログ・コネクタのGNDは共通のようです。
1 Analog input 1, positive signal
2 Analog input 1, negative signal
3 Analog input 2, positive signal
4 Analog input 2, negative signal
5 +5V
6 GND
プログラム
入力はAnalog input1だけの対応です。
node.sdo[0x3160]['Analog input 1 voltage'].phys
は電圧を読み取っています。実際の電圧の千倍の整数値が入っているので、速度の値にそのまま使います。差動入力のため、ボリュームを最小にするとマイナス値をとってくることがあります。対策をしていないので、エラーで止まります。
import canopen
import time
# Start with creating a network representing one CAN bus
network = canopen.Network()
# Add some nodes with corresponding Object Dictionaries
node = canopen.BaseNode402(5,'maxon_motor_EPOS4_0170h_6050h_0000h_0000h.eds')
network.add_node(node)
# Connect to the CAN bus
network.connect(bustype='ixxat', channel=0, bitrate=1000000)
print("\n===start ID=5 EPOS4\n")
def NMT_start():
node.nmt.send_command(0x81) # NMT reset
time.sleep(0.5)
node.nmt.send_command(0x82) # NMT Reset Communication
#node.nmt.wait_for_bootup(15)
time.sleep(0.5)
node.nmt.send_command(0x80) # NMT Pre-ope
time.sleep(0.5)
node.nmt.send_command(0x1) # NMT start
def CiA402_start():
print("---Switch CiA402")
node.setup_402_state_machine()
#node.sdo[0x6040].raw = 0x0010 # Fault Reset
node.sdo[0x1003].raw = 0x0000
time.sleep(0.1)
node.sdo[0x1003].raw = 0x0000
time.sleep(0.1)
#node.sdo[0x1003].raw = 0x0000
#time.sleep(0.1)
#node.state = 'NOT READY TO SWITCH ON'
#node.state = 'SWITCH ON DISABLED'
Statusword = node.sdo[0x6041].raw
print('Statusword {:0>16b}'.format(Statusword))
#node.state = 'READY TO SWITCH ON'
node.sdo[0x6040].raw = 0x0006
time.sleep(0.1)
node.sdo[0x6040].raw = 0x0006
time.sleep(0.1)
#node.sdo[0x6040].raw = 0x0006
#time.sleep(0.1)
#node.state = 'SWITCHED ON'
node.sdo[0x6040].raw = 0x0007
time.sleep(0.1)
node.sdo[0x6040].raw = 0x0007
time.sleep(0.1)
#node.sdo[0x6040].raw = 0x0007
#time.sleep(0.1)
#node.state = 'OPERATION ENABLED'
node.sdo[0x6040].raw = 0x000f
time.sleep(0.1)
node.sdo[0x6040].raw = 0x000f
time.sleep(0.1)
#node.sdo[0x6040].raw = 0x000f
#time.sleep(0.1)
#----int----------------
NMT_start()
network.check()
print('NMT:node state = {0}\n'.format(node.nmt.state))
network.sync.start(0.1)
CiA402_start()
print("\nSWITCH ready\n")
print('Statusword {:0>16b}\n'.format(node.sdo[0x6041].raw))
#----main----------------
def move(velocity):
node.sdo[0x6040].raw = 0x0006
node.sdo[0x6040].raw = 0x000f
node.rpdo[3]['Controlword'].phys = 0x007f
node.rpdo[3]['Target position'].phys = 5000
node.rpdo[3].transmit()
node.rpdo[4]['Controlword'].phys = 0x007f
node.rpdo[4]['Profile velocity'].phys = velocity
node.rpdo[4].transmit()
def readPosition():
print('Target position {:5d}'.format(node.tpdo[3]['Position actual value'].raw))
readPosition()
node.sdo[0x6060].raw = 0x0001 # Modes of operation <- Profile Position Mode
#node.sdo[0x607a].raw = 0 # Target position
node.sdo[0x6081].raw = 30 # Profile velocity
node.nmt.state = 'OPERATIONAL'
print('\n>>> move\n')
while 1:
newVerocity = int(node.sdo[0x3160]['Analog input 1 voltage'].phys)+30
print(newVerocity)
move(newVerocity)
readPosition()
time.sleep(3)
#-------------------
print("\n-----")
node.sdo[0x6040].raw = 0x0010 # Fault Reset
print("")
node.nmt.send_command(0x02) # NMT remote stop
network.check()
print('node state end) = {0}'.format(node.nmt.state))
node.nmt.send_command(0x81) # NMT reset
time.sleep(0.5)
node.nmt.send_command(0x82) # NMT Reset Communication
network.sync.stop()
network.disconnect()
最初は変な速度で回ります。node.sdo[0x6081].raw = 30
がないと、速度が変化しません。def move(velocity):
の関数にしないと、速度が変化しません。
まだ何か、初期設定などで、設定すべき事柄などがフォローしきれていないようです。