Modbus Communication API/zh-hans
语言: | 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)。