Difference between revisions of "Modbus Communication API/zh-hans"

From SoftMC-Wiki
Jump to: navigation, search
 
(3 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Languages}}
+
{{Languages|Modbus_Communication_API}} <div class="noprint" id="BackToTop" style="background-color:; position:fixed; bottom:32px; left:95%; z-index:9999; padding:0; margin:0;">
 +
&nbsp;
 +
<span style="color:blue; font-size:8pt; font-face:verdana,sans-serif; border:0.2em outset:#ceebf7; padding:0.1em; font-weight:bolder; -moz-border-radius:8px;">[[File:TOP2.png|50px|TOP2.png|link=#top]]</span></div>
 
== 概述 ==
 
== 概述 ==
 +
 
=== 基本概述 ===
 
=== 基本概述 ===
* 本章节介绍如何为softMC设置Modbus通信,以及如何生成softMC脚本来处理Modbus通信。
+
 
* 假设您熟悉Modbus通信的原理,尽管其中一些将在此页面中进行描述。
+
*本章节介绍如何为softMC设置Modbus通信,以及如何生成softMC脚本来处理Modbus通信。  
* 假设您熟悉softMC,ControlStudio和MC-Basic编程。
+
*假设您熟悉Modbus通信的原理,尽管其中一些将在此页面中进行描述。  
 +
*假设您熟悉softMC,ControlStudio和MC-Basic编程。  
  
 
=== Modbus通信背景 ===
 
=== Modbus通信背景 ===
* 运动控制器(MC)可以为服务器(从站),客户端(主站)或两者同时充当。
+
 
* 每个MC连接(TCP / RTU)可以用作服务器组件(如果连接由MC的服务器端使用)或客户端组件(如果连接由MC的客户端使用)。
+
*运动控制器(MC)可以为服务器(从站),客户端(主站)或两者同时充当。  
* 每个组件都有自己的参数定义。
+
*每个MC连接(TCP / RTU)可以用作服务器组件(如果连接由MC的服务器端使用)或客户端组件(如果连接由MC的客户端使用)。  
* 当MC作为服务器时,所有服务器组件共享“相同”的内存地址空间,从而充当具有多个连接的一个服务器。
+
*每个组件都有自己的参数定义。  
* Modbus网络上的每个服务器(从站)都有自己的deviceID,它是1到247之间的数字。
+
*当MC作为服务器时,所有服务器组件共享“相同”的内存地址空间,从而充当具有多个连接的一个服务器。  
 +
*Modbus网络上的每个服务器(从站)都有自己的deviceID,它是1到247之间的数字。  
  
 
=== Modbus服务器寄存器 ===
 
=== Modbus服务器寄存器 ===
* Modbus服务器地址空间中有4种寄存器类型:
+
 
*# 位(1位寄存器)
+
*Modbus服务器地址空间中有4种寄存器类型:  
*# 输入位(1位READ-ONLY寄存器)
+
*#位(1位寄存器)  
*# 保持寄存器(16位寄存器)
+
*#输入位(1位READ-ONLY寄存器)  
*# 输入寄存器(16位只读寄存器)
+
*#保持寄存器(16位寄存器)  
* 服务器可以读写自己的地址空间
+
*#输入寄存器(16位只读寄存器)  
* 客户端可以读写远程服务器的地址空间
+
*服务器可以读写自己的地址空间  
 +
*客户端可以读写远程服务器的地址空间  
  
 
== 入门 ==
 
== 入门 ==
 +
 
为了开始使用Modbus功能:
 
为了开始使用Modbus功能:
# 下载所需的文件: [[:File:MB_Required_files.zip]]
+
 
# 使用ControlStudio文件管理器,将以下文件上传到您的MC:
+
#下载所需的文件: [[:File:MB_Required_files.zip]]  
#* mb_x86.O ''(for softMC7 )'' / mb_armA9.O ''(for softMC3)''
+
#使用ControlStudio文件管理器,将以下文件上传到您的MC:  
#* Modbus.lib
+
#*mb_x86.O ''(for softMC7 )'' / mb_armA9.O ''(for softMC3)''  
#* MB_Load.prg
+
#*Modbus.lib  
#:[[File:modbus;newAPI-upload.jpg|850px]]
+
#*MB_Load.prg
# 通过键入以下命令加载MB_Load.prg: <pre>Load MB_Load.prg</pre>
+
#:[[File:modbus;newAPI-upload.jpg|850px|modbus;newAPI-upload.jpg]]  
#:这将加载mb_x86.O / mb_armA9.O,具体取决于您当前的系统,以及Modbus.LIB库文件。
+
#通过键入以下命令加载MB_Load.prg: <pre>Load MB_Load.prg</pre>
# '''或者''', 您可以通过键入来手动加载对象文件和Modbus库:
+
 
#:<Pre>
+
 
#::Oload mb_x86.O
+
#
#::Loadglobal Modbus.LIB</pre>
+
#:这将加载mb_x86.O / mb_armA9.O,具体取决于您当前的系统,以及Modbus.LIB库文件。  
 +
#'''或者''', 您可以通过键入来手动加载对象文件和Modbus库:  
 +
#:<pre>
 +
&nbsp;</pre>
 +
 
 +
&nbsp;
 +
#
 +
#:
 +
#::Oload mb_x86.O  
 +
#::Loadglobal Modbus.LIB    
  
 
现在可以配置Modbus系统。
 
现在可以配置Modbus系统。
  
 
== 初始化Modbus环境 ==
 
== 初始化Modbus环境 ==
 +
 
要初始化Modbus环境,包括服务器地址空间,调用:
 
要初始化Modbus环境,包括服务器地址空间,调用:
 
<pre>?init_multi_server([bits],[input_bits],[holding registers],[input_registers])</pre>
 
<pre>?init_multi_server([bits],[input_bits],[holding registers],[input_registers])</pre>
* 该功能打印"success",成功返回0,或者失败时返回错误代码。
+
 
* <u>'''注意:'''</u> 即使您只需要Client组件,您也必须调用此方法。 在这种情况下,只需传递0作为所需的寄存器大小
+
*该功能打印"success",成功返回0,或者失败时返回错误代码。  
* <u>'''注意:'''</u> 只有在没有活动的服务器组件时,才可以调用此方法。
+
*<u>'''注意:'''</u> 即使您只需要Client组件,您也必须调用此方法。 在这种情况下,只需传递0作为所需的寄存器大小  
 +
*<u>'''注意:'''</u> 只有在没有活动的服务器组件时,才可以调用此方法。  
 +
 
 
<u>'''错误代码:'''</u>
 
<u>'''错误代码:'''</u>
{| class="wikitable" border="1"
+
 
 +
{| border="1" class="wikitable"
 
|-
 
|-
 
! 错误
 
! 错误
Line 52: Line 72:
 
|-
 
|-
 
| -1
 
| -1
| Memory allocation failure.
+
| 内存分配失败
 
|-
 
|-
 
| -2
 
| -2
| Some servers are still running and using an already mapped address space.
+
| 某些服务器仍在运行,并使用已映射的地址空间
 
|-
 
|-
 
| -3
 
| -3
| Failed to create a modbus mapping.
+
| 无法创建modbus映射
 
|}
 
|}
  
== Server Components ==
+
== 服务器组件 ==
=== '''Adding server components''' ===
+
 
* Each time you'll add a component, you will receive a '''handle''', which is the component's identifier (for later use).
+
=== '''添加服务器组件''' ===
* It is best to keep this handles in variables inside your program.
+
 
==== Creating a TCP server component ====
+
*每次添加组件时,您将收到一个'''句柄''',它是组件的标识符(以供后续使用)。
 +
*最好将程序中的变量保存在此处。
 +
 
 +
==== 创建TCP服务器组件 ====
 
<pre>handle = mb_tcp_server_create([port],[deviceID])</pre>
 
<pre>handle = mb_tcp_server_create([port],[deviceID])</pre>
* This opens a TCP connection to the server on port [port] with deviceID [deviceID], and starts the created server immediately.
+
 
* Returns a handle on success, or an error code on failure.
+
*This opens a TCP connection to the server on port [port] with deviceID [deviceID], and starts the created server immediately.  
<u>'''Error codes:'''</u>
+
*Returns a handle on success, or an error code on failure.  
{| class="wikitable" border="1"
+
 
 +
<u>'''错误代码:'''</u>
 +
 
 +
{| border="1" class="wikitable"
 
|-
 
|-
! Error
+
! 错误
! Meaning
+
! 含义
 
|-
 
|-
 
| -1
 
| -1
| Server address spaces isn't initialized yet, please call "init_multi_server(...) and try again.
+
| 服务器地址空间尚未初始化,请调用“init_multi_server(...)”,然后重试
 
|-
 
|-
 
| -2
 
| -2
| Failed to create main socket.
+
| 无法创建主套接字
 
|-
 
|-
 
| -3
 
| -3
| Failed to connect.
+
| 连接失败
 
|-
 
|-
 
| -4
 
| -4
| Failed to create server thread.
+
| 无法创建服务器线程
 
|}
 
|}
==== Creating an RTU server component ====
+
 
 +
==== 创建RTU服务器组件 ====
 
<pre>handle = mb_rtu_server_create([type],[port],[baudrate],[data bits],[stop bits],[parity],[deviceID])</pre>
 
<pre>handle = mb_rtu_server_create([type],[port],[baudrate],[data bits],[stop bits],[parity],[deviceID])</pre>
* This opens an RTU connection with the given parameters, and starts the created server immediately.
+
 
* Returns a handle on success, or an error code on failure.
+
*这将打开与给定参数的RTU连接,并立即启动创建的服务器。
<u>'''Error codes:'''</u>
+
*成功返回的句柄,失败时返回错误代码。
{| class="wikitable" border="1"
+
 
 +
<u>'''错误代码:'''</u>
 +
 
 +
{| border="1" class="wikitable"
 
|-
 
|-
! Error
+
! 错误
! Meaning
+
! 含义
 
|-
 
|-
 
| -1
 
| -1
| Server address spaces isn't initialized yet, please call "init_multi_server(...) and try again.
+
| 服务器地址空间尚未初始化,请调用“init_multi_server(...)”,然后重试。
 
|-
 
|-
 
| -2
 
| -2
| Invalid device string.
+
| 设备字符串无效
 
|-
 
|-
 
| -3
 
| -3
| Invalid parity.
+
| 奇偶校验无效
 
|-
 
|-
 
| -4
 
| -4
| Failed opening RTU.
+
| 打开RTU失败
 
|-
 
|-
 
| -5
 
| -5
| Failed allocating query buffer memory.
+
| 分配查询缓冲区内存失败
 
|-
 
|-
 
| -6
 
| -6
| Failed to set RTU mode.
+
| 无法设置RTU模式
 
|-
 
|-
 
| -7
 
| -7
| Unable to connect.
+
| 无法连接
 
|-
 
|-
 
| -8
 
| -8
| Failed to create server thread.
+
| 无法创建服务器线程
 
|-
 
|-
 
| -9
 
| -9
| The device is already in use by another system component.
+
| 该设备已被另一个系统组件使用
 
|}
 
|}
=== '''Stopping Server Components''' ===
+
 
==== Stopping a specific server component ====
+
=== '''停止服务器组件''' ===
You can stop a specific server component by passing its handle to:
+
 
 +
==== 停止特定的服务器组件 ====
 +
 
 +
您可以通过传递其句柄来停止特定的服务器组件:
 
<pre>result = mb_server_stop([handle])</pre>
 
<pre>result = mb_server_stop([handle])</pre>
* Given a handle, this will stop and free the memory of the appropriate server component.
+
 
* Returns 0 on success, -1 on failure.
+
*给定句柄,这将停止并释放相应服务器组件的内存。
==== Stopping all server components ====
+
*成功返回0,失败时返回-1  
You can stop all server components with a single call to:
+
 
 +
==== 停止所有服务器组件 ====
 +
 
 +
您可以通过单次调用来停止所有服务器组件:
 
<pre>result = mb_server_stop_all</pre>
 
<pre>result = mb_server_stop_all</pre>
This function will:
+
 
* Stop and free all server components.
+
此功能将:
* Free the shared address space.
+
 
* Return 0 on success, -1 on failure.
+
*停止并释放所有服务器组件。
== Client Components ==
+
*释放共享地址空间。
=== '''Adding client components''' ===
+
*成功返回0,失败返回-1。
* Each time you'll add a component, you will receive a '''handle''', which is the component's identifier (for later use).
+
 
* It is best to keep this handles in variables inside your program.
+
== 客户端组件 ==
==== Adding a TCP Client component ====
+
 
 +
=== '''添加客户端组件''' ===
 +
 
 +
*每次添加一个组件时,您将收到一个'''句柄''',它是组件的标识符(以供后续使用)。
 +
*最好将程序中的变量保存在此处。
 +
 
 +
==== 添加TCP客户端组件 ====
 
<pre>handle = mb_tcp_client_create([ip],[port])</pre>
 
<pre>handle = mb_tcp_client_create([ip],[port])</pre>
* This will opens a TCP connection to the client on the given ip and port, and start the client immediately.
+
 
* Returns a handle on success, -1 on failure.
+
*这将在给定的ip和port上打开与客户端的TCP连接,并立即启动客户端。
==== Adding an RTU Client component ====
+
*成功时返回的句柄,失败时返回-1。
 +
 
 +
==== 添加RTU客户端组件 ====
 
<pre>handle = mb_rtu_client_create([type],[port],[baudrate],[data bits],[stop bits],[parity])</pre>
 
<pre>handle = mb_rtu_client_create([type],[port],[baudrate],[data bits],[stop bits],[parity])</pre>
* This will open an RTU connection to the client with the given parameters, and start the client immediately.
+
 
* Returns a handle on success, -1 on failure.
+
*这将打开与给定参数的客户端的RTU连接,并立即启动客户端。
=== Stopping client components ===
+
*成功返回的句柄,失败时返回-1。
A specific client can be stopped by calling:
+
 
 +
=== 停止客户端组件 ===
 +
 
 +
一个特定的客户端可以通过调用来停止:
 
<pre>result = mb_client_stop([handle])</pre>
 
<pre>result = mb_client_stop([handle])</pre>
* Given a handle, this will stop and free the memory of the appropriate client component.
+
 
* Returns 0 on success, -1 on failure.
+
*给定句柄,这将停止并释放相应客户端组件的内存。
== Reset the Modbus System ==
+
*成功返回0,失败时返回-1。
Sometimes, a user may wish to stop all server and client components at once, and reset the Modbus system (for example, when a user want to initialize a different Modbus system). To do that, call:
+
 
 +
== 重置Modbus系统 ==
 +
 
 +
有时,用户可能希望同时停止所有服务器和客户端组件,并重置Modbus系统(例如,当用户想要初始化不同的Modbus系统时)。 要这样做时,调用:
 
<pre>result = mb_reset</pre>
 
<pre>result = mb_reset</pre>
This function:
 
* Stops all running servers and clients.
 
* Frees their memory.
 
* Frees the shared address space.
 
* Reset the handle counter.
 
* Returns 0 on success, -1 on failure.
 
  
'''<u>Notice:</u>''' This function is called <u>automatically</u> when calling ''reset all''.
+
该功能将:
 +
 
 +
*停止所有正在运行的服务器和客户端。
 +
*释放自己的内存
 +
*释放共享地址空间。
 +
*复位手柄计数器。
 +
*成功返回0,失败时返回-1。
 +
 
 +
'''<u>注意:</u>'''当调用''reset all''时,这个功能被自动调用。
 +
 
 +
== 读写 ==
 +
 
 +
*服务器可以读写自己的地址空间。
 +
*客户端可以读写远程服务器的地址空间。
 +
*因此,服务器和客户端使用不同的功能从地址空间读取/写入数据。
  
== Reading and Writing ==
+
=== '''服务器组件''' ===
* Servers can read and write their own address space.
+
 
* Clients can read and write a remote server’s address space.
+
----
* Therefore, Servers and clients use different functions to read/write data from the address space.
+
 
=== '''Server Components''' ===
+
==== ====
<hr>
+
 
==== Reading ====
+
*以下函数从不同类型的寄存器读取变量并返回它们。
* The following functions read variables from the different types of registers and return them.
+
*当发生读错误时,功能将在消息日志中写入[功能名称] +“错误代码”+ [错误代码]
* When a read error occurs, the functions will write [function name] + "ERROR" + [error code] in the Message Log.
+
 
===== Reading from Holding registers =====
+
===== 从保持寄存器读取 =====
<pre>
+
<pre>Val = MB_SERVER_READ_REG_LONG([index], [byte_swap], [word_swap])
Val = MB_SERVER_READ_REG_LONG([index], [byte_swap], [word_swap])
 
 
Val = MB_SERVER_READ_REG_SHORT([index], [byte_swap])
 
Val = MB_SERVER_READ_REG_SHORT([index], [byte_swap])
 
Val = MB_SERVER_READ_REG_FLOAT([index], [byte_swap], [word_swap])
 
Val = MB_SERVER_READ_REG_FLOAT([index], [byte_swap], [word_swap])
 
Val = MB_SERVER_READ_REG_DOUBLE([index], [byte_swap], [word_swap], [long swap])
 
Val = MB_SERVER_READ_REG_DOUBLE([index], [byte_swap], [word_swap], [long swap])
 
</pre>
 
</pre>
===== Reading from Bits registers =====
+
 
 +
===== 从位寄存器读取 =====
 
<pre>val = MB_SERVER_READ_BIT([index])</pre>
 
<pre>val = MB_SERVER_READ_BIT([index])</pre>
===== Reading from Input registers =====
+
 
<pre>
+
===== 从输入寄存器读取 =====
Val = MB_SERVER_READ_INREG_LONG([index], [byte_swap], [word_swap])
+
<pre>Val = MB_SERVER_READ_INREG_LONG([index], [byte_swap], [word_swap])
 
Val = MB_SERVER_READ_INREG_SHORT([index], [byte_swap])
 
Val = MB_SERVER_READ_INREG_SHORT([index], [byte_swap])
 
Val = MB_SERVER_READ_INREG_FLOAT([index], [byte_swap], [word_swap])
 
Val = MB_SERVER_READ_INREG_FLOAT([index], [byte_swap], [word_swap])
 
Val = MB_SERVER_READ_INREG_DOUBLE([index], [byte_swap], [word_swap], [long swap])
 
Val = MB_SERVER_READ_INREG_DOUBLE([index], [byte_swap], [word_swap], [long swap])
 
</pre>
 
</pre>
===== Reading from Input Bits registers =====
+
 
 +
===== 从输入位寄存器读取 =====
 
<pre> val = MB_SERVER_READ_INBIT([index])</pre>
 
<pre> val = MB_SERVER_READ_INBIT([index])</pre>
===== Valid Parameters =====
+
 
{| class="wikitable" border="1"
+
===== 有效参数 =====
 +
 
 +
{| border="1" class="wikitable"
 
|-
 
|-
! Parameter
+
! 参数
! Valid Input
+
! 有效输入
 
|-
 
|-
 
| Index
 
| Index
| From 0 to the number of registers available.
+
| 从0到可用的寄存器数。
 
|-
 
|-
 
| Byte_swap
 
| Byte_swap
Line 211: Line 272:
 
| 1 or 0 (True/False)
 
| 1 or 0 (True/False)
 
|}
 
|}
==== Writing ====
+
 
* The following functions write data into the different types of registers.
+
==== ====
* When a write error occurs, the functions will write [function name] + "ERROR" + [error code] in the Message Log.
+
 
===== Writing to holding registers =====
+
*以下功能将数据写入不同类型的寄存器。
<pre>
+
*当发生写入错误时,功能将在消息日志中写入[功能名称] +“错误代码”+ [错误代码]
Val = MB_SERVER_WRITE_REG_LONG([index],[new value],[byte swap], [word swap])
+
 
 +
===== 写入寄存器 =====
 +
<pre>Val = MB_SERVER_WRITE_REG_LONG([index],[new value],[byte swap], [word swap])
 
Val = MB_SERVER_WRITE_REG_SHORT([index],[new value],[byte swap])
 
Val = MB_SERVER_WRITE_REG_SHORT([index],[new value],[byte swap])
 
Val = MB_SERVER_WRITE_REG_FLOAT([index],[new value],[byte swap], [word swap])
 
Val = MB_SERVER_WRITE_REG_FLOAT([index],[new value],[byte swap], [word swap])
 
Val = MB_SERVER_WRITE_REG_DOUBLE([index],[new value],[byte swap], [word swap], [long swap])
 
Val = MB_SERVER_WRITE_REG_DOUBLE([index],[new value],[byte swap], [word swap], [long swap])
 
</pre>
 
</pre>
===== Writing to Bits registers =====
+
 
 +
===== 写入位寄存器 =====
 
<pre>val = MB_SERVER_WRITE_BIT([index],[new value])</pre>
 
<pre>val = MB_SERVER_WRITE_BIT([index],[new value])</pre>
===== Writing to Input registers =====
+
 
<pre>
+
===== 写入输入寄存器 =====
Val = MB_SERVER_WRITE_INREG_LONG([index],[new value],[byte swap], [word swap])
+
<pre>Val = MB_SERVER_WRITE_INREG_LONG([index],[new value],[byte swap], [word swap])
 
Val = MB_SERVER_WRITE_INREG_SHORT([index],[new value],[byte swap])
 
Val = MB_SERVER_WRITE_INREG_SHORT([index],[new value],[byte swap])
 
Val = MB_SERVER_WRITE_INREG_FLOAT([index],[new value],[byte swap], [word swap])
 
Val = MB_SERVER_WRITE_INREG_FLOAT([index],[new value],[byte swap], [word swap])
 
Val = MB_SERVER_WRITE_INREG_DOUBLE([index],[new value],[byte swap], [word swap], [long swap])
 
Val = MB_SERVER_WRITE_INREG_DOUBLE([index],[new value],[byte swap], [word swap], [long swap])
 
</pre>
 
</pre>
===== Writing to Input Bits registers =====
+
 
 +
===== 写入输入位寄存器 =====
 
<pre>val = MB_SERVER_WRITE_INBIT([index],[value])</pre>
 
<pre>val = MB_SERVER_WRITE_INBIT([index],[value])</pre>
===== Valid Parameters =====
+
 
{| class="wikitable" border="1"
+
===== 有效参数 =====
 +
 
 +
{| border="1" class="wikitable"
 
|-
 
|-
! Parameter
+
! 参数
! Valid Input
+
! 有效输入
 
|-
 
|-
 
| Index
 
| Index
| From 0 to the number of registers available.
+
| 从0到可用的寄存器数
 
|-
 
|-
 
| New value
 
| New value
| The value to write, must be from the appropriate type.
+
| 写入的值必须来自适当的类型
 
|-
 
|-
 
| Byte_swap
 
| Byte_swap
Line 253: Line 320:
 
| 1 or 0 (True/False)
 
| 1 or 0 (True/False)
 
|}
 
|}
==== Error codes ====
+
 
{| class="wikitable" border="1"
+
==== 错误代码 ====
 +
 
 +
{| border="1" class="wikitable"
 
|-
 
|-
! Error
+
! 错误
! Meaning
+
! 含义
 
|-
 
|-
 
| -1
 
| -1
| Invalid index.
+
| 索引无效
 
|-
 
|-
 
| -2
 
| -2
| Local server's address space isn't mapped yet.
+
| 本地服务器的地址空间尚未映射
 
|-
 
|-
 
| -3
 
| -3
| Failed to catch the register mutex.
+
| 无法抓取寄存器互斥
 
|-
 
|-
 
| -4
 
| -4
| Failed to release the register mutex.
+
| 无法释放寄存器互斥
 
|}
 
|}
  
=== '''Client Components''' ===
+
=== '''客户端组件''' ===
<hr>
+
 
==== Reading ====
+
----
* The following functions read variables from the different types of registers in a REMOTE modbus server.
+
 
* The read value is inserted into an existing variable from the appropriate type (long/double).
+
==== ====
* The functions return 0 on success or an error code (not 0) on failure.
+
 
===== Reading from Holding registers =====
+
*以下功能从REMOTE modbus服务器中的不同类型的寄存器读取变量。
<pre>
+
*读取值从适当的类型(long/double)插入到现有变量中。
Val = MB_CLIENT_READ_REG_LONG([handle],[deviceID],[addr],[dest ptr])
+
*成功时,函数返回0或失败时返回错误代码(不为0)。
 +
 
 +
===== 从保持寄存器读取 =====
 +
<pre>Val = MB_CLIENT_READ_REG_LONG([handle],[deviceID],[addr],[dest ptr])
 
Val = MB_CLIENT_READ_REG_SHORT([handle],[deviceID],[addr],[dest ptr])
 
Val = MB_CLIENT_READ_REG_SHORT([handle],[deviceID],[addr],[dest ptr])
 
Val = MB_CLIENT_READ_REG_FLOAT([handle],[deviceID],[addr],[dest ptr])
 
Val = MB_CLIENT_READ_REG_FLOAT([handle],[deviceID],[addr],[dest ptr])
 
Val = MB_CLIENT_READ_REG_DOUBLE([handle],[deviceID],[addr],[dest ptr])
 
Val = MB_CLIENT_READ_REG_DOUBLE([handle],[deviceID],[addr],[dest ptr])
 
</pre>
 
</pre>
===== Reading from Bits registers =====
+
 
 +
===== 从位寄存器中读取 =====
 
<pre>val = MB_CLIENT_READ_BITS ([handle],[deviceID],[addr],[num of bits],[dest arr ptr])</pre>
 
<pre>val = MB_CLIENT_READ_BITS ([handle],[deviceID],[addr],[num of bits],[dest arr ptr])</pre>
===== Reading from Input registers =====
+
 
<pre>
+
===== 从输入寄存器中读取 =====
Val = MB_CLIENT_READ_INREG_LONG ([handle],[deviceID],[addr],[dest ptr])  
+
<pre>Val = MB_CLIENT_READ_INREG_LONG ([handle],[deviceID],[addr],[dest ptr])  
 
Val = MB_CLIENT_READ_INREG_SHORT([handle],[deviceID],[addr],[dest ptr])
 
Val = MB_CLIENT_READ_INREG_SHORT([handle],[deviceID],[addr],[dest ptr])
 
Val = MB_CLIENT_READ_INREG_FLOAT([handle],[deviceID],[addr],[dest ptr])
 
Val = MB_CLIENT_READ_INREG_FLOAT([handle],[deviceID],[addr],[dest ptr])
 
Val = MB_CLIENT_READ_INREG_DOUBLE([handle],[deviceID],[addr],[dest ptr])
 
Val = MB_CLIENT_READ_INREG_DOUBLE([handle],[deviceID],[addr],[dest ptr])
 
</pre>
 
</pre>
===== Reading from Input Bits registers =====
+
 
 +
===== 从输入位寄存器读取 =====
 
<pre>val = MB_CLIENT_READ_INBITS ([handle],[deviceID],[addr],[num of bits],[dest arr ptr])</pre>
 
<pre>val = MB_CLIENT_READ_INBITS ([handle],[deviceID],[addr],[num of bits],[dest arr ptr])</pre>
===== Valid Parameters =====
+
 
{| class="wikitable" border="1"
+
===== 有效参数 =====
 +
 
 +
{| border="1" class="wikitable"
 
|-
 
|-
! Parameter
+
! 参数
! Valid Input
+
! 有效输入
 
|-
 
|-
 
| Handle
 
| Handle
| The client's unique identifier (received on client creation).
+
| 客户端的唯一标识符(在客户端创建时收到)
 
|-
 
|-
 
| DeviceID
 
| DeviceID
| The remote server(slave)'s device ID.
+
| 远程服务器(从站)的设备ID
 
|-
 
|-
 
| Addr
 
| Addr
| The index of the register to read from.
+
| 要从中读取的寄存器的索引
 
|-
 
|-
 
| Num of bits (Reading bits)
 
| Num of bits (Reading bits)
| The number of bits to read.
+
| 要读取的位数
 
|-
 
|-
 
| dest ptr / dest arr ptr
 
| dest ptr / dest arr ptr
| The variable to store the read data. When reading bits, this must be an array of longs in the appropriate size (>= Num of bits).
+
| 用于存储读取数据的变量。 读取位时,必须是适当大小的长整数(> =位数)
 
|}
 
|}
==== Writing ====
+
 
* The following functions write data from existing variables to the different types of registers in a REMOTE modbus server.
+
==== ====
* The functions return 0 on success or an error code (not 0) on failure.
+
 
===== Writing to Holding registers =====
+
*以下功能将数据从现有变量写入REMOTE modbus服务器中的不同类型的寄存器。
<pre>
+
*成功时,函数返回0或失败时返回错误代码(不为0)
Val = MB_CLIENT_WRITE_REG_LONG([handle],[deviceID],[addr],[src ptr])
+
 
 +
===== 写入寄存器 =====
 +
<pre>Val = MB_CLIENT_WRITE_REG_LONG([handle],[deviceID],[addr],[src ptr])
 
Val = MB_CLIENT_WRITE_REG_SHORT([handle],[deviceID],[addr],[src ptr])
 
Val = MB_CLIENT_WRITE_REG_SHORT([handle],[deviceID],[addr],[src ptr])
 
Val = MB_CLIENT_WRITE_REG_FLOAT([handle],[deviceID],[addr],[src ptr])
 
Val = MB_CLIENT_WRITE_REG_FLOAT([handle],[deviceID],[addr],[src ptr])
 
Val = MB_CLIENT_WRITE_REG_DOUBLE([handle],[deviceID],[addr],[src ptr])
 
Val = MB_CLIENT_WRITE_REG_DOUBLE([handle],[deviceID],[addr],[src ptr])
 
</pre>
 
</pre>
===== Writing to Bits registers =====
+
 
 +
===== 写入位寄存器 =====
 
<pre>val = MB_CLIENT_WRITE_BIT([handle],[deviceID],[addr],[src ptr])</pre>
 
<pre>val = MB_CLIENT_WRITE_BIT([handle],[deviceID],[addr],[src ptr])</pre>
===== Valid Parameters =====
+
 
{| class="wikitable" border="1"
+
===== 有效参数 =====
 +
 
 +
{| border="1" class="wikitable"
 
|-
 
|-
! Parameter
+
! 参数
! Valid Input
+
! 有效输入
 
|-
 
|-
 
| Handle
 
| Handle
| The client's unique identifier (received on client creation).
+
| 客户端的唯一标识符(在客户端创建时收到)
 
|-
 
|-
 
| DeviceID
 
| DeviceID
| The remote server(slave)'s device ID.
+
| 远程服务器(从站)的设备ID
 
|-
 
|-
 
| Addr
 
| Addr
| The index of the register to start writing to.
+
| 寄存器开始写入的索引
 
|-
 
|-
 
| src ptr
 
| src ptr
| The variable that stores the data to be written. This must be a variable from the appropriate type.
+
| 存储要写入的数据的变量。 这必须是合适的变量类型
 
|}
 
|}
  
=== '''Reading and Writing Summary''' ===
+
=== '''读和写总结''' ===
[[File:modbus;newAPI-readwriteSummary.jpg|850px]]
+
 
 +
[[File:modbus;newAPI-readwriteSummary.jpg|850px|modbus;newAPI-readwriteSummary.jpg]]
 +
 
 +
&nbsp;
 +
 
 +
= Modbus配置器 =
 +
 
 +
== 背景 ==
 +
 
 +
=== 概述 ===
 +
 
 +
Modbus通信脚本生成器('''Modbus Configurator''')是一种工具,可将您的softMC应用程序变量映射到Modbus标签。
  
 +
'''注意''': 从HMI的角度定义了标签访问。 也就是:
  
=Modbus Configurator=
+
*'''读取访问''' 变量由softMC写入Modbus地址空间。
== Background ==
+
*'''写入访问''' 变量由softMC从Modbus地址空间读取。
=== General ===
 
The Modbus Communication Scripts Generator ('''Modbus Configurator''') is a tool that allows you to map your softMC application variables to Modbus tags.
 
  
'''Note''': Tag access is defined from the HMI perspective. In other words:
+
您可以定义变量是否具有读取访问权限或写访问权限。 目前,不可能将变量定义为具有读访问权限和写访问权限。 但是,通过在HMIMBMAP.LIB中生成的特殊例行程序,系统启动时,所有写访问变量都可以被softMC一次写入(见下节)。
* '''Read Access''' variables are written by the softMC to the Modbus address space.
 
* '''Write Access''' variables are read by the softMC from the Modbus address space.
 
  
You can define whether a variable has Read Access, or Write Access. Currently, it is not possible to define a variable as having both Read Access and Write Access. However, all Write Access variables can be written once by the softMC upon system startup by a special routine that is generated in HMIMBMAP.LIB (see section below).
+
MCMB配置器创建三个文件:
  
The MCMBConfigurator creates three files:
+
*'''HMIMBMAP.LIB''' '''HMIMBMAP.PRG'''文件是用于启动softMC任务的MC-Basic脚本。 这些是默认文件名,可以更改,但必须保留8.3格式。 根据访问类型,此任务可无限循环读取/写入Modbus标签。
* '''HMIMBMAP.LIB''' and '''HMIMBMAP.PRG''' files are MC-Basic scripts that are used to start a softMC task. These are default file names, which you can change, but must retain the 8.3 format. This task cyclically and indefinitely reads/writes Modbus tags according to access type.
+
*可以由HMI开发环境(如'''JMobile Studio''''''Indusoft''')使用的'''.CSV'''格式文件自动导入Modbus标签。 您可以通过选择将生成.csv文件的各种Python脚本来定义HMI开发环境。
* A '''.CSV''' format file that can be used by an HMI development environment, such as '''JMobile Studio''' or '''Indusoft''', to automatically import Modbus tags. You define the HMI development environment by selecting various Python scripts that will generate the .csv file.
 
=== Mapping Variables ===
 
* Variables destined to be mapped to Modbus tags must be defined as global variables by the '''common Shared''' declaration.
 
* In order to map the variables, the program must be loaded in the softMC.
 
  
== Getting Started ==
+
=== 变量映射 ===
#Start the Modbus Configurator: from the ControlStudio toolbar, select '''Tools > Modbus Configurator'''. The Modbus Configurator tool will appear.
 
#From the top menu, Select '''Connection > Setting'''.
 
#'''Enter the MC's IP and port''' (default connection port is 5001), then '''click OK'''.
 
# From the top menu, Select '''Connection > Connect'''.
 
# Configure the Modbus Address Space
 
## From the top menu, Select '''Modbus Comm. Settings'''.
 
## In the '''General''' tab, Select the appropriate python script.
 
## In the '''Registers''' tab, enter the amount of registers needed per type, and the registers offset (Optional).
 
##* Notice: The maximum register number is 65536.
 
## In the '''Connections''' tab, add the server connections (TCP/RTU).
 
## Click '''OK'''.
 
# Map your variables
 
#* Once the Modbus Configurator is connected to softMC it gets updated with the complete list of all the global variables. Double-clicking on variables automatically maps them to Modbus tags in consecutive order. The automatic Modbus address and data type are displayed in the table, along with the Modbus address space area in which the data will be stored (Default: Holding Registers).
 
#* If a mapped variable is '''defined as CONST''', its access type will automatically set to "Read". In such instances the access type cannot be changed. "Read Access variables are read only by the HMI; therefore the softMC only <u>writes</u> them to the Modbus address space.
 
#* If a mapped variable is '''not defined as CONST''', it automatically appears with "Write" Access. '''Double-click on the access type''' to toggle the variable between Read Access and Write Access, and thus determine whether the variable will be read or written by softMC.
 
  
[[File:softMC_Modbus_HMI_(4).png|600px]]
+
*要映射到Modbus标签的变量必须通过'''common Shared'''声明定义为全局变量。
<br/>
+
*为了映射变量,程序必须加载到softMC中。
<br/>
 
  
==Generating and Using Scripts==
+
== 开始 ==
After you are done mapping variables and defining the access types, a snapshot of the current configuration must be saved in order to generate the Modbus-handling scripts.
 
  
1. Click '''Files''', and then '''Save As'''.
+
#启动Modbus配置器:从ControlStudio工具栏中选择'''Tools > Modbus Configurator''',将显示Modbus Configurator工具。
 +
#从顶部菜单中选择'''Connection > Setting'''。
 +
#'''输入MC的IP和端口'''(默认连接端口为5001),然后'''单击OK'''。
 +
#从顶部菜单中选择'''Connection > Connect'''。
 +
#配置Modbus地址空间
 +
##从顶部菜单中选择'''Modbus Comm. Settings'''。
 +
##在'''General'''选项卡中,选择适当的python脚本。
 +
##在'''Registers'''选项卡中,输入每种类型所需的寄存器数量,寄存器的偏移量(可选)。
 +
##*注意: 最大寄存器号为65536。 
 +
##在'''Connections'''选项卡中,添加服务器连接(TCP / RTU)。
 +
##点击 '''OK'''.  
 +
#映射你的变量
 +
#*一旦将Modbus Configurator连接到softMC,就可以降使用所有全局变量的完整列表进行更新。双击变量会自动将它们连续地映射到Modbus标签。Modbus地址和数据类型自动显示在表格中,以及存储数据的Modbus地址空间区域(默认值:保持寄存器)。
 +
#*如果映射变量'''定义为CONST''',则其访问类型将自动设置为"读"。在这种情况下,无法更改访问类型。 “读访问变量只能由HMI读取;因此,softMC只将其<u>写入</u>Modbus地址空间。
 +
#*如果映射变量'''未定义为CONST''',则会自动显示"写入"访问。 双击访问类型,在读取访问和写入访问之间切换变量,从而确定变量将被softMC读取或写入。 
  
:The mapping is saved in an '''.mbas''' file.
+
[[File:softMC Modbus HMI (4).png|600px|softMC Modbus HMI (4).png]]<br/> &nbsp;
  
:If you makes changes after saving the .mbas file, the MBAS file indicator in the status bar will light up.
+
== 生成和使用脚本 ==
  
2. To generate the product files, click '''Generate'''.
+
完成映射变量并定义访问类型后,必须保存当前配置的快照才能生成Modbus处理脚本。
  
:The Log windows will display Success messages.
+
1. 单击'''Files''',然后单击'''Save As'''。
  
:The product files were created in the target folder you chose when saving the .mbas file.
+
:映射保存在'''.mbas'''文件中。
  
:The files HMIMBMAP.LIB and HMIMBMAP.PRG will automatically open in ControlStudio.
+
:如果在保存.mbas文件后进行更改,状态栏中的MBAS文件指示灯将亮起。
  
[[File:softMC_Modbus_HMI_(5).png|600px]]
+
2. 要生成产品文件,请单击'''Generate'''。
  
 +
:日志窗口将显示成功消息。
  
==Using the Modbus-Handling Scripts==
+
:在保存.mbas文件时,您选择的目标文件夹中创建了产品文件。
1. Using the ControlStudio File Manager, copy HMIMBMAP.LIB and HMIMBMAP.PRG to the softMC.
 
  
'''Note''': Before these files can be loaded and used, your application must be loaded, and all mapped variables must exist in the softMC memory.
+
:文件HMIMBMAP.LIB和HMIMBMAP.PRG将在ControlStudio中自动打开。
  
[[File:softMC_Modbus_HMI_(6).png|600px]]
+
[[File:softMC Modbus HMI (5).png|600px|softMC Modbus HMI (5).png]]
<br/>
+
 
<br/>
+
&nbsp;
1. Using the ControlStudio Terminal, load the library HMIMBMAP.LIB:
+
 
 +
== 使用Modbus处理脚本 ==
 +
 
 +
1. 使用ControlStudio文件管理器,将HMIMBMAP.LIB和HMIMBMAP.PRG复制到softMC。
 +
 
 +
'''注意''':在加载和使用这些文件之前,必须加载应用程序,并且所有映射的变量必须存在于softMC内存中。
 +
 
 +
[[File:softMC Modbus HMI (6).png|600px|softMC Modbus HMI (6).png]]<br/> <br/> 1. 使用ControlStudio终端,加载库HMIMBMAP.LIB:
 
<pre>Load HMIMBMAP.LIB</pre>
 
<pre>Load HMIMBMAP.LIB</pre>
  
:Since HMIMBMAP.PRG imports this library it must not be loaded globally. This code can be executed wherever is convenient.
+
:由于HMIMBMAP.PRG导入此库,因此不得在全局加载。 该代码可以在任何合适的地方执行。
 
 
2. Verify that the library was loaded successfully:
 
  
 +
2.验证库是否已成功加载:
 
<pre>?tasklist</pre>
 
<pre>?tasklist</pre>
  
3. Start the Modbus communication task by loading the program:
+
3. 通过加载程序启动Modbus通信任务:
 
 
 
<pre>Load HMIMBMAP.PRG</pre>
 
<pre>Load HMIMBMAP.PRG</pre>
  
HMIMBMAP.PRG is defined as '''Program Continue''', therefore it starts automatically after it is loaded and it does not require an explicit StartTask command.
+
HMIMBMAP.PRG被定义为'''Program Continue''',因此它在加载后自动启动,并且不需要显式的StartTask命令。
  
Of course, HMIMBMAP.PRG can be loaded and executed only after HMIMBMAP.LIB is loaded. Therefore, you should add the following code to AUTOEXEC.PRG or wherever is convenient:
+
当然,HMIMBMAP.PRG只能在加载HMIMBMAP.LIB之后加载和执行。 因此,您应该将以下代码添加到AUTOEXEC.PRG或其它合适的地方:
 
<pre>Load HMIMBMAP.LIB
 
<pre>Load HMIMBMAP.LIB
 
Load HMIMBMAP.PRG
 
Load HMIMBMAP.PRG
 
</pre>
 
</pre>
  
==HMIMBMAP.PRG Explained==
+
== HMIMBMAP.PRG说明 ==
The code:
+
 
 +
代码:
 
<pre>import HMIMBMAP.LIB
 
<pre>import HMIMBMAP.LIB
 
Program Continue
 
Program Continue
Line 452: Line 540:
 
End Program</pre>
 
End Program</pre>
  
The functions '''Init_Modbus''', '''Read_Modbus_Registers''' and '''Write_Modbus_Registers''' are implemented in '''HMIMBMAP.LIB''', which is automatically generated by a Python script.
+
函数'''Init_Modbus''','''Read_Modbus_Registers''''''Write_Modbus_Registers''''''HMIMBMAP.LIB'''中实现,它由Python脚本自动生成。
 +
 
 +
函数'''Init_Modbus'''启动Modbus服务器,然后将所有写入访问变量(即由softMC从 Modbus地址空间读取的所有变量)写入Modbus地址空间。 此功能允许您在HMI / PLC连接到 之前将系统设置为初始化的Modbus地址空间。 HMI / PLC可以读取地址空间并相应地进行初 始化。
 +
 
 +
函数'''Read_Modbus_Registers'''和'''Write_Modbus_Registers'''被无限循环调用。 '''Read_Modbus_Registers'''读取HMI / PLC写入的所有标签,并用新值更新写访问变量, 而'''Write_Modbus_Registers'''则相反。
 +
 
 +
= HMI IDEs and .CSV Files =
 +
 
 +
MCMB 配置器文件生成的.csv文件中的每行都保存有关单个变量的数据,例如Modbus 地址或数据类型。
 +
 
 +
该数据可以由HMI IDE用于导入Modbus标签并将其与HMI功能相关联。
 +
 
 +
不同的制造商IDE使用不同的.csv格式化; 因此,使用各种Python脚本来创建适合特定制造 商IDE的特定的.csv文件。
 +
 
 +
== JMobile Studio ==
 +
 
 +
Python脚本: '''JMobile_csv.py'''
 +
 
 +
默认目标.csv文件名: '''JMobile_HMI.csv''' (user-definable)
  
The function '''Init_Modbus''' starts the Modbus server and then writes to the Modbus address space all the '''Write Access Variables''' (i.e., all the variables read by the softMC from the Modbus address space). This feature allows you to setup the system to start with an initialized Modbus address space before the HMI/PLC connects to it. The HMI/PLC can read the address space and initialize itself accordingly.
+
要导入标签,请在JMobile Studio中执行以下步骤。
  
The functions '''Read_Modbus_Registers''' and '''Write_Modbus_Registers''' are invoked cyclically and indefinitely. '''Read_Modbus_Registers''' reads all the tags that are written by the HMI/PLC and updates the '''Write Access''' variables with new values, while '''Write_Modbus_Registers''' does the opposite.
+
=== 定义协议 ===
  
=HMI IDEs and .CSV Files=
+
1. 在ProjectView窗格中,选择'''Protocols'''。
Each line in the .csv file generated by the MCMBConfigurator file holds data about a single variable, such as Modbus address or data type.
 
 
This data can be used by an HMI IDE to import Modbus tags and associate them with HMI functionality.
 
  
Different manufacturer IDEs use different .csv formatting; therefore, various Python scripts are used to create the specific .csv files suitable for a particular manufacturer IDE.
+
2. 点击蓝色的'''+'''号
  
==JMobile Studio==
+
3. 从列表中选择Modbus TCP。
Python script: '''JMobile_csv.py'''
 
  
Default target .csv file name: '''JMobile_HMI.csv''' (user-definable)
+
4. 在Modbus TCP配置窗口中,定义:
  
To import tags, perform the following procedure in JMobile Studio.
+
:IP地址:设置您的softMC的IP地址。
  
===Define Protocol===
+
:PLC型号:选择通用Modbus(基于0),表示softMC Modbus服务器从0开始寻址标签。
1. In the ProjectView pane, select '''Protocols'''.
 
  
2. Click the blue '''+''' sign.
+
:单击 '''OK'''.  
  
3. From the list, select Modbus TCP.
+
[[File:softMC Modbus HMI (7).png|600px|softMC Modbus HMI (7).png]]<br/> &nbsp;
  
4. In the Modbus TCP configuration window, define:
+
=== 导入标签 ===
  
:IP Address: Set the IP address of your softMC.
+
1. 在ProjectView窗格中,选择'''Tags'''。
  
:PLC Models: Select '''Generic Modbus''' (0-based), meaning the softMC Modbus server starts addressing tags from 0.
+
2. 从列表中选择以前定义的Modbus TCP协议。
  
:Click '''OK'''.
+
[[File:softMC Modbus HMI (8).png|600px|softMC Modbus HMI (8).png]]<br/> <br/> 3. 点击'''Import Tags'''按钮。
  
[[File:softMC_Modbus_HMI_(7).png|600px]]
+
4. 打开生成的文件'''JMobile_HMI.csv'''
<br/>
 
<br/>
 
===Import Tags===
 
1. In the ProjectView pane, select '''Tags'''.
 
  
2. From the list, select '''Modbus TCP''' protocol defined previously.
+
[[File:softMC Modbus HMI (9).png|600px|softMC Modbus HMI (9).png]]<br/> <br/> 5. 选择要添加到项目的标签,然后单击 ''Import tags''按钮。
  
[[File:softMC_Modbus_HMI_(8).png|600px]]
+
[[File:softMC Modbus HMI (10).png|600px|softMC Modbus HMI (10).png]]<br/> &nbsp;
<br/>
 
<br/>
 
3. Click the '''Import Tags''' button.
 
  
4. Open the generated file '''JMobile_HMI.csv'''.
+
== AdvancedHMI ==
  
[[File:softMC_Modbus_HMI_(9).png|600px]]
+
AdvancedHMI是一个开源项目([http://www.advancedhmi.com/),它作为Visual http://www.advancedhmi.com/),它作为Visual] Basic项目 下载。 然后,您可以打开项目,添加小部件,编译并运行它。
<br/>
 
<br/>
 
5. Select the tags you want to add to your project, and click the ''Import tags'' button.
 
  
[[File:softMC_Modbus_HMI_(10).png|600px]]
+
[[File:softMC Modbus HMI (11).png|600px|softMC Modbus HMI (11).png]]<br/> <br/> 1. 将ModbusTCPCom拖放到MainForm.vb [Design]中。
<br/>
 
<br/>
 
  
==AdvancedHMI==
+
2. 驱动程序出现在屏幕的底部(绿色圈出)。
AdvancedHMI is an open source project (http://www.advancedhmi.com/), which is downloaded as a Visual Basic project. You can then open the project, add widgets, compile, and run it.
 
  
[[File:softMC_Modbus_HMI_(11).png|600px]]
+
:单击驱动程序,然后使用属性窗格(红色圈出)设置Modbus服务器的IP地址。
<br/>
 
<br/>
 
1. Drag and drop '''ModbusTCPCom''' into MainForm.vb [Design].
 
  
2. The driver appears the bottom of the screen (circled in green).  
+
:例如,将DigitalPanelMeter和MomentaryButton拖放到MainForm.vb [Design]中。
  
:Click the driver, and then use the Properties pane (circled in red) to setup the IP address of the Modbus server.
+
[[File:softMC Modbus HMI (12).png|600px|softMC Modbus HMI (12).png]]<br/> <br/> 3. 对于这两个小部件,使用“属性”窗格设置与softMC应用程序的变量相关联的Modbus地址。
  
:For example, drag and drop DigitalPanelMeter and MomentaryButton into MainForm.vb [Design].
+
[[File:softMC Modbus HMI (13).png|600px|softMC Modbus HMI (13).png]]<br/> <br/> '''注意''':
  
[[File:softMC_Modbus_HMI_(12).png|600px]]
+
:
<br/>
+
::MC Modbus服务器寻址从'''40000'''开始。
<br/>
+
::AdvancedHMI Modbus客户端寻址从'''40001''开始。
3. For both widgets, use the Properties pane to set the Modbus address that is associated with the variables from the softMC application.
+
::字母L为地址前缀 
  
[[File:softMC_Modbus_HMI_(13).png|600px]]
+
4. 保存项目(Ctrl + S)。
<br/>
 
<br/>
 
'''Note''':
 
::MC Modbus server addressing starts from '''40000'''.
 
::AdvancedHMI Modbus client addressing starts from '''40001'''.
 
::Prefix the address with the letter '''L'''.
 
  
4. Save the project (Ctrl+S).
+
5. 生成项目(Ctrl + Shift + B)。
  
5. Build the project (Ctrl+Shift+B).
+
6. 运行项目(F5)。
  
6. Run the project (F5).
+
[[Category:Modbus Communication]]

Latest revision as of 16:11, 6 February 2020

语言: English  • 中文(简体)‎

 

TOP2.png

概述

基本概述

  • 本章节介绍如何为softMC设置Modbus通信,以及如何生成softMC脚本来处理Modbus通信。
  • 假设您熟悉Modbus通信的原理,尽管其中一些将在此页面中进行描述。
  • 假设您熟悉softMC,ControlStudio和MC-Basic编程。

Modbus通信背景

  • 运动控制器(MC)可以为服务器(从站),客户端(主站)或两者同时充当。
  • 每个MC连接(TCP / RTU)可以用作服务器组件(如果连接由MC的服务器端使用)或客户端组件(如果连接由MC的客户端使用)。
  • 每个组件都有自己的参数定义。
  • 当MC作为服务器时,所有服务器组件共享“相同”的内存地址空间,从而充当具有多个连接的一个服务器。
  • Modbus网络上的每个服务器(从站)都有自己的deviceID,它是1到247之间的数字。

Modbus服务器寄存器

  • Modbus服务器地址空间中有4种寄存器类型:
    1. 位(1位寄存器)
    2. 输入位(1位READ-ONLY寄存器)
    3. 保持寄存器(16位寄存器)
    4. 输入寄存器(16位只读寄存器)
  • 服务器可以读写自己的地址空间
  • 客户端可以读写远程服务器的地址空间

入门

为了开始使用Modbus功能:

  1. 下载所需的文件: File:MB_Required_files.zip
  2. 使用ControlStudio文件管理器,将以下文件上传到您的MC:
    • mb_x86.O (for softMC7 ) / mb_armA9.O (for softMC3)
    • Modbus.lib
    • MB_Load.prg
    modbus;newAPI-upload.jpg
  3. 通过键入以下命令加载MB_Load.prg:
    Load MB_Load.prg


  1. 这将加载mb_x86.O / mb_armA9.O,具体取决于您当前的系统,以及Modbus.LIB库文件。
  2. 或者, 您可以通过键入来手动加载对象文件和Modbus库:
 

 

  1. Oload mb_x86.O
    Loadglobal Modbus.LIB

现在可以配置Modbus系统。

初始化Modbus环境

要初始化Modbus环境,包括服务器地址空间,调用:

?init_multi_server([bits],[input_bits],[holding registers],[input_registers])
  • 该功能打印"success",成功返回0,或者失败时返回错误代码。
  • 注意: 即使您只需要Client组件,您也必须调用此方法。 在这种情况下,只需传递0作为所需的寄存器大小
  • 注意: 只有在没有活动的服务器组件时,才可以调用此方法。

错误代码:

错误 含义
-1 内存分配失败
-2 某些服务器仍在运行,并使用已映射的地址空间
-3 无法创建modbus映射

服务器组件

添加服务器组件

  • 每次添加组件时,您将收到一个句柄,它是组件的标识符(以供后续使用)。
  • 最好将程序中的变量保存在此处。

创建TCP服务器组件

handle = mb_tcp_server_create([port],[deviceID])
  • This opens a TCP connection to the server on port [port] with deviceID [deviceID], and starts the created server immediately.
  • Returns a handle on success, or an error code on failure.

错误代码:

错误 含义
-1 服务器地址空间尚未初始化,请调用“init_multi_server(...)”,然后重试
-2 无法创建主套接字
-3 连接失败
-4 无法创建服务器线程

创建RTU服务器组件

handle = mb_rtu_server_create([type],[port],[baudrate],[data bits],[stop bits],[parity],[deviceID])
  • 这将打开与给定参数的RTU连接,并立即启动创建的服务器。
  • 成功返回的句柄,失败时返回错误代码。

错误代码:

错误 含义
-1 服务器地址空间尚未初始化,请调用“init_multi_server(...)”,然后重试。
-2 设备字符串无效
-3 奇偶校验无效
-4 打开RTU失败
-5 分配查询缓冲区内存失败
-6 无法设置RTU模式
-7 无法连接
-8 无法创建服务器线程
-9 该设备已被另一个系统组件使用

停止服务器组件

停止特定的服务器组件

您可以通过传递其句柄来停止特定的服务器组件:

result = mb_server_stop([handle])
  • 给定句柄,这将停止并释放相应服务器组件的内存。
  • 成功返回0,失败时返回-1

停止所有服务器组件

您可以通过单次调用来停止所有服务器组件:

result = mb_server_stop_all

此功能将:

  • 停止并释放所有服务器组件。
  • 释放共享地址空间。
  • 成功返回0,失败返回-1。

客户端组件

添加客户端组件

  • 每次添加一个组件时,您将收到一个句柄,它是组件的标识符(以供后续使用)。
  • 最好将程序中的变量保存在此处。

添加TCP客户端组件

handle = mb_tcp_client_create([ip],[port])
  • 这将在给定的ip和port上打开与客户端的TCP连接,并立即启动客户端。
  • 成功时返回的句柄,失败时返回-1。

添加RTU客户端组件

handle = mb_rtu_client_create([type],[port],[baudrate],[data bits],[stop bits],[parity])
  • 这将打开与给定参数的客户端的RTU连接,并立即启动客户端。
  • 成功返回的句柄,失败时返回-1。

停止客户端组件

一个特定的客户端可以通过调用来停止:

result = mb_client_stop([handle])
  • 给定句柄,这将停止并释放相应客户端组件的内存。
  • 成功返回0,失败时返回-1。

重置Modbus系统

有时,用户可能希望同时停止所有服务器和客户端组件,并重置Modbus系统(例如,当用户想要初始化不同的Modbus系统时)。 要这样做时,调用:

result = mb_reset

该功能将:

  • 停止所有正在运行的服务器和客户端。
  • 释放自己的内存
  • 释放共享地址空间。
  • 复位手柄计数器。
  • 成功返回0,失败时返回-1。

注意:当调用reset all时,这个功能被自动调用。

读写

  • 服务器可以读写自己的地址空间。
  • 客户端可以读写远程服务器的地址空间。
  • 因此,服务器和客户端使用不同的功能从地址空间读取/写入数据。

服务器组件


  • 以下函数从不同类型的寄存器读取变量并返回它们。
  • 当发生读错误时,功能将在消息日志中写入[功能名称] +“错误代码”+ [错误代码]。
从保持寄存器读取
Val = MB_SERVER_READ_REG_LONG([index], [byte_swap], [word_swap])
Val = MB_SERVER_READ_REG_SHORT([index], [byte_swap])
Val = MB_SERVER_READ_REG_FLOAT([index], [byte_swap], [word_swap])
Val = MB_SERVER_READ_REG_DOUBLE([index], [byte_swap], [word_swap], [long swap])
从位寄存器读取
val = MB_SERVER_READ_BIT([index])
从输入寄存器读取
Val = MB_SERVER_READ_INREG_LONG([index], [byte_swap], [word_swap])
Val = MB_SERVER_READ_INREG_SHORT([index], [byte_swap])
Val = MB_SERVER_READ_INREG_FLOAT([index], [byte_swap], [word_swap])
Val = MB_SERVER_READ_INREG_DOUBLE([index], [byte_swap], [word_swap], [long swap])
从输入位寄存器读取
 val = MB_SERVER_READ_INBIT([index])
有效参数
参数 有效输入
Index 从0到可用的寄存器数。
Byte_swap 1 or 0 (True/False)
Word_swap 1 or 0 (True/False)
Long_swap 1 or 0 (True/False)

  • 以下功能将数据写入不同类型的寄存器。
  • 当发生写入错误时,功能将在消息日志中写入[功能名称] +“错误代码”+ [错误代码]。
写入寄存器
Val = MB_SERVER_WRITE_REG_LONG([index],[new value],[byte swap], [word swap])
Val = MB_SERVER_WRITE_REG_SHORT([index],[new value],[byte swap])
Val = MB_SERVER_WRITE_REG_FLOAT([index],[new value],[byte swap], [word swap])
Val = MB_SERVER_WRITE_REG_DOUBLE([index],[new value],[byte swap], [word swap], [long swap])
写入位寄存器
val = MB_SERVER_WRITE_BIT([index],[new value])
写入输入寄存器
Val = MB_SERVER_WRITE_INREG_LONG([index],[new value],[byte swap], [word swap])
Val = MB_SERVER_WRITE_INREG_SHORT([index],[new value],[byte swap])
Val = MB_SERVER_WRITE_INREG_FLOAT([index],[new value],[byte swap], [word swap])
Val = MB_SERVER_WRITE_INREG_DOUBLE([index],[new value],[byte swap], [word swap], [long swap])
写入输入位寄存器
val = MB_SERVER_WRITE_INBIT([index],[value])
有效参数
参数 有效输入
Index 从0到可用的寄存器数
New value 写入的值必须来自适当的类型
Byte_swap 1 or 0 (True/False)
Word_swap 1 or 0 (True/False)
Long_swap 1 or 0 (True/False)

错误代码

错误 含义
-1 索引无效
-2 本地服务器的地址空间尚未映射
-3 无法抓取寄存器互斥
-4 无法释放寄存器互斥

客户端组件


  • 以下功能从REMOTE modbus服务器中的不同类型的寄存器读取变量。
  • 读取值从适当的类型(long/double)插入到现有变量中。
  • 成功时,函数返回0或失败时返回错误代码(不为0)。
从保持寄存器读取
Val = MB_CLIENT_READ_REG_LONG([handle],[deviceID],[addr],[dest ptr])
Val = MB_CLIENT_READ_REG_SHORT([handle],[deviceID],[addr],[dest ptr])
Val = MB_CLIENT_READ_REG_FLOAT([handle],[deviceID],[addr],[dest ptr])
Val = MB_CLIENT_READ_REG_DOUBLE([handle],[deviceID],[addr],[dest ptr])
从位寄存器中读取
val = MB_CLIENT_READ_BITS ([handle],[deviceID],[addr],[num of bits],[dest arr ptr])
从输入寄存器中读取
Val = MB_CLIENT_READ_INREG_LONG ([handle],[deviceID],[addr],[dest ptr]) 
Val = MB_CLIENT_READ_INREG_SHORT([handle],[deviceID],[addr],[dest ptr])
Val = MB_CLIENT_READ_INREG_FLOAT([handle],[deviceID],[addr],[dest ptr])
Val = MB_CLIENT_READ_INREG_DOUBLE([handle],[deviceID],[addr],[dest ptr])
从输入位寄存器读取
val = MB_CLIENT_READ_INBITS ([handle],[deviceID],[addr],[num of bits],[dest arr ptr])
有效参数
参数 有效输入
Handle 客户端的唯一标识符(在客户端创建时收到)
DeviceID 远程服务器(从站)的设备ID
Addr 要从中读取的寄存器的索引
Num of bits (Reading bits) 要读取的位数
dest ptr / dest arr ptr 用于存储读取数据的变量。 读取位时,必须是适当大小的长整数(> =位数)

  • 以下功能将数据从现有变量写入REMOTE modbus服务器中的不同类型的寄存器。
  • 成功时,函数返回0或失败时返回错误代码(不为0)
写入寄存器
Val = MB_CLIENT_WRITE_REG_LONG([handle],[deviceID],[addr],[src ptr])
Val = MB_CLIENT_WRITE_REG_SHORT([handle],[deviceID],[addr],[src ptr])
Val = MB_CLIENT_WRITE_REG_FLOAT([handle],[deviceID],[addr],[src ptr])
Val = MB_CLIENT_WRITE_REG_DOUBLE([handle],[deviceID],[addr],[src ptr])
写入位寄存器
val = MB_CLIENT_WRITE_BIT([handle],[deviceID],[addr],[src ptr])
有效参数
参数 有效输入
Handle 客户端的唯一标识符(在客户端创建时收到)
DeviceID 远程服务器(从站)的设备ID
Addr 寄存器开始写入的索引
src ptr 存储要写入的数据的变量。 这必须是合适的变量类型

读和写总结

modbus;newAPI-readwriteSummary.jpg

 

Modbus配置器

背景

概述

Modbus通信脚本生成器(Modbus Configurator)是一种工具,可将您的softMC应用程序变量映射到Modbus标签。

注意: 从HMI的角度定义了标签访问。 也就是:

  • 读取访问 变量由softMC写入Modbus地址空间。
  • 写入访问 变量由softMC从Modbus地址空间读取。

您可以定义变量是否具有读取访问权限或写访问权限。 目前,不可能将变量定义为具有读访问权限和写访问权限。 但是,通过在HMIMBMAP.LIB中生成的特殊例行程序,系统启动时,所有写访问变量都可以被softMC一次写入(见下节)。

MCMB配置器创建三个文件:

  • HMIMBMAP.LIBHMIMBMAP.PRG文件是用于启动softMC任务的MC-Basic脚本。 这些是默认文件名,可以更改,但必须保留8.3格式。 根据访问类型,此任务可无限循环读取/写入Modbus标签。
  • 可以由HMI开发环境(如JMobile StudioIndusoft)使用的.CSV格式文件自动导入Modbus标签。 您可以通过选择将生成.csv文件的各种Python脚本来定义HMI开发环境。

变量映射

  • 要映射到Modbus标签的变量必须通过common Shared声明定义为全局变量。
  • 为了映射变量,程序必须加载到softMC中。

开始

  1. 启动Modbus配置器:从ControlStudio工具栏中选择Tools > Modbus Configurator,将显示Modbus Configurator工具。
  2. 从顶部菜单中选择Connection > Setting
  3. 输入MC的IP和端口(默认连接端口为5001),然后单击OK
  4. 从顶部菜单中选择Connection > Connect
  5. 配置Modbus地址空间
    1. 从顶部菜单中选择Modbus Comm. Settings
    2. General选项卡中,选择适当的python脚本。
    3. Registers选项卡中,输入每种类型所需的寄存器数量,寄存器的偏移量(可选)。
      • 注意: 最大寄存器号为65536。
    4. Connections选项卡中,添加服务器连接(TCP / RTU)。
    5. 点击 OK.
  6. 映射你的变量
    • 一旦将Modbus Configurator连接到softMC,就可以降使用所有全局变量的完整列表进行更新。双击变量会自动将它们连续地映射到Modbus标签。Modbus地址和数据类型自动显示在表格中,以及存储数据的Modbus地址空间区域(默认值:保持寄存器)。
    • 如果映射变量定义为CONST,则其访问类型将自动设置为"读"。在这种情况下,无法更改访问类型。 “读访问变量只能由HMI读取;因此,softMC只将其写入Modbus地址空间。
    • 如果映射变量未定义为CONST,则会自动显示"写入"访问。 双击访问类型,在读取访问和写入访问之间切换变量,从而确定变量将被softMC读取或写入。

softMC Modbus HMI (4).png
 

生成和使用脚本

完成映射变量并定义访问类型后,必须保存当前配置的快照才能生成Modbus处理脚本。

1. 单击Files,然后单击Save As

映射保存在.mbas文件中。
如果在保存.mbas文件后进行更改,状态栏中的MBAS文件指示灯将亮起。

2. 要生成产品文件,请单击Generate

日志窗口将显示成功消息。
在保存.mbas文件时,您选择的目标文件夹中创建了产品文件。
文件HMIMBMAP.LIB和HMIMBMAP.PRG将在ControlStudio中自动打开。

softMC Modbus HMI (5).png

 

使用Modbus处理脚本

1. 使用ControlStudio文件管理器,将HMIMBMAP.LIB和HMIMBMAP.PRG复制到softMC。

注意:在加载和使用这些文件之前,必须加载应用程序,并且所有映射的变量必须存在于softMC内存中。

softMC Modbus HMI (6).png

1. 使用ControlStudio终端,加载库HMIMBMAP.LIB:

Load HMIMBMAP.LIB
由于HMIMBMAP.PRG导入此库,因此不得在全局加载。 该代码可以在任何合适的地方执行。

2.验证库是否已成功加载:

?tasklist

3. 通过加载程序启动Modbus通信任务:

Load HMIMBMAP.PRG

HMIMBMAP.PRG被定义为Program Continue,因此它在加载后自动启动,并且不需要显式的StartTask命令。

当然,HMIMBMAP.PRG只能在加载HMIMBMAP.LIB之后加载和执行。 因此,您应该将以下代码添加到AUTOEXEC.PRG或其它合适的地方:

Load HMIMBMAP.LIB
Load HMIMBMAP.PRG

HMIMBMAP.PRG说明

代码:

import HMIMBMAP.LIB
Program Continue
	dim retVal as long = 0
	retVal = Init_Modbus
	while 1
		retVal = Read_Modbus_Registers
		retVal = Write_Modbus_Registers
		sleep 1
	end while
End Program

函数Init_Modbus,Read_Modbus_RegistersWrite_Modbus_RegistersHMIMBMAP.LIB中实现,它由Python脚本自动生成。

函数Init_Modbus启动Modbus服务器,然后将所有写入访问变量(即由softMC从 Modbus地址空间读取的所有变量)写入Modbus地址空间。 此功能允许您在HMI / PLC连接到 之前将系统设置为初始化的Modbus地址空间。 HMI / PLC可以读取地址空间并相应地进行初 始化。

函数Read_Modbus_RegistersWrite_Modbus_Registers被无限循环调用。 Read_Modbus_Registers读取HMI / PLC写入的所有标签,并用新值更新写访问变量, 而Write_Modbus_Registers则相反。

HMI IDEs and .CSV Files

MCMB 配置器文件生成的.csv文件中的每行都保存有关单个变量的数据,例如Modbus 地址或数据类型。

该数据可以由HMI IDE用于导入Modbus标签并将其与HMI功能相关联。

不同的制造商IDE使用不同的.csv格式化; 因此,使用各种Python脚本来创建适合特定制造 商IDE的特定的.csv文件。

JMobile Studio

Python脚本: JMobile_csv.py

默认目标.csv文件名: JMobile_HMI.csv (user-definable)

要导入标签,请在JMobile Studio中执行以下步骤。

定义协议

1. 在ProjectView窗格中,选择Protocols

2. 点击蓝色的+

3. 从列表中选择Modbus TCP。

4. 在Modbus TCP配置窗口中,定义:

IP地址:设置您的softMC的IP地址。
PLC型号:选择通用Modbus(基于0),表示softMC Modbus服务器从0开始寻址标签。
单击 OK.

softMC Modbus HMI (7).png
 

导入标签

1. 在ProjectView窗格中,选择Tags

2. 从列表中选择以前定义的Modbus TCP协议。

softMC Modbus HMI (8).png

3. 点击Import Tags按钮。

4. 打开生成的文件JMobile_HMI.csv

softMC Modbus HMI (9).png

5. 选择要添加到项目的标签,然后单击 Import tags按钮。

softMC Modbus HMI (10).png
 

AdvancedHMI

AdvancedHMI是一个开源项目(http://www.advancedhmi.com/),它作为Visual Basic项目 下载。 然后,您可以打开项目,添加小部件,编译并运行它。

softMC Modbus HMI (11).png

1. 将ModbusTCPCom拖放到MainForm.vb [Design]中。

2. 驱动程序出现在屏幕的底部(绿色圈出)。

单击驱动程序,然后使用属性窗格(红色圈出)设置Modbus服务器的IP地址。
例如,将DigitalPanelMeter和MomentaryButton拖放到MainForm.vb [Design]中。

softMC Modbus HMI (12).png

3. 对于这两个小部件,使用“属性”窗格设置与softMC应用程序的变量相关联的Modbus地址。

softMC Modbus HMI (13).png

注意:

MC Modbus服务器寻址从40000开始。
AdvancedHMI Modbus客户端寻址从'40001开始。
字母L为地址前缀

4. 保存项目(Ctrl + S)。

5. 生成项目(Ctrl + Shift + B)。

6. 运行项目(F5)。