1、modbus数据帧格式
在tcp/ip以太网上传输,支持ethernet ii和802.3两种帧格式。图3所示,modbus tcp数据帧包含报文头、功能代码和数据3部分。
2、 modbus功能代码
3.1 3种类型
(1)公共功能代码(如表2所示):已定义好的功能码,保证其唯一性,由modbus.org认可。
(2)用户自定义功能代码有两组,分别为65~72和100~110,无需认可,但不保证代码使用的唯一性。如变为公共代码,需交rfc认可。
(3)保留的功能代码,由某些公司使用在某些传统设备的代码,不可作为公共用途。
[m]
3.2功能代码划分:按应用深浅,可分为3个类别。
(1)类别0,对于客户机/服务器最小的可用子集:读多个保持寄存器(fc.3);写多个保持寄存器(fc.16)。
(2)类别1,可实现基本互易操作的常用代码:读线圈(fc.1);读开关量输入(fc.2);读输入寄存器(fc.4);写线圈(fc.5);写单一寄存器(fc.6)。
(3)类别2,用于人机界面、监控系统的例行操作和数据传送功能:
(4)强制多个线圈(fc.15);读通用寄存器(fc.20);写通用寄存器(fc.21);屏蔽写寄存器(fc.22);读写寄存器(fc.23)。
4、vb的基本概念
vb(visual basic)是面向对象的程序设计语言,用它来开发windows操作系统下的应用程序,它提供了很多接口成员,对象、属性、事件、方法就是4个重要的接口,vb提供了许多常用的控件。
4.1卷标控件
卷标控件如图4(a)所示,该控件专用于显示文字、数字用,显示如图4(b)所示。
4.2 按钮控件
按钮控件如图5(a)所示,该控件使用率很高,提供一个供系统用户操作用的按钮,如图5(b)所示。
5、基于winsock控件的tcp/ip以太网通信
要完成vb与plc等设备的以太网通信要用到winsock控件,在此有必要对该控件作较详细的说明。winsock是一个activex控件,需要要手动添加许多项目,其步骤如下:
(1)选择菜单的【工程】。
(2)选择【部件】。
(3)在弹出的对话框中做如图6的选择。
图6 对话框界面
(4)如图7所示,在部件选项卡就会出现winsock控件。
6、winsock控件的基本属性
此控件对于用户在运行时不可见,提供了一个简单的途径访问tcp及udp网络服务而无需了解底层细节,使用时你只需设置属性、在恰当的时候调用它提供的方法即可。
主要属性有:
bytesreceived:返回当前缓冲区中的字节数量,我们可以使用 getdata 方法以接收数据。只读且设计时不可用。
localhostname:返回本机名字符串,设计时不可用。
localip:返回以(xxx.xxx.xxx.xxx)格式表达的ip地址串。设计时不可用,运行时只读。
localport :本机使用接收端口可读写,设计时可用,long型。对于客户,如果无需指定端口,则用端口0发送数据。在此情况下,控件将随机选择一个端口。在一个连接确定后,为tcp的端口。对于服务器,指用于监听的端口。如设置为0,则用随机数。在调用listen 方法后,该属性自动包含用到的端口。端口0总是用于在两计算机间建立动态连接。客户希望通过端口0获得一个随机端口以”回调”连接服务器。
protocol :套接字类型,为tcp或udp二者之一,缺省为tcp类型。设置为scktcpprotocol表示tcp协议sckudpprotocol表示udp协议。在此属性被重置之前需用close方法关闭之。
remotehost:发送或接收数据的主机,你可提供主机名如:
ftp://ftp.microsoft.com
,或一ip地址串,例如“100.0.1.1”。
remotehostip:远程主机的ip地址。对于客户程序,在连接确定后使用connect方法,此属性包含远程主机的ip名串。对于服务器程序, 在引入连接需求后(connection request 事件),此属性包含ip串。当使用udp套接字,在data arrival事件发生后,此属性为发送udp数据的机器ip地址串。
remoteport:连接套接字端口值。例如通常http应用使用80端口,ftp则使用21。
state:控件的状态, 只读且设计时不可用。可为以下值:
常量描述
sckclosed 0 缺省值,关闭套接字
sckopen 1 打开套接字
scklistening 2 正监听端口
sckconnectionpending 3 正在进行未定的连接
sckresolvinghost 4 正解析主机地址
sckhostresolved 5 主机地址已解析
sckconnecting 6 正在连接
sckconnected 7 已连接
sckclosing 8 连接关闭
sckerror 9 错误
7、vb与plc基于modbus tcp的以太网通信的实现
以下举例说明如何实现vb与plc的以太网通信。
(1)控制要求:用交替型按钮控制y0,并用指示灯显示y0状态(绿色为运行,红色为停止);能够对
d100
、d200两个寄存器进行数值写入与读出的操作。
(2)实现思路:同样y0的地址分别为h0500。写入ff00为on,0000为off,按功能码05操作;
d100
,d200地址分别为h1064,h10c8,按功能码03操作即可实现寄存器的读功能,按功能码10h操作即可实现寄存器的写功能。
(3)vb接口的设计如图8所示
在界面中用按钮控制y0的on/off及d100、d200数据的写与读;用shape组件做指示灯,指示y0的on/off状态;用winsock控件实现plc与vb的通信。
(1)实现功能的代码构成
(2)建立网络连接
private sub command1_click()
winsock1.close
winsock1.connect text1, 502
label2.caption = version: 1.0 : + format(now, mmm dd yyyy hh:nn:ss)
command1.enabled = false
command1.enabled = false
text1.enabled = false
end sub
(2)、y0的on/off控制
private sub comd_send_click()
on error goto errproc
dim sendstr(14) as byte
sendstr(0) = &h0 交换识别号高字节,通常为0
sendstr(1) = &h0 交换识别号低字节,通常为0
sendstr(2) = &h0 协议识别号高字节,为 0
sendstr(3) = &h0 协议识别号低字节,为 0
sendstr(4) = &h0 字节长度高字节
sendstr(5) = &h9 以下字节长度低字节
sendstr(6) = &hff 单元识别号,确省为 255
sendstr(7) = &h5 写一个线圈命令代码
sendstr(8) = &h0 写线圈的起始地址高字节
sendstr(9) = &h1写线圈的起始地址低字节
sendstr(10) = a =ff打开线圈,=00关闭线圈
sendstr(11) = &h0
dim astr as string
dim i, j as integer
for i = 0 to 11
astr = astr & chr(sendstr(i))
next
winsock1.senddata astr
exit sub
errproc:
msgbox 传输数据失败, vbcritical, 网络传输
end sub
(3)线圈状态显示及寄存器读出数据显示
private sub winsock1_dataarrival(byval bytestotal as long)
dim strdata() as byte
dim i, j as integer
dim s as string
dim s1 as string
dim io as byte
i = winsock1.bytesreceived
redim strdata(i)
winsock1.getdata strdata, vbbyte, i
for j = 0 to i - 1
s = s + hex(strdata(j))
next
if s like *5* then
s1 = mid(s, 12, 2)
if s1 = ff then
io = 1
a = &h0
else
io = 0
a = &hff
end if
if io = 1 then
shape1.fillcolor = rgb(0, 255, 0) green
labl3.caption = io点接通
else
shape1.fillcolor = rgb(255, 0, 0) red
labl3.caption = io点断开
end if
end if if s like *3* then
text3.text = text3.text + mid(s, 11) +
end if
(4)、读多个寄存器数据
end sub private sub command4_click()
on error goto errproc
dim str(12) as byte
str(0) = &h0 交换识别号高字节,通常为 0
str(1) = &h0 交换识别号低字节,通常为 0
str(2) = &h0 协议识别号高字节,为 0
str(3) = &h0 协议识别号低字节,为 0
str(4) = &h0 字节长度高字节
str(5) = &h6 以下字节长度低字节
str(6) = &hff 单元识别号,确省为 255
str(7) = &h3 读多个寄存器命令代码
str(8) = &h10 读数据的起始地址高字节
str(9) = &hc8 读数据的起始地址低字节
str(10) = &h0 数据长度高字节
str(11) = &h1 数据长度低字节
dim bstr as string
dim i as integer
for i = 0 to 11
bstr = bstr & chr(str(i))
next
winsock1.senddata bstr
exit sub
errproc:
msgbox 传输数据失败, vbcritical, 网络传输
end sub
1楼
0
0
回复
在tcp/ip以太网上传输,支持ethernet ii和802.3两种帧格式。图3所示,modbus tcp数据帧包含报文头、功能代码和数据3部分。
2、 modbus功能代码
3.1 3种类型
(1)公共功能代码(如表2所示):已定义好的功能码,保证其唯一性,由modbus.org认可。
(2)用户自定义功能代码有两组,分别为65~72和100~110,无需认可,但不保证代码使用的唯一性。如变为公共代码,需交rfc认可。
(3)保留的功能代码,由某些公司使用在某些传统设备的代码,不可作为公共用途。
[m]
3.2功能代码划分:按应用深浅,可分为3个类别。
(1)类别0,对于客户机/服务器最小的可用子集:读多个保持寄存器(fc.3);写多个保持寄存器(fc.16)。
(2)类别1,可实现基本互易操作的常用代码:读线圈(fc.1);读开关量输入(fc.2);读输入寄存器(fc.4);写线圈(fc.5);写单一寄存器(fc.6)。
(3)类别2,用于人机界面、监控系统的例行操作和数据传送功能:
(4)强制多个线圈(fc.15);读通用寄存器(fc.20);写通用寄存器(fc.21);屏蔽写寄存器(fc.22);读写寄存器(fc.23)。
4、vb的基本概念
vb(visual basic)是面向对象的程序设计语言,用它来开发windows操作系统下的应用程序,它提供了很多接口成员,对象、属性、事件、方法就是4个重要的接口,vb提供了许多常用的控件。
4.1卷标控件
卷标控件如图4(a)所示,该控件专用于显示文字、数字用,显示如图4(b)所示。
4.2 按钮控件
按钮控件如图5(a)所示,该控件使用率很高,提供一个供系统用户操作用的按钮,如图5(b)所示。
5、基于winsock控件的tcp/ip以太网通信
要完成vb与plc等设备的以太网通信要用到winsock控件,在此有必要对该控件作较详细的说明。winsock是一个activex控件,需要要手动添加许多项目,其步骤如下:
(1)选择菜单的【工程】。
(2)选择【部件】。
(3)在弹出的对话框中做如图6的选择。
图6 对话框界面
(4)如图7所示,在部件选项卡就会出现winsock控件。
6、winsock控件的基本属性
此控件对于用户在运行时不可见,提供了一个简单的途径访问tcp及udp网络服务而无需了解底层细节,使用时你只需设置属性、在恰当的时候调用它提供的方法即可。
主要属性有:
bytesreceived:返回当前缓冲区中的字节数量,我们可以使用 getdata 方法以接收数据。只读且设计时不可用。
localhostname:返回本机名字符串,设计时不可用。
localip:返回以(xxx.xxx.xxx.xxx)格式表达的ip地址串。设计时不可用,运行时只读。
localport :本机使用接收端口可读写,设计时可用,long型。对于客户,如果无需指定端口,则用端口0发送数据。在此情况下,控件将随机选择一个端口。在一个连接确定后,为tcp的端口。对于服务器,指用于监听的端口。如设置为0,则用随机数。在调用listen 方法后,该属性自动包含用到的端口。端口0总是用于在两计算机间建立动态连接。客户希望通过端口0获得一个随机端口以”回调”连接服务器。
protocol :套接字类型,为tcp或udp二者之一,缺省为tcp类型。设置为scktcpprotocol表示tcp协议sckudpprotocol表示udp协议。在此属性被重置之前需用close方法关闭之。
remotehost:发送或接收数据的主机,你可提供主机名如:
ftp://ftp.microsoft.com
,或一ip地址串,例如“100.0.1.1”。
remotehostip:远程主机的ip地址。对于客户程序,在连接确定后使用connect方法,此属性包含远程主机的ip名串。对于服务器程序, 在引入连接需求后(connection request 事件),此属性包含ip串。当使用udp套接字,在data arrival事件发生后,此属性为发送udp数据的机器ip地址串。
remoteport:连接套接字端口值。例如通常http应用使用80端口,ftp则使用21。
state:控件的状态, 只读且设计时不可用。可为以下值:
常量描述
sckclosed 0 缺省值,关闭套接字
sckopen 1 打开套接字
scklistening 2 正监听端口
sckconnectionpending 3 正在进行未定的连接
sckresolvinghost 4 正解析主机地址
sckhostresolved 5 主机地址已解析
sckconnecting 6 正在连接
sckconnected 7 已连接
sckclosing 8 连接关闭
sckerror 9 错误
7、vb与plc基于modbus tcp的以太网通信的实现
以下举例说明如何实现vb与plc的以太网通信。
(1)控制要求:用交替型按钮控制y0,并用指示灯显示y0状态(绿色为运行,红色为停止);能够对
d100
、d200两个寄存器进行数值写入与读出的操作。
(2)实现思路:同样y0的地址分别为h0500。写入ff00为on,0000为off,按功能码05操作;
d100
,d200地址分别为h1064,h10c8,按功能码03操作即可实现寄存器的读功能,按功能码10h操作即可实现寄存器的写功能。
(3)vb接口的设计如图8所示
在界面中用按钮控制y0的on/off及d100、d200数据的写与读;用shape组件做指示灯,指示y0的on/off状态;用winsock控件实现plc与vb的通信。
(1)实现功能的代码构成
(2)建立网络连接
private sub command1_click()
winsock1.close
winsock1.connect text1, 502
label2.caption = version: 1.0 : + format(now, mmm dd yyyy hh:nn:ss)
command1.enabled = false
command1.enabled = false
text1.enabled = false
end sub
(2)、y0的on/off控制
private sub comd_send_click()
on error goto errproc
dim sendstr(14) as byte
sendstr(0) = &h0 交换识别号高字节,通常为0
sendstr(1) = &h0 交换识别号低字节,通常为0
sendstr(2) = &h0 协议识别号高字节,为 0
sendstr(3) = &h0 协议识别号低字节,为 0
sendstr(4) = &h0 字节长度高字节
sendstr(5) = &h9 以下字节长度低字节
sendstr(6) = &hff 单元识别号,确省为 255
sendstr(7) = &h5 写一个线圈命令代码
sendstr(8) = &h0 写线圈的起始地址高字节
sendstr(9) = &h1写线圈的起始地址低字节
sendstr(10) = a =ff打开线圈,=00关闭线圈
sendstr(11) = &h0
dim astr as string
dim i, j as integer
for i = 0 to 11
astr = astr & chr(sendstr(i))
next
winsock1.senddata astr
exit sub
errproc:
msgbox 传输数据失败, vbcritical, 网络传输
end sub
(3)线圈状态显示及寄存器读出数据显示
private sub winsock1_dataarrival(byval bytestotal as long)
dim strdata() as byte
dim i, j as integer
dim s as string
dim s1 as string
dim io as byte
i = winsock1.bytesreceived
redim strdata(i)
winsock1.getdata strdata, vbbyte, i
for j = 0 to i - 1
s = s + hex(strdata(j))
next
if s like *5* then
s1 = mid(s, 12, 2)
if s1 = ff then
io = 1
a = &h0
else
io = 0
a = &hff
end if
if io = 1 then
shape1.fillcolor = rgb(0, 255, 0) green
labl3.caption = io点接通
else
shape1.fillcolor = rgb(255, 0, 0) red
labl3.caption = io点断开
end if
end if if s like *3* then
text3.text = text3.text + mid(s, 11) +
end if
(4)、读多个寄存器数据
end sub private sub command4_click()
on error goto errproc
dim str(12) as byte
str(0) = &h0 交换识别号高字节,通常为 0
str(1) = &h0 交换识别号低字节,通常为 0
str(2) = &h0 协议识别号高字节,为 0
str(3) = &h0 协议识别号低字节,为 0
str(4) = &h0 字节长度高字节
str(5) = &h6 以下字节长度低字节
str(6) = &hff 单元识别号,确省为 255
str(7) = &h3 读多个寄存器命令代码
str(8) = &h10 读数据的起始地址高字节
str(9) = &hc8 读数据的起始地址低字节
str(10) = &h0 数据长度高字节
str(11) = &h1 数据长度低字节
dim bstr as string
dim i as integer
for i = 0 to 11
bstr = bstr & chr(str(i))
next
winsock1.senddata bstr
exit sub
errproc:
msgbox 传输数据失败, vbcritical, 网络传输
end sub