LoginSignup
0
0

More than 1 year has passed since last update.

日記;回すだけIII ⑪ pythonでSDO、PDOの読み書き<その6 Profile Position Mode + アナログ入力(EPOS4)>ベータ版

Last updated at Posted at 2022-03-22

 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のままです。

2022-03-22 (2).png

 Finishで終了します。
 オブジェクト・ディレクトリでも確認できます。
 0x3160にアナログ電圧が入っています。
2022-03-22 (4).png

 0x60ffに換算された速度値が入っています。見ていると、値は更新されます。しかし、プログラムでは初期の値しか代入できず、更新された値は反映できませんでした。

2022-03-22 (6).png

ハードウェア

 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

2022-03-22 (14).png

IMGP1033.png

プログラム

 入力は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):の関数にしないと、速度が変化しません。
 まだ何か、初期設定などで、設定すべき事柄などがフォローしきれていないようです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0