Modbus 本身是一种信息交换的规范,Modbus TCP则是透过TCP/IP来实现Modbus 的一种方式,因此所有的信息都是通过TCP/IP来传输的;Modbus协议属于 C/S 架构,Modbus Tcp Master可以读写Rtu Slave的地址,实现数据交互;
使用场景
设备间数据采集和监控(如PLC与传感器、HMI的连接)。
过程自动化中的数据传输。
远程监控和控制系统。
整体架构
注: 本手册中用到的中科时代的软件包,均可以从官网的子页面获取。官网提供的版本可能比本手册中提到的版本更高,一般情况下这不会影响您按照本手册的例子执行相应的操作
Modbus Tcp是透过TCP/IP来实现Modbus的一种方式,因此所有讯息是透过TCP/IP来传输的,Modbus Tcp Master可以对Slave发送读或者写的指令,Slave收到指令后会回复确认信息,整个Modbus的沟通建立在一来一回的讯息交换上;
下表概述了各个产品组件
产品组件 | 描述说明 | |
---|---|---|
主站 | simodbusmaster_1.1.4_amd64.deb | Modbus tcp Master RTE组件 |
SF4100_ModbusMaster_1.0.0.2.library | Modbus tcp Master Metafacture 库文件 | |
从站 | modbusslave_1.1.3_amd64.deb | Modbus tcp Slave RTE组件 |
sf4100_modbusslave_1.0.0.1.library | Modbus tcp Slave Metafacture 库文件 |
安装要求
中科时代出厂的工智机;
安装DeviceManager.exe (0.0.2.4)软件
安装过程
工智机端安装Modbus Tcp Master RTE组件
运行DeviceManager.exe 软件
安装ACP 服务(以工智机(192.168.105.20)为例),选择“在线安装”
选择工智机(192.168.105.20),点击“本地”,进入本地安装界面;
进入工智机设备管理器界面,点击"软件”下拉选择“组件管理”,进入“浏览页面”,选择"modbusmaster"查看安装版本并点击“安装”;
传输完成,弹窗选择确定安装;安装完成后,选择确认重启组件;
安装完成后,本地新增1.1.4版本的"modbusmaster"组件,
Metafacture安装library
打开Metafacture,点击“工具” -- “库存储”
点击“安装” -- 选中modbus master的库文件,点击“打开”
工程中点击“库管理器” -- “添加库” -- 选中modbus库点击“确定”
卸载过程
工智机端卸载Modbus Tcp Master RTE组件
确认卸载组件且确定重新加载;
加载完成后,"modbusmaster" 组件被删除;
卸载MetaFacture侧的Modbus Tcp master library
本例实验要求及原理
硬件: | 软件: |
---|
本例实验要求及原理
实验要求:按照“安装卸载”部分中的“安装过程”配置完成Modbus Tcp Master环境
1、实验原理
Metafacture Modbus Tcp主站通过 TCP 连接向第三方Modbus Tcp 从站发送请求,主要包含:功能码、目标寄存器的地址和数量、写操作时的数据;从站收到请求后先检查数据的合法性,然后执行请求的操作,响应主站请求;
上位机和工智机使用EtherNet连接;
上位机上,MetaFacture下装工程到工智机。工程中会包含下面的试验操作步骤中的配置;
工智机与第三方TCPIP客户端通过EtherNet连接;
读操作
测试环境
SX21工智机作为主站,助手作为从站:
从站助手配置:
Connection 选择:Modbus TCP/IP
Ip Address :本机电脑IP地址(与工智机在同一网段)
Port :502(示例使用默认端口号)
操作步骤
1、创建工程ModbusTCPMaster 工程;
2、按照如下操作完成读功能操作;
读多线圈的实验步骤如下:
POU中声明区域调用modbus tcp master读线圈功能块
bRead : BOOL ;
ReadCoils : FB_MBTcpReadCoils;
ReadCoilData : ARRAY[0..9] OF BYTE;
c
工程运行后触发ReadCoils中的bExecute上升沿执行读取线圈的值,即写入bRead为True;
工程中调用功能块的nUnitID必须写为当前从站设置的ID值,不然会报错,并且读不到数据,后面调用其他功能块也是必须写nUnitID。
Modbus Slave 工具配置模式如下:
MetaFacture配置程序暂停并重新运行,获取结果如下:
b读取离散输入的实验步骤如下:
bRead : BOOL ;
ReadInputs : FB_MBTcpReadInputs;
ReadInputData : ARRAY[0..9] OF BYTE;
ReadInputs(sIPAddr:=ipaddr ,
nTCPPort:=502 ,
nUnitID:= 1,
nQuantity:=10 ,
nMBAddr:=0 ,
cbLength:=SIZEOF(ReadInputData) , pDestAddr:=ADR(ReadInputData) ,
bExecute:=bRead ,
tTimeout:= , bBUSY=> , bError=> , nErrId=> );
工程运行后触发ReadInputs中的bExecute上升沿执行读取离散输入的值,即写入bRead为True;
Modbus Slave工具配置模式如下:
MetaFacture配置程序暂停并重新运行,获取结果如下:
c. 读取保持寄存器的实验步骤如下:
bRead : BOOL ;
ReadRegs : FB_MBTcpReadRegs;
ReadRegsData : ARRAY[0..9] OF WORD;
ReadRegs(sIPAddr:=ipaddr ,
nTCPPort:=502 ,
nUnitID:= 1,
nQuantity:=10 ,
nMBAddr:=0 ,
cbLength:=SIZEOF(ReadRegsData) , pDestAddr:=ADR(ReadRegsData) ,
bExecute:=bRead ,
tTimeout:= , bBUSY=> , bError=> , nErrId=> );
工程运行后触发ReadRegs中的bExecute上升沿执行读取保持寄存器的值,即写入bRead为True;
Modbus Slave工具配置模式如下:
MetaFacture配置程序暂停并重新运行,获取结果如下
d. 读取输入寄存器的实验步骤如下:
bRead : BOOL ;
ReadInputRegs : FB_MBTcpReadInputRegs;
ReadInputRegsData: ARRAY[0..9] OF WORD;
ReadInputRegs(sIPAddr:=ipaddr ,
nTCPPort:=502 ,
nUnitID:=1 ,
nQuantity:=10 ,
nMBAddr:=0 ,
cbLength:=SIZEOF(ReadInputRegsData) , pDestAddr:=ADR(ReadInputRegsData) , bExecute:=bRead ,
tTimeout:= , bBUSY=> , bError=> , nErrId=> );
工程运行后触发ReadInputRegs中的bExecute上升沿执行读取输入寄存器的值,即写入bRead为True;
Modbus Slave工具配置模式如下:
MetaFacture配置程序暂停并重新运行,获取结果如下:
写操作
测试环境
SX21工智机作为主站,助手作为从站。
操作步骤
1、创建工程ModbusTCP Master 工程;
2、按照如下操作完成写功能操作;
a. 写多线圈的实验步骤如下:
bWrite : BOOL ;
WriteCoils : FB_MBTcpWriteCoils;
WriteCoilsData : ARRAY[0..9] OF BOOL:=[1,1,1,1,1];
WriteCoils(sIPAddr:=ipaddr ,
nTCPPort:=502 ,
nUnitID:=1 ,
nQuantity:=10 ,
nMBAddr:=0 ,
cbLength:=SIZEOF(WriteCoilsData) ,
pSrcAddr:=ADR(WriteCoilsData) ,
bExecute:=bWrite ,
tTimeout:= , bBUSY=> , bError=> , nErrId=> );
工程运行后触发WriteCoils中的bExecute上升沿执行写多线圈的值,即写入bWrite为True;
从站显示结果:
b. 写多保持寄存器的实验步骤如下:
bWrite : BOOL ;
WriteRegs : FB_MBTcpWriteRegs;
WriteRegsData : ARRAY[0..9] OF WORD:=[16#FF,16#FE,16#FD,16#FC,16#FB,16#FA,16#F9,16#F8,16#F7,16#F6];
WriteRegs(sIPAddr:=ipaddr ,
nTCPPort:=502 ,
nUnitID:=1 ,
nQuantity:=10 ,
nMBAddr:=0 ,
cbLength:=SIZEOF(WriteRegsData) , pSrcAddr:=ADR(WriteRegsData) ,
bExecute:=bWrite ,
tTimeout:= , bBUSY=> , bError=> , nErrId=> );
工程运行后触发WriteRegs中的bExecute上升沿执行写多保持寄存器的值,即写入bWrite为True;
从站显示结果:
测试环境
SX20工智机作为主站,SX21工智机作为从站。
Modbus Slave 端使用说明:
Modbus slaver 默认502 端口
新增M区 、Q区配置:
Q区---功能码:01 ,02 、05 位变量操作(读写)
M区---功能码:03 ,04 、06 寄存器变量操作(读写)
操作步骤
1、创建工程ModbusTCPSlave 工程;
2、配置从站工程声明变量;
PROGRAM ModbusTCPSlave
VAR
TCPslave : MetaCore_ModbusSlave.FB_ModbusTCPSlave;//Modbus TCP从站功能块
Coil : ARRAY[0..9] OF BOOL:=[1,0,1,0,1,0,1,0,1,0];//初始化线圈数据
DiscreteInput : ARRAY[0..9] OF BOOL:=[0,1,0,1,0,1,0,1,0,1];//初始化离散输入数据
InputRegister : ARRAY[0..9] OF WORD:=[11,22,33,44,55,66,77,88,99,16#AA];
//初始化输入型寄存器数据
HoldingRegister : ARRAY[0..9] OF WORD:=[16#AA,99,88,77,66,55,44,33,22,11];
//初始化保持型寄存器数据
END_VAR
TCPslave(
bEnable:=TRUE , //Modbus TCP从站功能块使能
ePort:= , //Modbus RTU参数,Modbus TCP不填
sIpAddr:='192.168.105.11' , //Modbus TCP从站IP地址
uiIpPort:=503 , //Modbus TCP从站端口,本例使用503端口
udiTimeOut:= , //超时时间
pbyCoil:=ADR(Coil) , //线圈指针
pbyDiscreteInput:=ADR(DiscreteInput) , //离散输入指针
pbyInputRegister:=ADR(InputRegister) , //输入型寄存器指针
pbyHoldingRegister:=ADR(HoldingRegister) , //保持型寄存器指针
udiRwBitSize:=SIZEOF(Coil) , //线圈的个数
udiInBitSize:=SIZEOF(DiscreteInput) , //离散输入的个数
udiInWordSize:=SIZEOF(InputRegister) , //输入型寄存器的个数
udiRwWordSize:=SIZEOF(HoldingRegister) , //保持型寄存器的个数
psMbTest:= , //测试用,不可填
bBusy=> , bActive=> , bConnect=> , bError=> , eError=> , ulRecvCounter=> , ulSendCounter=> , sLocalIp=> , sClientIP=> );
3、创建工程ModbusTCPMaster 工程;
4、按照如下操作完成写功能操作;
a. 写多线圈的实验步骤如下:
bWrite : BOOL ;
WriteCoils : FB_MBTcpWriteCoils;
WriteCoilsData : ARRAY[0..9] OF BOOL:=[1,1,1,1,1];
WriteCoils(sIPAddr:=ipaddr ,
nTCPPort:=503 ,
nUnitID:=1 ,
nQuantity:=10 ,
nMBAddr:=0 ,
cbLength:=SIZEOF(WriteCoilsData) ,
pSrcAddr:=ADR(WriteCoilsData) ,
bExecute:=bWrite ,
tTimeout:= , bBUSY=> , bError=> , nErrId=> );
工程运行后触发WriteCoils中的bExecute上升沿执行写多线圈的值,即写入bWrite为True;
主站数据
从站显示结果:
b. 写多保持寄存器的实验步骤如下:
bWrite : BOOL ;
WriteRegs : FB_MBTcpWriteRegs;
WriteRegsData : ARRAY[0..9] OF WORD:=[16#FF,16#FE,16#FD,16#FC,16#FB,16#FA,16#F9,16#F8,16#F7,16#F6];
WriteRegs(sIPAddr:=ipaddr ,
nTCPPort:=503 ,
nUnitID:=1 ,
nQuantity:=10 ,
nMBAddr:=0 ,
cbLength:=SIZEOF(WriteRegsData) , pSrcAddr:=ADR(WriteRegsData) ,
bExecute:=bWrite ,
tTimeout:= , bBUSY=> , bError=> , nErrId=> );
工程运行后触发WriteRegs中的bExecute上升沿执行写多保持寄存器的值,即写入bWrite为True;
主站数据
从站显示结果:
1、实验中用到的从站的IP、端口请改成实际使用的从站ip、端口;
2、实验中使用的从站配置案例如下:
配置PC 为从站:
安装工具ModbusSlave
配置模式:SlaveID、功能码(01,02,03,04)开始地址、队列
设置寄存器的值/状态
功能块FB_MBTcpReadCoils介绍
参数介绍
参数名称 | 参数类型 | 描述 |
---|---|---|
sIPAddr | string | 从站的IP |
nTCPPort | UINT | 从站的端口 |
nUnitID | BYTE | 从站ID |
nQuantity | WORD | 从线圈起始位置读取的长度,一次最多读取125位 |
nMBAddr | WORD | 线圈起始位置 |
cbLength | UDINT | 存储读取的字节大小 |
pDestAddr | POINTER TO BYTE | 要读的存放数据的存放地址 |
bExecute | BOOL | 上升沿触发执行 |
tTimeout | Time | 超时 |
参数名称 | 参数类型 | 描述 |
---|---|---|
bBUSY | BOOL | 功能块激活时设置,直到确认接收 |
bError | BOOL | 如果命令在传输过程中出现错误,则设置true直到bBusy输出被重置 |
nErrId | UDINT | 当bError输出被设置,提供错误号 |
功能块FB_MBTcpReadInputRegs介绍
参数介绍
参数名称 | 参数类型 | 描述 |
---|---|---|
sIPAddr | string | 从站ip |
nTCPPort | UINT | 从站端口 |
nUnitID | UINT | 从站id |
nQuantity | UINT | 读取多少位输入寄存器,一次最多读取125位 |
nMBAddr | UINT | 读取的输入寄存器起始位置 |
cbLength | UINT | 存储读取的字节大小 |
pDestAddr | POINTER TO WORD | 要读的存放数据的存放地址 |
bExecute | BOOL | 上升沿触发执行 |
tTimeout | TIME | 超时 |
参数名称 | 参数类型 | 描述 |
---|---|---|
bBUSY | BOOL | 功能块激活时设置,直到确认接收 |
bError | BOOL | 如果命令在传输过程中出现错误,则设置true直到bBusy输出被重置 |
nErrId | UDINT | 当bError输出被设置,提供错误号 |
功能块FB_MBTcpReadInputs介绍
参数介绍
参数名称 | 参数类型 | 描述 |
---|---|---|
sIPAddr | string | 从站ip |
nTCPPort | UINT | 从站端口 |
nUnitID | UINT | 从站id |
nQuantity | UINT | 读取多少位离散输入 |
nMBAddr | UINT | 读取的离散输入起始位置 |
cbLength | UINT | 存储读取的字节大小 |
pDestAddr | POINTER TO BYTE | 要读的存放数据的存放地址 |
bExecute | BOOL | 上升沿触发执行 |
tTimeout | TIME | 超时 |
参数名称 | 参数类型 | 描述 |
---|---|---|
bBUSY | BOOL | 功能块激活时设置,直到确认接收 |
bError | BOOL | 如果命令在传输过程中出现错误,则设置true直到bBusy输出被重置 |
nErrId | UDINT | 当bError输出被设置,提供错误号 |
功能块FB_MBTcpReadRegs介绍
参数介绍
参数名称 | 参数类型 | 描述 |
---|---|---|
sIPAddr | string | 从站ip |
nTCPPort | UINT | 从站端口 |
nUnitID | UINT | 从站id |
nQuantity | UINT | 读取多少位保持寄存器,一次最多读取125位 |
nMBAddr | UINT | 读取的保持寄存器起始位置 |
cbLength | UINT | 存储读取的字节大小 |
pDestAddr | POINTER TO word | 要读的存放数据的存放地址 |
bExecute | BOOL | 上升沿触发执行 |
tTimeout | TIME | 超时 |
参数名称 | 参数类型 | 描述 |
---|---|---|
bBUSY | BOOL | 功能块激活时设置,直到确认接收 |
bError | BOOL | 如果命令在传输过程中出现错误,则设置true直到bBusy输出被重置 |
nErrId | UDINT | 当bError输出被设置,提供错误号 |
功能块FB_MBTcpWriteCoils介绍
参数介绍
参数名称 | 参数类型 | 描述 |
---|---|---|
sIPAddr | string | 从站ip |
nTCPPort | UINT | 从站端口 |
nUnitID | UINT | 从站id |
nQuantity | UINT | 写多少位线圈 |
nMBAddr | UINT | 要写入的线圈起始位置 |
cbLength | UINT | 存储写入的字节大小 |
pSrcAddr | POINTER TO BYTE | 要写入的数据的存放地址 |
bExecute | BOOL | 上升沿触发执行 |
tTimeout | TIME | 超时 |
参数名称 | 参数类型 | 描述 |
---|---|---|
bBUSY | BOOL | 功能块激活时设置,直到确认接收 |
bError | BOOL | 如果命令在传输过程中出现错误,则设置true直到bBusy输出被重置 |
nErrId | UDINT | 当bError输出被设置,提供错误号 |
功能块FB_MBTcpWriteRegs介绍
参数介绍
参数名称 | 参数类型 | 描述 |
---|---|---|
sIPAddr | string | 从站ip |
nTCPPort | UINT | 从站端口 |
nUnitID | UINT | 从站id |
nQuantity | UINT | 写多少位线圈,一次最多写123位 |
nMBAddr | UINT | 要写入的保持寄存器起始位置 |
cbLength | UINT | 存储写入的字节大小 |
pSrcAddr | POINTER TO WORD | 要写入的数据的存放地址 |
bExecute | BOOL | 上升沿触发执行 |
tTimeout | TIME | 超时 |
参数名称 | 参数类型 | 描述 |
---|---|---|
bBUSY | BOOL | 功能块激活时设置,直到确认接收 |
bError | BOOL | 如果命令在传输过程中出现错误,则设置true直到bBusy输出被重置 |
nErrId | UDINT | 当bError输出被设置,提供错误号 |
功能块FB_MBTcpWriteSingleCoil介绍
参数介绍
参数名称 | 参数类型 | 描述 |
---|---|---|
sIPAddr | string | 从站ip |
nTCPPort | UINT | 从站端口 |
nUnitID | UINT | 从站id |
nMBAddr | UINT | 要写入的单线圈的位置 |
nValue | BOOL | 要写入的值 |
bExecute | BOOL | 上升沿触发执行 |
tTimeout | TIME | 超时 |
参数名称 | 参数类型 | 描述 |
---|---|---|
bBUSY | BOOL | 功能块激活时设置,直到确认接收 |
bError | BOOL | 如果命令在传输过程中出现错误,则设置true直到bBusy输出被重置 |
nErrId | UDINT | 当bError输出被设置,提供错误号 |
功能块FB_MBTcpWriteSingleReg介绍
参数名称 | 参数类型 | 描述 |
---|---|---|
sIPAddr | string | 从站ip |
nTCPPort | UINT | 从站端口 |
nUnitID | UINT | 从站id |
nMBAddr | UINT | 要写入的单保持寄存器的位置 |
nValue | UINT | 要写入的值 |
bExecute | BOOL | 上升沿触发执行 |
tTimeout | TIME | 超时 |
参数名称 | 参数类型 | 描述 |
---|---|---|
bBUSY | BOOL | 功能块激活时设置,直到确认接收 |
bError | BOOL | 如果命令在传输过程中出现错误,则设置true直到bBusy输出被重置 |
nErrId | UDINT | 当bError输出被设置,提供错误号 |
使用模拟软件配置10个从站(各个从站ID配置不一样),参考如下:
主站配置连接10个从站进行读写操作,测试读写正常
安装要求
中科时代出厂的工智机;
熟悉基础的Linux操作命令
安装过程
工智机端安装Modbus Tcp Master RTE组件
上传deb包到工智机Linux环境的/home/sinsegye目录下
上传完成后在工智机上执行命令安装(参考下方截图,如果模块文件名发生变化则命令行中的文件名做相应更改)
cd $HOME sudo dpkg -i modbusmaster_1.1.4_amd64.deb
\[ComponentManager] Component.0=retainDeamon Component.1=CmpCanBusUtils Component.2=CmpSinsegyeLibs Component.3=SinsegyeCmp Component.4=modbusmaster
sudo systemctl restart sinsegyerte.service
更新安装
工智机端升级Modbus Tcp Master RTE组件
上传deb包到工智机Linux环境的/home/sinsegye目录下
上传完成后在工智机上执行命令安装(参考下方截图,如果模块文件名发生变化则命令行中的文件名做相应更改)
cd $HOME sudo dpkg -i modbusmaster_1.1.4_amd64.deb
sudo systemctl restart sinsegyerte.service
卸载过程
工智机端卸载Modbus Tcp Master RTE组件
sudo dpkg -r simodbusmaster
sudo vim /usr/local/etc/SinsegyeRTE/SinsegyeRTE.cfg
sudo systemctl restart sinsegyerte.service
错误处理
需要先确定网络通讯正常,确定主站要请求的从站地址都存在;
确保主/从站的deb包与Library文件包一致;