Bring Values and Sucesses To Our Customers

Home / Support and services / Technical Support

Technical support

Technical Support

Development Tutorial -- EtherCAT Motion Control Card & Python


As we all know, Python is a kind of development language that has excellent basic codes library. It lays emphasis on practical application, and codes are with extremely strong readability. You can run the program directly when edited. Therefore, it is used in machine vision and automation control increasingly.

 

Today, ZMOTION TECHNOLOGY shares application development of motion control card and Python.

I. ECI2828 Hardware introduction


ECI2828
 series motion control cards support linear interpolation of up to 16 axes, including interpolation of any circular interpolation, spherical and helical, electronic cam, electronic gear, synchronous follow, virtual axis, robotic arm instruction, etc. What's more, real-time motion control can be achieved through optimized network communication protocol.

 

ECI2828 series motion control cards support connection of Ethernet, 232 communication interface and computer, and they will receive computer's instructions to run. Each expansion module can be connected through EtherCAT bus and CAN bus for expanding inputs, outputs or motion axes.

image ECI2828.jpg


Application programs of ECI2828 series cards can be developed by VC, VB, VS, C++, etc. And "zmotion.dll" dynamic library is needed when running. When debugging, ZDevelop software can be connected to controller at the same time, which is convenient for debugging and observing.

 

ECI2828 ying.png

 


II. Python Language Development Process


Usage environment of Python:

a: Operation system environment: win7_64x

b: Python development running environment: PyCharm2019.2

c: Python interpreter version: Python 3.7.4(32bit)

 

1.   New build project


 Open "Pycharm" software to operate

→ click "Create New Project" to build new project.

image 1.jpg

2.   Set Python project saving path


→ 
Select "Pure Python" project

→ select the location where saves Python project

→ click "Create".

image 2.jpg

3.   New build Python file


→ 
Build new Python file in Python project

→ right-click "CratPython" folder

→ select "New PythonFile".

image 3.jpg

4.   Copy Python dynamic library into Python project.

image 4.jpg

 

5.   Module import, load dynamic link library


→ 
Import Python's two modules "platform and ctypes".

(ctypes module provides data types that are compatible with C language, and it can conveniently call C interface function that is output from dynamic link library)

 

import platform

import ctypes

import os

#running environment judge

systype = platform.system()

if systype == 'Windows':

if platform.architecture()[0] == '64bit':

zauxdll = ctypes.WinDLL('./zauxdll64.dll')

print('Windows x64')

else:

zauxdll = ctypes.WinDLL('./zauxdll.dll')

print('Windows x86')

elif systype == 'Darwin':

zmcdll = ctypes.CDLL('./zmotion.dylib')

print("macOS")

elif systype == 'Linux':

zmcdll = ctypes.CDLL('./libzmotion.so')

print("Linux")

else:

print("Not Supported!!")

 

6.   Call functions of ZMotion PC Function Manual through loading imported dynamic link library


(1)
  usage operation

Firstly, use "connection function" to controller through controller connection method, then output controller handle, next operate library function using handle of controller.

Process in details: open PC function manual  search function you need  check function description  call zauxdll object returned from loaded dynamic link library.

image 5.jpg


 

(2)  connect returned controller handle of function interface through ip, and operate "handle".

image 6 (指令7).png


#####controller connection#####

    def connect(self, ip, console=[]):

        if self.handle.value is not None:

            self.disconnect()

        ip_bytes = ip.encode('utf-8')

        p_ip = ctypes.c_char_p(ip_bytes)

        print("Connecting to", ip, "...")

        ret = zauxdll.ZAux_OpenEth(p_ip, ctypes.pointer(self.handle))

        msg = "Connected"

        if ret == 0:

            msg = ip + " Connected"

            self.sys_ip = ip

            self.is_connected = True

         else:

            msg = "Connection Failed, Error " + str(ret)

            self.is_connected = False

         console.append(msg)

         console.append(self.sys_info)

         return ret

 

#disconnect

def disconnect(self):

    ret = zauxdll.ZAux_Close(self.handle)

    self.is_connected = False

    return ret

 

(3)  we provide basic codes of EtherCAT bus initialization, and codes can be downloaded into controller through ZAux_BasDown(), then initialization of EtherCAT bus axis can be achieved.

