As we all know, Python, as an emerging object-oriented programming language, has a complete basic code library, strong practicality and code readability, and is being used by more and more people for motion control of intelligent equipment.
Today, Zhengdong Technology will share with you a tutorial on developing motion control card applications using Python.
Before we begin our formal learning, let's first understand the motion control cards ECI2418 and ECI2618 from Zheng Motion Technology. These two products are 4-axis and 6-axis motion control cards, respectively.
The ECI2418 supports 4-axis pulse input and encoder feedback, with 24 onboard inputs, 16 onboard outputs, 2 AD, 2 DA, and a handwheel interface. Some outputs support high-speed PWM control.
The ECI2618 supports 6-axis pulse input and encoder feedback, with 24 onboard inputs, 16 onboard outputs, 2 AD converters, 2 DA converters, and a handwheel interface. Some outputs support high-speed PWM control.
Both ECI2418 and ECI2618 use the same set of API functions and support development languages such as C, C++, C#, LabVIEW, Python, and Delphi. They also support platforms such as VC6.0, VB6.0, Qt, and .Net, and operating systems such as Windows, Linux, WinCE, and iMac.
The following is the development process for the Python language.
1. Create a new project.
Open PyCharm and click "Create New Project" to create a new project.
2. Set the storage path for Python projects.
This process mainly consists of three steps:
Select Python project → Select the path where the Python project will be stored → Create Python project.
3. Create a new Python file.
To create a new Python file in your Python project, right-click the CratPython folder and select "New → PythonFile".
Select "New → Python File"
Create a new Python file
4. Copy the Python dynamic library into the Python project.
5. Import and load the dynamic link library.
First, import the two modules in Python (platform and ctypes). The ctypes module provides data types compatible with the C language, which makes it easy to call C interface functions exported from dynamic link libraries.
import platform
import ctypes
# Operating Environment Determination
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. By loading the imported dynamic library, call the functions in the ZMotion PC function manual.
1) Operation.
First, connect the controller using a connection function according to the controller connection method, and output the controller handle. We can then use the controller handle to operate on the library functions.
That is, "Open the PC function manual → search for the desired function → view the function description → call it through the zauxdll object returned by the dynamic link library that was just loaded".
2) Operate on the controller handle returned by the IP connection function interface.
#####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) Axis parameter settings.
#####Axis Parameter Settings####
# 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!" )
return ret
# Set pulse equivalent
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!" )
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!" )
return ret
# Set axis running 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!" )
return ret
4) Axis parameter reading.
#####Axis Parameter Reading####
# Read axis type
def get_atype (self, iaxis):
iValue = (ctypes.c_int)()
ret = zauxdll.ZAux_Direct_GetAtype(self.handle, iaxis, ctypes.byref(iValue))
if ret == 0 :
print( "Get Axis (" , iaxis, ") Atype:" , iValue.value)
else :
print( "Get Axis (" , iaxis, ") Atype fail!" )
return ret
# Read axis pulse equivalent
def get_units (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!" )
return ret
# Read axis acceleration
def get_accel (self, iaxis):
iValue = (ctypes.c_float)()
ret = zauxdll.ZAux_Direct_GetAccel(self.handle, iaxis, ctypes.byref(iValue))
if ret == 0 :
print( "Get Axis (" , iaxis, ") Accel:" , iValue.value)
else :
print( "Get Axis (" , iaxis, ") Accel fail!" )
return ret
# Read axis deceleration
def get_decel (self, iaxis):
iValue = (ctypes.c_float)()
ret = zauxdll.ZAux_Direct_GetDecel(self.handle, iaxis, ctypes.byref(iValue))
if ret == 0 :
print( "Get Axis (" , iaxis, ") Decel:" , iValue.value)
else :
print( "Get Axis (" , iaxis, ") Decel fail!" )
return ret
# Read axis running speed
def get_speed (self, iaxis):
iValue = (ctypes.c_float)()
ret = zauxdll.ZAux_Direct_GetSpeed(self.handle, iaxis, ctypes.byref(iValue))
if ret == 0 :
print( "Get Axis (" , iaxis, ") Speed:" , iValue.value)
else :
print( "Get Axis (" , iaxis, ") Speed fail!" )
return ret
5) Single-axis motion.
#####Motion Activation####
# Linear Motion
def move (self, iaxis, iValue):
ret = zauxdll.ZAux_Direct_Single_Move(self.handle, iaxis, iValue)
if ret == 0 :
print( "Axis (" , iaxis, ") Move:" ,iValue)
else :
print( "Axis (" , iaxis, ") Move Fail" )
return ret
6) Run the program and output the results.
Call the encapsulated function → run → output the program's output.
#####Function Usage####
zaux = ZMCWrapper()
# Connect to the controller IP address (default 192.168.0.11)
zaux.connect( "192.168.0.11" )
# Set axis 0 parameters
zaux.set_atype(0, 1)
zaux.set_units(0, 100)
zaux.set_accel(0, 1000)
zaux.set_decel(0, 1000)
zaux.set_speed(0, 1000)
# Get axis 0 parameter
zaux.get_atype(0)
zaux.get_units(0)
zaux.get_accel(0)
zaux.get_decel(0)
zaux.get_speed(0)
# sports
zaux.move(0, 100) # Move 100 units linearly along axis 0
Run and output the program results.
This concludes our tutorial on developing motion control card applications using Python. For more great content, please follow our official WeChat account.
This article was originally created by Zheng Motion Assistant. We welcome everyone to reprint it for mutual learning and to improve China's intelligent manufacturing capabilities. Copyright belongs to Zheng Motion Technology. Please indicate the source if you reprint this article.