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

From SoftMC-Wiki
Jump to: navigation, search
 
(2 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 62: Line 82:
  
 
== 服务器组件 ==
 
== 服务器组件 ==
 +
 
=== '''添加服务器组件''' ===
 
=== '''添加服务器组件''' ===
* 每次添加组件时,您将收到一个'''句柄''',它是组件的标识符(以供后续使用)。
+
 
* 最好将程序中的变量保存在此处。
+
*每次添加组件时,您将收到一个'''句柄''',它是组件的标识符(以供后续使用)。  
 +
*最好将程序中的变量保存在此处。  
 +
 
 
==== 创建TCP服务器组件 ====
 
==== 创建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.  
 +
*Returns a handle on success, or an error code on failure.  
 +
 
 
<u>'''错误代码:'''</u>
 
<u>'''错误代码:'''</u>
{| class="wikitable" border="1"
+
 
 +
{| border="1" class="wikitable"
 
|-
 
|-
 
! 错误
 
! 错误
Line 87: Line 113:
 
| 无法创建服务器线程
 
| 无法创建服务器线程
 
|}
 
|}
 +
 
==== 创建RTU服务器组件 ====
 
==== 创建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>
* 这将打开与给定参数的RTU连接,并立即启动创建的服务器。
+
 
* 成功返回的句柄,失败时返回错误代码。
+
*这将打开与给定参数的RTU连接,并立即启动创建的服务器。  
 +
*成功返回的句柄,失败时返回错误代码。  
 +
 
 
<u>'''错误代码:'''</u>
 
<u>'''错误代码:'''</u>
{| class="wikitable" border="1"
+
 
 +
{| border="1" class="wikitable"
 
|-
 
|-
 
! 错误
 
! 错误
Line 124: Line 154:
 
| 该设备已被另一个系统组件使用
 
| 该设备已被另一个系统组件使用
 
|}
 
|}
 +
 
=== '''停止服务器组件''' ===
 
=== '''停止服务器组件''' ===
 +
 
==== 停止特定的服务器组件 ====
 
==== 停止特定的服务器组件 ====
 +
 
您可以通过传递其句柄来停止特定的服务器组件:
 
您可以通过传递其句柄来停止特定的服务器组件:
 
<pre>result = mb_server_stop([handle])</pre>
 
<pre>result = mb_server_stop([handle])</pre>
* 给定句柄,这将停止并释放相应服务器组件的内存。
+
 
* 成功返回0,失败时返回-1
+
*给定句柄,这将停止并释放相应服务器组件的内存。  
 +
*成功返回0,失败时返回-1  
 +
 
 
==== 停止所有服务器组件 ====
 
==== 停止所有服务器组件 ====
 +
 
您可以通过单次调用来停止所有服务器组件:
 
您可以通过单次调用来停止所有服务器组件:
 
<pre>result = mb_server_stop_all</pre>
 
<pre>result = mb_server_stop_all</pre>
 +
 
此功能将:
 
此功能将:
* 停止并释放所有服务器组件。
+
 
* 释放共享地址空间。
+
*停止并释放所有服务器组件。  
* 成功返回0,失败返回-1。
+
*释放共享地址空间。  
 +
*成功返回0,失败返回-1。  
 +
 
 
== 客户端组件 ==
 
== 客户端组件 ==
 +
 
=== '''添加客户端组件''' ===
 
=== '''添加客户端组件''' ===
* 每次添加一个组件时,您将收到一个'''句柄''',它是组件的标识符(以供后续使用)。
+
 
* 最好将程序中的变量保存在此处。
+
*每次添加一个组件时,您将收到一个'''句柄''',它是组件的标识符(以供后续使用)。  
 +
*最好将程序中的变量保存在此处。  
 +
 
 
==== 添加TCP客户端组件 ====
 
==== 添加TCP客户端组件 ====
 
<pre>handle = mb_tcp_client_create([ip],[port])</pre>
 
<pre>handle = mb_tcp_client_create([ip],[port])</pre>
* 这将在给定的ip和port上打开与客户端的TCP连接,并立即启动客户端。
+
 
* 成功时返回的句柄,失败时返回-1。
+
*这将在给定的ip和port上打开与客户端的TCP连接,并立即启动客户端。  
 +
*成功时返回的句柄,失败时返回-1。  
 +
 
 
==== 添加RTU客户端组件 ====
 
==== 添加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>
* 这将打开与给定参数的客户端的RTU连接,并立即启动客户端。
+
 
* 成功返回的句柄,失败时返回-1。
+
*这将打开与给定参数的客户端的RTU连接,并立即启动客户端。  
 +
*成功返回的句柄,失败时返回-1。  
 +
 
 
=== 停止客户端组件 ===
 
=== 停止客户端组件 ===
 +
 
一个特定的客户端可以通过调用来停止:
 
一个特定的客户端可以通过调用来停止:
 
<pre>result = mb_client_stop([handle])</pre>
 
<pre>result = mb_client_stop([handle])</pre>
* 给定句柄,这将停止并释放相应客户端组件的内存。
+
 
* 成功返回0,失败时返回-1。
+
*给定句柄,这将停止并释放相应客户端组件的内存。  
 +
*成功返回0,失败时返回-1。  
 +
 
 
== 重置Modbus系统 ==
 
== 重置Modbus系统 ==
 +
 
有时,用户可能希望同时停止所有服务器和客户端组件,并重置Modbus系统(例如,当用户想要初始化不同的Modbus系统时)。 要这样做时,调用:
 
有时,用户可能希望同时停止所有服务器和客户端组件,并重置Modbus系统(例如,当用户想要初始化不同的Modbus系统时)。 要这样做时,调用:
 
<pre>result = mb_reset</pre>
 
<pre>result = mb_reset</pre>
 +
 
该功能将:
 
该功能将:
*停止所有正在运行的服务器和客户端。
+
 
*释放自己的内存
+
*停止所有正在运行的服务器和客户端。  
*释放共享地址空间。
+
*释放自己的内存  
*复位手柄计数器。
+
*释放共享地址空间。  
*成功返回0,失败时返回-1。
+
*复位手柄计数器。  
 +
*成功返回0,失败时返回-1。  
  
 
'''<u>注意:</u>'''当调用''reset all''时,这个功能被自动调用。
 
'''<u>注意:</u>'''当调用''reset all''时,这个功能被自动调用。
  
 
== 读写 ==
 
== 读写 ==
* 服务器可以读写自己的地址空间。
+
 
* 客户端可以读写远程服务器的地址空间。
+
*服务器可以读写自己的地址空间。  
* 因此,服务器和客户端使用不同的功能从地址空间读取/写入数据。
+
*客户端可以读写远程服务器的地址空间。  
 +
*因此,服务器和客户端使用不同的功能从地址空间读取/写入数据。  
  
 
=== '''服务器组件''' ===
 
=== '''服务器组件''' ===
<hr>
+
 
 +
----
 +
 
 
==== 读 ====
 
==== 读 ====
* 以下函数从不同类型的寄存器读取变量并返回它们。
+
 
* 当发生读错误时,功能将在消息日志中写入[功能名称] +“错误代码”+ [错误代码]。
+
*以下函数从不同类型的寄存器读取变量并返回它们。  
 +
*当发生读错误时,功能将在消息日志中写入[功能名称] +“错误代码”+ [错误代码]。  
 +
 
 
===== 从保持寄存器读取 =====
 
===== 从保持寄存器读取 =====
<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>
 +
 
===== 从位寄存器读取 =====
 
===== 从位寄存器读取 =====
 
<pre>val = MB_SERVER_READ_BIT([index])</pre>
 
<pre>val = MB_SERVER_READ_BIT([index])</pre>
 +
 
===== 从输入寄存器读取 =====
 
===== 从输入寄存器读取 =====
<pre>
+
<pre>Val = MB_SERVER_READ_INREG_LONG([index], [byte_swap], [word_swap])
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>
 +
 
===== 从输入位寄存器读取 =====
 
===== 从输入位寄存器读取 =====
 
<pre> val = MB_SERVER_READ_INBIT([index])</pre>
 
<pre> val = MB_SERVER_READ_INBIT([index])</pre>
 +
 
===== 有效参数 =====
 
===== 有效参数 =====
{| class="wikitable" border="1"
+
 
 +
{| border="1" class="wikitable"
 
|-
 
|-
 
! 参数
 
! 参数
Line 212: Line 272:
 
| 1 or 0 (True/False)
 
| 1 or 0 (True/False)
 
|}
 
|}
 +
 
==== 写 ====
 
==== 写 ====
* 以下功能将数据写入不同类型的寄存器。
+
 
* 当发生写入错误时,功能将在消息日志中写入[功能名称] +“错误代码”+ [错误代码]。
+
*以下功能将数据写入不同类型的寄存器。  
 +
*当发生写入错误时,功能将在消息日志中写入[功能名称] +“错误代码”+ [错误代码]。  
 +
 
 
===== 写入寄存器 =====
 
===== 写入寄存器 =====
<pre>
+
<pre>Val = MB_SERVER_WRITE_REG_LONG([index],[new value],[byte swap], [word swap])
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>
 +
 
===== 写入位寄存器 =====
 
===== 写入位寄存器 =====
 
<pre>val = MB_SERVER_WRITE_BIT([index],[new value])</pre>
 
<pre>val = MB_SERVER_WRITE_BIT([index],[new value])</pre>
 +
 
===== 写入输入寄存器 =====
 
===== 写入输入寄存器 =====
<pre>
+
<pre>Val = MB_SERVER_WRITE_INREG_LONG([index],[new value],[byte swap], [word swap])
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>
 +
 
===== 写入输入位寄存器 =====
 
===== 写入输入位寄存器 =====
 
<pre>val = MB_SERVER_WRITE_INBIT([index],[value])</pre>
 
<pre>val = MB_SERVER_WRITE_INBIT([index],[value])</pre>
 +
 
===== 有效参数 =====
 
===== 有效参数 =====
{| class="wikitable" border="1"
+
 
 +
{| border="1" class="wikitable"
 
|-
 
|-
 
! 参数
 
! 参数
Line 254: Line 320:
 
| 1 or 0 (True/False)
 
| 1 or 0 (True/False)
 
|}
 
|}
 +
 
==== 错误代码 ====
 
==== 错误代码 ====
{| class="wikitable" border="1"
+
 
 +
{| border="1" class="wikitable"
 
|-
 
|-
 
! 错误
 
! 错误
Line 274: Line 342:
  
 
=== '''客户端组件''' ===
 
=== '''客户端组件''' ===
<hr>
+
 
 +
----
 +
 
 
==== 读 ====
 
==== 读 ====
* 以下功能从REMOTE modbus服务器中的不同类型的寄存器读取变量。
+
 
* 读取值从适当的类型(long/double)插入到现有变量中。
+
*以下功能从REMOTE modbus服务器中的不同类型的寄存器读取变量。  
* 成功时,函数返回0或失败时返回错误代码(不为0)。
+
*读取值从适当的类型(long/double)插入到现有变量中。  
 +
*成功时,函数返回0或失败时返回错误代码(不为0)。  
 +
 
 
===== 从保持寄存器读取 =====
 
===== 从保持寄存器读取 =====
<pre>
+
<pre>Val = MB_CLIENT_READ_REG_LONG([handle],[deviceID],[addr],[dest ptr])
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>
 +
 
===== 从位寄存器中读取 =====
 
===== 从位寄存器中读取 =====
 
<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>
 +
 
===== 从输入寄存器中读取 =====
 
===== 从输入寄存器中读取 =====
<pre>
+
<pre>Val = MB_CLIENT_READ_INREG_LONG ([handle],[deviceID],[addr],[dest 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_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>
 +
 
===== 从输入位寄存器读取 =====
 
===== 从输入位寄存器读取 =====
 
<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>
 +
 
===== 有效参数 =====
 
===== 有效参数 =====
{| class="wikitable" border="1"
+
 
 +
{| border="1" class="wikitable"
 
|-
 
|-
 
! 参数
 
! 参数
Line 318: Line 393:
 
| 用于存储读取数据的变量。 读取位时,必须是适当大小的长整数(> =位数)
 
| 用于存储读取数据的变量。 读取位时,必须是适当大小的长整数(> =位数)
 
|}
 
|}
 +
 
==== 写 ====
 
==== 写 ====
* 以下功能将数据从现有变量写入REMOTE modbus服务器中的不同类型的寄存器。
+
 
* 成功时,函数返回0或失败时返回错误代码(不为0)
+
*以下功能将数据从现有变量写入REMOTE modbus服务器中的不同类型的寄存器。  
 +
*成功时,函数返回0或失败时返回错误代码(不为0)  
 +
 
 
===== 写入寄存器 =====
 
===== 写入寄存器 =====
<pre>
+
<pre>Val = MB_CLIENT_WRITE_REG_LONG([handle],[deviceID],[addr],[src ptr])
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>
 +
 
===== 写入位寄存器 =====
 
===== 写入位寄存器 =====
 
<pre>val = MB_CLIENT_WRITE_BIT([handle],[deviceID],[addr],[src ptr])</pre>
 
<pre>val = MB_CLIENT_WRITE_BIT([handle],[deviceID],[addr],[src ptr])</pre>
 +
 
===== 有效参数 =====
 
===== 有效参数 =====
{| class="wikitable" border="1"
+
 
 +
{| border="1" class="wikitable"
 
|-
 
|-
 
! 参数
 
! 参数
Line 346: Line 426:
 
|-
 
|-
 
| src ptr
 
| src ptr
|存储要写入的数据的变量。 这必须是合适的变量类型
+
| 存储要写入的数据的变量。 这必须是合适的变量类型
 
|}
 
|}
  
 
=== '''读和写总结''' ===
 
=== '''读和写总结''' ===
[[File:modbus;newAPI-readwriteSummary.jpg|850px]]
 
  
 +
[[File:modbus;newAPI-readwriteSummary.jpg|850px|modbus;newAPI-readwriteSummary.jpg]]
 +
 +
&nbsp;
 +
 +
= Modbus配置器 =
  
=Modbus配置器=
 
 
== 背景 ==
 
== 背景 ==
 +
 
=== 概述 ===
 
=== 概述 ===
 +
 
Modbus通信脚本生成器('''Modbus Configurator''')是一种工具,可将您的softMC应用程序变量映射到Modbus标签。
 
Modbus通信脚本生成器('''Modbus Configurator''')是一种工具,可将您的softMC应用程序变量映射到Modbus标签。
  
'''注意''': 从HMI的角度定义了标签访问。 也就是:
+
'''注意''': 从HMI的角度定义了标签访问。 也就是:
* '''读取访问''' 变量由softMC写入Modbus地址空间。
 
* '''写入访问''' 变量由softMC从Modbus地址空间读取。
 
  
您可以定义变量是否具有读取访问权限或写访问权限。 目前,不可能将变量定义为具有读访问权限和写访问权限。 但是,通过在HMIMBMAP.LIB中生成的特殊例行程序,系统启动时,所有写访问变量都可以被softMC一次(写入见下节)。
+
*'''读取访问''' 变量由softMC写入Modbus地址空间。
 +
*'''写入访问''' 变量由softMC从Modbus地址空间读取。
 +
 
 +
您可以定义变量是否具有读取访问权限或写访问权限。 目前,不可能将变量定义为具有读访问权限和写访问权限。 但是,通过在HMIMBMAP.LIB中生成的特殊例行程序,系统启动时,所有写访问变量都可以被softMC一次写入(见下节)。
  
 
MCMB配置器创建三个文件:
 
MCMB配置器创建三个文件:
 +
 
*'''HMIMBMAP.LIB''' 和'''HMIMBMAP.PRG'''文件是用于启动softMC任务的MC-Basic脚本。 这些是默认文件名,可以更改,但必须保留8.3格式。 根据访问类型,此任务可无限循环读取/写入Modbus标签。  
 
*'''HMIMBMAP.LIB''' 和'''HMIMBMAP.PRG'''文件是用于启动softMC任务的MC-Basic脚本。 这些是默认文件名,可以更改,但必须保留8.3格式。 根据访问类型,此任务可无限循环读取/写入Modbus标签。  
* 可以由HMI开发环境(如'''JMobile Studio'''或'''Indusoft''')使用的'''.CSV'''格式文件自动导入Modbus标签。 您可以通过选择将生成.csv文件的各种Python脚本来定义HMI开发环境。
+
*可以由HMI开发环境(如'''JMobile Studio'''或'''Indusoft''')使用的'''.CSV'''格式文件自动导入Modbus标签。 您可以通过选择将生成.csv文件的各种Python脚本来定义HMI开发环境。  
  
 
=== 变量映射 ===
 
=== 变量映射 ===
* 要映射到Modbus标签的变量必须通过'''common Shared'''声明定义为全局变量。
+
 
* 为了映射变量,程序必须加载到softMC中。
+
*要映射到Modbus标签的变量必须通过'''common Shared'''声明定义为全局变量。  
 +
*为了映射变量,程序必须加载到softMC中。  
  
 
== 开始 ==
 
== 开始 ==
#启动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读取或写入。
 
  
[[File:softMC_Modbus_HMI_(4).png|600px]]
+
#启动Modbus配置器:从ControlStudio工具栏中选择'''Tools > Modbus Configurator''',将显示Modbus Configurator工具。
<br/>
+
#从顶部菜单中选择'''Connection > Setting'''。
<br/>
+
#'''输入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读取或写入。 
 +
 
 +
[[File:softMC Modbus HMI (4).png|600px|softMC Modbus HMI (4).png]]<br/> &nbsp;
 +
 
 +
== 生成和使用脚本 ==
  
==生成和使用脚本==
 
 
完成映射变量并定义访问类型后,必须保存当前配置的快照才能生成Modbus处理脚本。
 
完成映射变量并定义访问类型后,必须保存当前配置的快照才能生成Modbus处理脚本。
  
 
1. 单击'''Files''',然后单击'''Save As'''。
 
1. 单击'''Files''',然后单击'''Save As'''。
:映射保存在'''.mbas'''文件中。
 
  
:如果在保存.mbas文件后进行更改,状态栏中的MBAS文件指示灯将亮起。
+
:映射保存在'''.mbas'''文件中。
 +
 
 +
:如果在保存.mbas文件后进行更改,状态栏中的MBAS文件指示灯将亮起。  
  
 
2. 要生成产品文件,请单击'''Generate'''。
 
2. 要生成产品文件,请单击'''Generate'''。
  
:日志窗口将显示成功消息。
+
:日志窗口将显示成功消息。  
  
:在保存.mbas文件时,您选择的目标文件夹中创建了产品文件。
+
:在保存.mbas文件时,您选择的目标文件夹中创建了产品文件。  
  
:文件HMIMBMAP.LIB和HMIMBMAP.PRG将在ControlStudio中自动打开。
+
:文件HMIMBMAP.LIB和HMIMBMAP.PRG将在ControlStudio中自动打开。  
  
[[File:softMC_Modbus_HMI_(5).png|600px]]
+
[[File:softMC Modbus HMI (5).png|600px|softMC Modbus HMI (5).png]]
  
 +
&nbsp;
 +
 +
== 使用Modbus处理脚本 ==
  
==使用Modbus处理脚本==
 
 
1. 使用ControlStudio文件管理器,将HMIMBMAP.LIB和HMIMBMAP.PRG复制到softMC。
 
1. 使用ControlStudio文件管理器,将HMIMBMAP.LIB和HMIMBMAP.PRG复制到softMC。
  
 
'''注意''':在加载和使用这些文件之前,必须加载应用程序,并且所有映射的变量必须存在于softMC内存中。
 
'''注意''':在加载和使用这些文件之前,必须加载应用程序,并且所有映射的变量必须存在于softMC内存中。
  
[[File:softMC_Modbus_HMI_(6).png|600px]]
+
[[File:softMC Modbus HMI (6).png|600px|softMC Modbus HMI (6).png]]<br/> <br/> 1. 使用ControlStudio终端,加载库HMIMBMAP.LIB:
<br/>
 
<br/>
 
1. 使用ControlStudio终端,加载库HMIMBMAP.LIB:
 
 
<pre>Load HMIMBMAP.LIB</pre>
 
<pre>Load HMIMBMAP.LIB</pre>
  
:由于HMIMBMAP.PRG导入此库,因此不得在全局加载。 该代码可以在任何合适的地方执行。
+
:由于HMIMBMAP.PRG导入此库,因此不得在全局加载。 该代码可以在任何合适的地方执行。  
  
 
2.验证库是否已成功加载:
 
2.验证库是否已成功加载:
 
 
<pre>?tasklist</pre>
 
<pre>?tasklist</pre>
  
 
3. 通过加载程序启动Modbus通信任务:
 
3. 通过加载程序启动Modbus通信任务:
 
 
<pre>Load HMIMBMAP.PRG</pre>
 
<pre>Load HMIMBMAP.PRG</pre>
  
 
HMIMBMAP.PRG被定义为'''Program Continue''',因此它在加载后自动启动,并且不需要显式的StartTask命令。
 
HMIMBMAP.PRG被定义为'''Program Continue''',因此它在加载后自动启动,并且不需要显式的StartTask命令。
  
当然,HMIMBMAP.PRG只能在加载HMIMBMAP.LIB之后加载和执行。 因此,您应该将以下代码
+
当然,HMIMBMAP.PRG只能在加载HMIMBMAP.LIB之后加载和执行。 因此,您应该将以下代码添加到AUTOEXEC.PRG或其它合适的地方:
 
 
添加到AUTOEXEC.PRG或其它合适的地方:
 
 
 
 
<pre>Load HMIMBMAP.LIB
 
<pre>Load HMIMBMAP.LIB
 
Load HMIMBMAP.PRG
 
Load HMIMBMAP.PRG
 
</pre>
 
</pre>
  
==HMIMBMAP.PRG说明==
+
== HMIMBMAP.PRG说明 ==
 +
 
 
代码:
 
代码:
 
<pre>import HMIMBMAP.LIB
 
<pre>import HMIMBMAP.LIB
Line 458: Line 542:
 
函数'''Init_Modbus''','''Read_Modbus_Registers'''和'''Write_Modbus_Registers'''在'''HMIMBMAP.LIB'''中实现,它由Python脚本自动生成。
 
函数'''Init_Modbus''','''Read_Modbus_Registers'''和'''Write_Modbus_Registers'''在'''HMIMBMAP.LIB'''中实现,它由Python脚本自动生成。
  
函数'''Init_Modbus'''启动Modbus服务器,然后将所有写入访问变量(即由softMC从
+
函数'''Init_Modbus'''启动Modbus服务器,然后将所有写入访问变量(即由softMC从 Modbus地址空间读取的所有变量)写入Modbus地址空间。 此功能允许您在HMI / PLC连接到 之前将系统设置为初始化的Modbus地址空间。 HMI / PLC可以读取地址空间并相应地进行初 始化。
Modbus地址空间读取的所有变量)写入Modbus地址空间。 此功能允许您在HMI / PLC连接到
 
之前将系统设置为初始化的Modbus地址空间。 HMI / PLC可以读取地址空间并相应地进行初
 
始化。
 
  
函数'''Read_Modbus_Registers'''和'''Write_Modbus_Registers'''被无限循环调用。
+
函数'''Read_Modbus_Registers'''和'''Write_Modbus_Registers'''被无限循环调用。 '''Read_Modbus_Registers'''读取HMI / PLC写入的所有标签,并用新值更新写访问变量, 而'''Write_Modbus_Registers'''则相反。
'''Read_Modbus_Registers'''读取HMI / PLC写入的所有标签,并用新值更新写访问变量,
+
 
而'''Write_Modbus_Registers'''则相反。
+
= HMI IDEs and .CSV Files =
 +
 
 +
MCMB 配置器文件生成的.csv文件中的每行都保存有关单个变量的数据,例如Modbus 地址或数据类型。
  
=HMI IDEs and .CSV Files=
 
MCMB 配置器文件生成的.csv文件中的每行都保存有关单个变量的数据,例如Modbus
 
地址或数据类型。
 
 
 
该数据可以由HMI IDE用于导入Modbus标签并将其与HMI功能相关联。
 
该数据可以由HMI IDE用于导入Modbus标签并将其与HMI功能相关联。
  
不同的制造商IDE使用不同的.csv格式化; 因此,使用各种Python脚本来创建适合特定制造
+
不同的制造商IDE使用不同的.csv格式化; 因此,使用各种Python脚本来创建适合特定制造 商IDE的特定的.csv文件。
商IDE的特定的.csv文件。
 
  
==JMobile Studio==
+
== JMobile Studio ==
Python脚本: '''JMobile_csv.py'''  
+
 
 +
Python脚本: '''JMobile_csv.py'''
  
 
默认目标.csv文件名: '''JMobile_HMI.csv''' (user-definable)
 
默认目标.csv文件名: '''JMobile_HMI.csv''' (user-definable)
Line 483: Line 562:
 
要导入标签,请在JMobile Studio中执行以下步骤。
 
要导入标签,请在JMobile Studio中执行以下步骤。
  
===定义协议===
+
=== 定义协议 ===
 +
 
 
1. 在ProjectView窗格中,选择'''Protocols'''。
 
1. 在ProjectView窗格中,选择'''Protocols'''。
  
Line 490: Line 570:
 
3. 从列表中选择Modbus TCP。
 
3. 从列表中选择Modbus TCP。
  
4. 在Modbus TCP配置窗口中,定义:  
+
4. 在Modbus TCP配置窗口中,定义:
 +
 
 +
:IP地址:设置您的softMC的IP地址。
 +
 
 +
:PLC型号:选择通用Modbus(基于0),表示softMC Modbus服务器从0开始寻址标签。
  
:IP地址:设置您的softMC的IP地址。
+
:单击 '''OK'''.
  
:PLC型号:选择通用Modbus(基于0),表示softMC Modbus服务器从0开始寻址标签。
+
[[File:softMC Modbus HMI (7).png|600px|softMC Modbus HMI (7).png]]<br/> &nbsp;
  
:单击 '''OK'''.
+
=== 导入标签 ===
  
[[File:softMC_Modbus_HMI_(7).png|600px]]
 
<br/>
 
<br/>
 
===导入标签===
 
 
1. 在ProjectView窗格中,选择'''Tags'''。
 
1. 在ProjectView窗格中,选择'''Tags'''。
  
 
2. 从列表中选择以前定义的Modbus TCP协议。
 
2. 从列表中选择以前定义的Modbus TCP协议。
  
[[File:softMC_Modbus_HMI_(8).png|600px]]
+
[[File:softMC Modbus HMI (8).png|600px|softMC Modbus HMI (8).png]]<br/> <br/> 3. 点击'''Import Tags'''按钮。
<br/>
 
<br/>
 
3. 点击'''Import Tags'''按钮。
 
  
 
4. 打开生成的文件'''JMobile_HMI.csv'''。
 
4. 打开生成的文件'''JMobile_HMI.csv'''。
  
[[File:softMC_Modbus_HMI_(9).png|600px]]
+
[[File:softMC Modbus HMI (9).png|600px|softMC Modbus HMI (9).png]]<br/> <br/> 5. 选择要添加到项目的标签,然后单击 ''Import tags''按钮。
<br/>
+
 
<br/>
+
[[File:softMC Modbus HMI (10).png|600px|softMC Modbus HMI (10).png]]<br/> &nbsp;
5. 选择要添加到项目的标签,然后单击 ''Import tags''按钮。
 
  
[[File:softMC_Modbus_HMI_(10).png|600px]]
+
== AdvancedHMI ==
<br/>
 
<br/>
 
  
==AdvancedHMI==
+
AdvancedHMI是一个开源项目([http://www.advancedhmi.com/),它作为Visual http://www.advancedhmi.com/),它作为Visual] Basic项目 下载。 然后,您可以打开项目,添加小部件,编译并运行它。
AdvancedHMI是一个开源项目(http://www.advancedhmi.com/),它作为Visual Basic项目
 
下载。 然后,您可以打开项目,添加小部件,编译并运行它。
 
  
[[File:softMC_Modbus_HMI_(11).png|600px]]
+
[[File:softMC Modbus HMI (11).png|600px|softMC Modbus HMI (11).png]]<br/> <br/> 1. 将ModbusTCPCom拖放到MainForm.vb [Design]中。
<br/>
 
<br/>
 
1. 将ModbusTCPCom拖放到MainForm.vb [Design]中。
 
  
2. 驱动程序出现在屏幕的底部(绿色圈出)。  
+
2. 驱动程序出现在屏幕的底部(绿色圈出)。
  
:单击驱动程序,然后使用属性窗格(红色圈出)设置Modbus服务器的IP地址。
+
:单击驱动程序,然后使用属性窗格(红色圈出)设置Modbus服务器的IP地址。  
  
:例如,将DigitalPanelMeter和MomentaryButton拖放到MainForm.vb [Design]中。
+
:例如,将DigitalPanelMeter和MomentaryButton拖放到MainForm.vb [Design]中。  
  
[[File:softMC_Modbus_HMI_(12).png|600px]]
+
[[File:softMC Modbus HMI (12).png|600px|softMC Modbus HMI (12).png]]<br/> <br/> 3. 对于这两个小部件,使用“属性”窗格设置与softMC应用程序的变量相关联的Modbus地址。
<br/>
 
<br/>
 
3. 对于这两个小部件,使用“属性”窗格设置与softMC应用程序的变量相关联的Modbus地址。
 
  
[[File:softMC_Modbus_HMI_(13).png|600px]]
+
[[File:softMC Modbus HMI (13).png|600px|softMC Modbus HMI (13).png]]<br/> <br/> '''注意''':
<br/>
+
 
<br/>
+
:
'''注意''':
+
::MC Modbus服务器寻址从'''40000'''开始。  
::MC Modbus服务器寻址从'''40000'''开始。
+
::AdvancedHMI Modbus客户端寻址从'''40001''开始。  
::AdvancedHMI Modbus客户端寻址从'''40001''开始。
+
::字母L为地址前缀  
::字母L为地址前缀
 
  
 
4. 保存项目(Ctrl + S)。
 
4. 保存项目(Ctrl + S)。
Line 555: Line 620:
  
 
6. 运行项目(F5)。
 
6. 运行项目(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)。