image 7 (指令12).png


 ********************ECAT bus initialization****************

            global CONST BUS_TYPE = 0             'bus type

            global CONST MAX_AXISNUM = 16       'max axes

            global CONST Bus_Slot  = 0             'slot number is 0

            global CONST Bus_AxisStart   = 0      'starting number of bus axis

            

            global Bus_InitStatus               'bus initialization is in completion status

            Bus_InitStatus = -1

            global  Bus_TotalAxisnum         'check scanned total axis numbers

            delay(3000)                          'delay 3s, wait drive power on

            Ecat_Init()

            end

            

            global sub Ecat_Init()

              'initialization recover the axis type

               for i=0 to MAX_AXISNUM - 1              

                  AXIS_ENABLE(i) = 0

                  ATYPE(i)=0  

               next

                  'scan the bus

                  Bus_InitStatus = -1

                  Bus_TotalAxisnum = 0  

                  SLOT_STOP(Bus_Slot)

                  DELAY(200)

                  SLOT_SCAN(Bus_Slot)

                  'scan success           

                  if return then      

                     ?"success to scan the bus", "connected device numbers"NODE_COUNT(Bus_Slot)    

                     ?"start to map axis number"

                     'traverse all slave stations under bus

                     for i=0 to NODE_COUNT(Bus_Slot)-1            

                        'judge whether the current node has motor

                        if NODE_AXIS_COUNT(Bus_Slot,i) <>0 then      

                        for j=0 to NODE_AXIS_COUNT(Bus_Slot,i)-1

                           'map axis number

                           AXIS_ADDRESS(Bus_AxisStart+i)=Bus_TotalAxisnum+1

                           'set control mode, 65-position, 66-speed, 67-torque

                           ATYPE(Bus_AxisStart+i)=65

                           'set PROFILE function              

                           DRIVE_PROFILE(Bus_AxisStart+i)= 4

                           'make group separately for each axis    

                           DISABLE_GROUP(Bus_AxisStart+i)              

                           'map IO start address on drive

                           DRIVE_IO(Bus_AxisStart+i) = 128 + (Bus_AxisStart+i)*16  

                          'total axes +1      

                          Bus_TotalAxisnum=Bus_TotalAxisnum+1                

                      next

                    endif

               next      

                  ?"axis number has been mapped", "connected axis numbers"Bus_TotalAxisnum

                  WA 2000

                  'bus is on

                  SLOT_START(Bus_Slot)            

                  if return then 

                     ?"bus is on"            

                     ?"start to clear drive errors (according to drive data dictionary configuration)"

                     for i= Bus_AxisStart to Bus_AxisStart + Bus_TotalAxisnum - 1              

                        DRIVE_CONTROLWORD(i)=128          'according to drive data dictionary

                        wa 100

                        DRIVE_CONTROLWORD(i)=6

                        wa 100

                        DRIVE_CONTROLWORD(i)=15

                        wa 100      

                     next        

                        ?"drive errors are cleared out "

                        wa 100    

                        ?"clear controller error"

                        DATUM(0)

                        DRIVE_CLEAR(0)

                        ?"controller errors are cleared out"

                        wa 100              

                        ?"axis enable preparation"

                        for i= Bus_AxisStart to Bus_AxisStart + Bus_TotalAxisnum - 1

                           base(i)

                           AXIS_ENABLE=1

                        next

                            'enable switch

                            WDOG=1                      

                            Bus_InitStatus  = 1

                            ?"axis enable completion"

                     else

                        ?"bus fails to be on"

                        Bus_InitStatus = 0

                     endif

                  

                 else

                    ?"bus fails to be scanned"

                    Bus_InitStatus = 0

                 endif

            end sub

 

(4)  axis parameters configuration

#####axis parameter configuration####

    #set axis type

    def set_atype(self, iaxis, iValue):

        ret = zauxdll.ZAux_Direct_SetAtype(self.handle, iaxis, iValue)

        if ret == 0:

            print("Set Axis (", iaxis, ") Atype:", iValue)

        else:

            print("Set Axis (", iaxis, ") Atype fail!error:",ret)

        return ret

 

    #set pulse amount

    def set_units(self, iaxis, iValue):

        ret = zauxdll.ZAux_Direct_SetUnits(self.handle, iaxis, ctypes.c_float(iValue))

        if ret == 0:

            print("Set Axis (", iaxis, ") Units:", iValue)

        else:

            print("Set Axis (", iaxis, ") Units fail!error:",ret)

         return ret

 

    #set axis acceleration

    def set_accel(self, iaxis, iValue):

        ret = zauxdll.ZAux_Direct_SetAccel(self.handle, iaxis, ctypes.c_float(iValue))

        if ret == 0:

            print("Set Axis (", iaxis, ") Accel:", iValue)

        else:

            print("Set Accel (", iaxis, ") Accel fail!")

        return ret

 

    #set axis deceleration

    def set_decel(self, iaxis, iValue):

        ret = zauxdll.ZAux_Direct_SetDecel(self.handle, iaxis, ctypes.c_float(iValue))

        if ret == 0:

            print("Set Axis (", iaxis, ") Decel:", iValue)

        else:

            print("Set Axis (", iaxis, ") Decel fail!error:",ret)

        return ret

 

    #set axis motion speed

    def set_speed(self, iaxis, iValue):

        ret = zauxdll.ZAux_Direct_SetAccel(self.handle, iaxis, ctypes.c_float(iValue))

        if ret == 0:

            print("Set Axis (", iaxis, ") Speed:", iValue)

        else:

            print("Set Axis (", iaxis, ") Speed fail!error:",ret)

        return ret

 

(5)  axis parameters reading

#read axis pulse amount

def get_untis(self, iaxis):

    iValue = (ctypes.c_float)()

    ret = zauxdll.ZAux_Direct_GetUnits(self.handle, iaxis, ctypes.byref(iValue))

    if ret == 0:

        print("Get Axis (", iaxis, ") Units:", iValue.value)

    else:

        print("Get Axis (", iaxis, ") Units fail! error:",ret)

    return ret


Copyright © 2013-2024 Shenzhen Zmotion Technology Co.,Ltd Design by Zmotion    粤ICP备13037187号 Motion Controller-Motion Control Card

Contact Us-Youtube