Difference between revisions of "Modbus Communication API/zh-hans"
(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;"> |
+ | | ||
+ | <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库: | + | |
− | #:< | + | |
− | #::Oload mb_x86.O | + | # |
− | #::Loadglobal Modbus.LIB | + | #:这将加载mb_x86.O / mb_armA9.O,具体取决于您当前的系统,以及Modbus.LIB库文件。 |
+ | #'''或者''', 您可以通过键入来手动加载对象文件和Modbus库: | ||
+ | #:<pre> | ||
+ | </pre> | ||
+ | |||
+ | | ||
+ | # | ||
+ | #: | ||
+ | #::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> | ||
− | {| | + | |
+ | {| 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> | ||
− | {| | + | |
+ | {| 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> | ||
− | {| | + | |
+ | {| 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''时,这个功能被自动调用。 | ||
== 读写 == | == 读写 == | ||
− | * 服务器可以读写自己的地址空间。 | + | |
− | * 客户端可以读写远程服务器的地址空间。 | + | *服务器可以读写自己的地址空间。 |
− | * 因此,服务器和客户端使用不同的功能从地址空间读取/写入数据。 | + | *客户端可以读写远程服务器的地址空间。 |
+ | *因此,服务器和客户端使用不同的功能从地址空间读取/写入数据。 | ||
=== '''服务器组件''' === | === '''服务器组件''' === | ||
− | + | ||
+ | ---- | ||
+ | |||
==== 读 ==== | ==== 读 ==== | ||
− | * 以下函数从不同类型的寄存器读取变量并返回它们。 | + | |
− | * 当发生读错误时,功能将在消息日志中写入[功能名称] +“错误代码”+ [错误代码]。 | + | *以下函数从不同类型的寄存器读取变量并返回它们。 |
+ | *当发生读错误时,功能将在消息日志中写入[功能名称] +“错误代码”+ [错误代码]。 | ||
+ | |||
===== 从保持寄存器读取 ===== | ===== 从保持寄存器读取 ===== | ||
− | <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> | ||
+ | |||
===== 有效参数 ===== | ===== 有效参数 ===== | ||
− | {| | + | |
+ | {| 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> | ||
+ | |||
===== 有效参数 ===== | ===== 有效参数 ===== | ||
− | {| | + | |
+ | {| border="1" class="wikitable" | ||
|- | |- | ||
! 参数 | ! 参数 | ||
Line 254: | Line 320: | ||
| 1 or 0 (True/False) | | 1 or 0 (True/False) | ||
|} | |} | ||
+ | |||
==== 错误代码 ==== | ==== 错误代码 ==== | ||
− | {| | + | |
+ | {| border="1" class="wikitable" | ||
|- | |- | ||
! 错误 | ! 错误 | ||
Line 274: | Line 342: | ||
=== '''客户端组件''' === | === '''客户端组件''' === | ||
− | + | ||
+ | ---- | ||
+ | |||
==== 读 ==== | ==== 读 ==== | ||
− | * 以下功能从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> | ||
+ | |||
===== 有效参数 ===== | ===== 有效参数 ===== | ||
− | {| | + | |
+ | {| 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> | ||
+ | |||
===== 有效参数 ===== | ===== 有效参数 ===== | ||
− | {| | + | |
+ | {| border="1" class="wikitable" | ||
|- | |- | ||
! 参数 | ! 参数 | ||
Line 346: | Line 426: | ||
|- | |- | ||
| src ptr | | src ptr | ||
− | |存储要写入的数据的变量。 这必须是合适的变量类型 | + | | 存储要写入的数据的变量。 这必须是合适的变量类型 |
|} | |} | ||
=== '''读和写总结''' === | === '''读和写总结''' === | ||
− | |||
+ | [[File:modbus;newAPI-readwriteSummary.jpg|850px|modbus;newAPI-readwriteSummary.jpg]] | ||
+ | |||
+ | | ||
+ | |||
+ | = Modbus配置器 = | ||
− | |||
== 背景 == | == 背景 == | ||
+ | |||
=== 概述 === | === 概述 === | ||
+ | |||
Modbus通信脚本生成器('''Modbus Configurator''')是一种工具,可将您的softMC应用程序变量映射到Modbus标签。 | Modbus通信脚本生成器('''Modbus Configurator''')是一种工具,可将您的softMC应用程序变量映射到Modbus标签。 | ||
− | '''注意''': 从HMI的角度定义了标签访问。 也就是: | + | '''注意''': 从HMI的角度定义了标签访问。 也就是: |
− | |||
− | |||
− | 您可以定义变量是否具有读取访问权限或写访问权限。 目前,不可能将变量定义为具有读访问权限和写访问权限。 但是,通过在HMIMBMAP. | + | *'''读取访问''' 变量由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中。 | ||
== 开始 == | == 开始 == | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | [[File: | + | #启动Modbus配置器:从ControlStudio工具栏中选择'''Tools > Modbus Configurator''',将显示Modbus Configurator工具。 |
− | <br/> | + | #从顶部菜单中选择'''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|softMC Modbus HMI (4).png]]<br/> | ||
+ | |||
+ | == 生成和使用脚本 == | ||
− | |||
完成映射变量并定义访问类型后,必须保存当前配置的快照才能生成Modbus处理脚本。 | 完成映射变量并定义访问类型后,必须保存当前配置的快照才能生成Modbus处理脚本。 | ||
1. 单击'''Files''',然后单击'''Save As'''。 | 1. 单击'''Files''',然后单击'''Save As'''。 | ||
− | |||
− | :如果在保存.mbas文件后进行更改,状态栏中的MBAS文件指示灯将亮起。 | + | :映射保存在'''.mbas'''文件中。 |
+ | |||
+ | :如果在保存.mbas文件后进行更改,状态栏中的MBAS文件指示灯将亮起。 | ||
2. 要生成产品文件,请单击'''Generate'''。 | 2. 要生成产品文件,请单击'''Generate'''。 | ||
− | :日志窗口将显示成功消息。 | + | :日志窗口将显示成功消息。 |
− | :在保存.mbas文件时,您选择的目标文件夹中创建了产品文件。 | + | :在保存.mbas文件时,您选择的目标文件夹中创建了产品文件。 |
− | :文件HMIMBMAP.LIB和HMIMBMAP.PRG将在ControlStudio中自动打开。 | + | :文件HMIMBMAP.LIB和HMIMBMAP.PRG将在ControlStudio中自动打开。 |
− | [[File: | + | [[File:softMC Modbus HMI (5).png|600px|softMC Modbus HMI (5).png]] |
+ | | ||
+ | |||
+ | == 使用Modbus处理脚本 == | ||
− | |||
1. 使用ControlStudio文件管理器,将HMIMBMAP.LIB和HMIMBMAP.PRG复制到softMC。 | 1. 使用ControlStudio文件管理器,将HMIMBMAP.LIB和HMIMBMAP.PRG复制到softMC。 | ||
'''注意''':在加载和使用这些文件之前,必须加载应用程序,并且所有映射的变量必须存在于softMC内存中。 | '''注意''':在加载和使用这些文件之前,必须加载应用程序,并且所有映射的变量必须存在于softMC内存中。 | ||
− | [[File: | + | [[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或其它合适的地方: |
− | |||
− | |||
− | |||
<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 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开始寻址标签。 | ||
− | : | + | :单击 '''OK'''. |
− | : | + | [[File:softMC Modbus HMI (7).png|600px|softMC Modbus HMI (7).png]]<br/> |
− | + | === 导入标签 === | |
− | |||
− | |||
− | |||
− | |||
1. 在ProjectView窗格中,选择'''Tags'''。 | 1. 在ProjectView窗格中,选择'''Tags'''。 | ||
2. 从列表中选择以前定义的Modbus TCP协议。 | 2. 从列表中选择以前定义的Modbus TCP协议。 | ||
− | [[File: | + | [[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: | + | [[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/> |
− | 5. 选择要添加到项目的标签,然后单击 ''Import tags''按钮。 | ||
− | + | == AdvancedHMI == | |
− | |||
− | |||
− | + | AdvancedHMI是一个开源项目([http://www.advancedhmi.com/),它作为Visual http://www.advancedhmi.com/),它作为Visual] Basic项目 下载。 然后,您可以打开项目,添加小部件,编译并运行它。 | |
− | |||
− | 下载。 然后,您可以打开项目,添加小部件,编译并运行它。 | ||
− | [[File: | + | [[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: | + | [[File:softMC Modbus HMI (12).png|600px|softMC Modbus HMI (12).png]]<br/> <br/> 3. 对于这两个小部件,使用“属性”窗格设置与softMC应用程序的变量相关联的Modbus地址。 |
− | <br/> | ||
− | <br/> | ||
− | 3. 对于这两个小部件,使用“属性”窗格设置与softMC应用程序的变量相关联的Modbus地址。 | ||
− | [[File: | + | [[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 • 中文(简体) |
---|
Contents
概述
基本概述
- 本章节介绍如何为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位READ-ONLY寄存器)
- 保持寄存器(16位寄存器)
- 输入寄存器(16位只读寄存器)
- 服务器可以读写自己的地址空间
- 客户端可以读写远程服务器的地址空间
入门
为了开始使用Modbus功能:
- 下载所需的文件: File:MB_Required_files.zip
- 使用ControlStudio文件管理器,将以下文件上传到您的MC:
- mb_x86.O (for softMC7 ) / mb_armA9.O (for softMC3)
- Modbus.lib
- MB_Load.prg
- 通过键入以下命令加载MB_Load.prg:
Load MB_Load.prg
-
- 这将加载mb_x86.O / mb_armA9.O,具体取决于您当前的系统,以及Modbus.LIB库文件。
- 或者, 您可以通过键入来手动加载对象文件和Modbus库:
-
-
- 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配置器
背景
概述
Modbus通信脚本生成器(Modbus Configurator)是一种工具,可将您的softMC应用程序变量映射到Modbus标签。
注意: 从HMI的角度定义了标签访问。 也就是:
- 读取访问 变量由softMC写入Modbus地址空间。
- 写入访问 变量由softMC从Modbus地址空间读取。
您可以定义变量是否具有读取访问权限或写访问权限。 目前,不可能将变量定义为具有读访问权限和写访问权限。 但是,通过在HMIMBMAP.LIB中生成的特殊例行程序,系统启动时,所有写访问变量都可以被softMC一次写入(见下节)。
MCMB配置器创建三个文件:
- HMIMBMAP.LIB 和HMIMBMAP.PRG文件是用于启动softMC任务的MC-Basic脚本。 这些是默认文件名,可以更改,但必须保留8.3格式。 根据访问类型,此任务可无限循环读取/写入Modbus标签。
- 可以由HMI开发环境(如JMobile Studio或Indusoft)使用的.CSV格式文件自动导入Modbus标签。 您可以通过选择将生成.csv文件的各种Python脚本来定义HMI开发环境。
变量映射
- 要映射到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只将其写入Modbus地址空间。
- 如果映射变量未定义为CONST,则会自动显示"写入"访问。 双击访问类型,在读取访问和写入访问之间切换变量,从而确定变量将被softMC读取或写入。
生成和使用脚本
完成映射变量并定义访问类型后,必须保存当前配置的快照才能生成Modbus处理脚本。
1. 单击Files,然后单击Save As。
- 映射保存在.mbas文件中。
- 如果在保存.mbas文件后进行更改,状态栏中的MBAS文件指示灯将亮起。
2. 要生成产品文件,请单击Generate。
- 日志窗口将显示成功消息。
- 在保存.mbas文件时,您选择的目标文件夹中创建了产品文件。
- 文件HMIMBMAP.LIB和HMIMBMAP.PRG将在ControlStudio中自动打开。
使用Modbus处理脚本
1. 使用ControlStudio文件管理器,将HMIMBMAP.LIB和HMIMBMAP.PRG复制到softMC。
注意:在加载和使用这些文件之前,必须加载应用程序,并且所有映射的变量必须存在于softMC内存中。
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_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)
要导入标签,请在JMobile Studio中执行以下步骤。
定义协议
1. 在ProjectView窗格中,选择Protocols。
2. 点击蓝色的+号
3. 从列表中选择Modbus TCP。
4. 在Modbus TCP配置窗口中,定义:
- IP地址:设置您的softMC的IP地址。
- PLC型号:选择通用Modbus(基于0),表示softMC Modbus服务器从0开始寻址标签。
- 单击 OK.
导入标签
1. 在ProjectView窗格中,选择Tags。
2. 从列表中选择以前定义的Modbus TCP协议。
4. 打开生成的文件JMobile_HMI.csv。
5. 选择要添加到项目的标签,然后单击 Import tags按钮。
AdvancedHMI
AdvancedHMI是一个开源项目(http://www.advancedhmi.com/),它作为Visual Basic项目 下载。 然后,您可以打开项目,添加小部件,编译并运行它。
1. 将ModbusTCPCom拖放到MainForm.vb [Design]中。
2. 驱动程序出现在屏幕的底部(绿色圈出)。
- 单击驱动程序,然后使用属性窗格(红色圈出)设置Modbus服务器的IP地址。
- 例如,将DigitalPanelMeter和MomentaryButton拖放到MainForm.vb [Design]中。
3. 对于这两个小部件,使用“属性”窗格设置与softMC应用程序的变量相关联的Modbus地址。
-
- MC Modbus服务器寻址从40000开始。
- AdvancedHMI Modbus客户端寻址从'40001开始。
- 字母L为地址前缀
4. 保存项目(Ctrl + S)。
5. 生成项目(Ctrl + Shift + B)。
6. 运行项目(F5)。