回波通讯的计算机处理
回波通讯的计算机处理
在计算机采用串口和232BD连接与FX 系列PLC通讯的时候不存在回波通讯的问题,通讯情况都比较正常,但是这种通讯方式只可以一台计算机连接一台PLC,而当我们要用一台计算机控制16台及以下FX系列PLC的时候就就有可能出现回波通讯, 即使用FX-485-PC-IF、FX-485BD采用一对线模式构成FX系列PLC与计算机通讯时会产生回波通讯,此时PLC返回给计算机的数据会比原来没有发生回波通讯的正常数据要多,PLC会返回计算机发给PLC的数据和PLC本该返回给计算机的数据,给通讯带来麻烦;那么怎么解决回波通讯的问题呢,下面我就回波通讯问题结合我的实践以例子形式给出计算机的解决办法。
<!--[if !supportLists]-->一、<!--[endif]-->PLC和计算机的连接
PLC采用485通讯模块连接构成类似N:N网络的一对线的接线模式,计算机采用232口和FX-485-PC-IF连接,FX-485-PC-IF另外一端和PLC构成的网络相连接,接线方式不变,接线如下面两个图所示:
<!--[if !supportLists]-->二、<!--[endif]-->PLC设置
PLC通讯参数可以通过GXDeveloper的PLC参数设置的PLC系统(2)进行设置,也可以通过PLC程序修改D8120和D8121进行设置,下面给出设置站号为1的PLC参数参考:
设置参数完成后要传入PLC,并掉电后再次上电,设置才有效;其他站号的PLC设置基本上相同,改变站号设置那里就可以。
三、计算机VB程序
(一)、通讯格式
在正常情况下(没有回波通讯时)计算机向PLC发出请求数据后,PLC返回计算机的数据不包含计算机向PLC发出的请求数据,通讯格式如下:
当发生回波通讯时,PLC返回数据会加上计算机发送给PLC的请求数据,通讯格式如下:
计算机发送数据1:
PLC返回数据:
这里返回的数据包含了计算机发送PLC的请求数据和应该返回给计算机的数据。
计算机发送数据2:
其他指令(BW、BT、WR、WW、RR、RS)格式和正常通讯情况差不多,都是PLC返回数据多加了计数器的请求数据,格式不再给出。
(二)、VB程序
在这里给出用计算机控制1#PLC 控制电动机正反转和2#PLC控制电动机星三角降压启动和PLC强制运用、停止的VB程序,并做注释讲解回波通讯的处理差别。
1、窗体及控件
串口波特率,校验方式,数据位,停止位如图所示;定时器时间设定为3秒(2#PLC电动机启动时间),Interval设置为3000。
2、代码
PrivateFunction SumCHk(Dats$) As String 'ASCII求和子程序
Dim i&
Dim CHK&
For i = 1 ToLen(Dats)
CHK = CHK + Asc(Mid(Dats, i, 1))
Next i
SumCHk =Right(Hex$(CHK), 2)
End Function
Private SubCommand1_Click() ’强制运行1#PLC
Dim rd AsString
IfMSComm1.PortOpen = False Then
MSComm1.PortOpen= True '打开串行端口
End If
MSComm1.InputLen= 0 '串行数据接收缓冲区初始化
rd ="01FFRRA"
MSComm1.Output= Chr(5) + rd + SumCHk(rd) '准备向PLC发送的读取数据命令字符串
AA: If MSComm1.InBufferCount< 15 Then GoTo AA '等待收数据
'如果没有回波通讯MSComm1.InBufferCount < 5 ,此时没有发回计算机命令数据,数据相对较少,要收多少字符的自己算出。
rdh =MSComm1.Input '读取接收缓冲区数据
pd = Mid(rdh,11, 5) '取字符串中的部分字符,发生回波通讯,取字符是要去掉重复发送的计算机命令及数据,如果没有回波通讯测pd = Mid(rdh, 1, 5)
If pd =Chr(6) + "01FF" Then '判断读取是否正确
Text1.Text ="NO.1 PLC 强制RUN 成功"
Else
Text1.Text ="NO.1 PLC 强制RUN 失败"
End If
MSComm1.PortOpen= False
End Sub
Private SubCommand2_Click() ’强停止1#PLC
Dim rd AsString
IfMSComm1.PortOpen = False Then
MSComm1.PortOpen= True '打开串行端口
End If
MSComm1.InputLen= 0 '串行数据接收缓冲区初始化
rd ="01FFRSA"
MSComm1.Output= Chr(5) + rd + SumCHk(rd) '准备向PLC发送的读取数据命令字符串
AA: IfMSComm1.InBufferCount < 15 Then GoTo AA '等待收数据
rdh =MSComm1.Input '读取接收缓冲区数据
pd = Mid(rdh,11, 5) '取字符串中的部分字符
'Print "收到的数据是:"; rdh
'Print "头是"; pd '取PLC应答字符串的前5位
If pd =Chr(6) + "01FF" Then '判断读取是否正确
Text1.Text ="NO.1 PLC 强制STOP 成功"
Else
Text1.Text ="NO.1 PLC 强制STOP 失败"
End If
MSComm1.PortOpen= False
End Sub
Private SubCommand3_Click() ’1#PLC 正向启动电动机
Dim rd AsString
IfMSComm1.PortOpen = False Then
MSComm1.PortOpen= True '打开串行端口
End If
MSComm1.InputLen= 0 '串行数据接收缓冲区初始化
rd ="01FFBWAY00010210"
MSComm1.Output= Chr(5) + rd + SumCHk(rd) '准备向PLC发送的读取数据命令字符串
AA: IfMSComm1.InBufferCount < 24 Then GoTo AA '等待收数据
rdh =MSComm1.Input '读取接收缓冲区数据
pd = Mid(rdh,20, 5) '取字符串中的部分字符
'Print "收到的数据是:"; rdh
'Print "头是"; pd '取PLC应答字符串的前5位
If pd =Chr(6) + "01FF" Then '判断读取是否正确
Text1.Text ="NO.1PLC 正向启动成功"
js = Chr(6) +"01FF"
Else
Text1.Text ="NO.1PLC 正向启动N 失败"
js = Chr(15)+ "01FF"
End If
MSComm1.Output= js
MSComm1.PortOpen= False
End Sub
Private SubCommand4_Click() ’1#PLC 反向启动电动机
Dim rd AsString
IfMSComm1.PortOpen = False Then
MSComm1.PortOpen= True '打开串行端口
End If
MSComm1.InputLen= 0 '串行数据接收缓冲区初始化
rd ="01FFBWAY00010201"
MSComm1.Output= Chr(5) + rd + SumCHk(rd) '准备向PLC发送的读取数据命令字符串
AA: IfMSComm1.InBufferCount < 24 Then GoTo AA '等待收数据
rdh =MSComm1.Input '读取接收缓冲区数据
pd = Mid(rdh,20, 5) '取字符串中的部分字符
'Print "收到的数据是:"; rdh
'Print "头是"; pd '取PLC应答字符串的前5位
If pd =Chr(6) + "01FF" Then '判断读取是否正确
Text1.Text ="NO.1PLC 反向启动成功"
js = Chr(6) +"01FF"
Else
Text1.Text ="NO.1PLC 反向启动失败"
js = Chr(15)+ "01FF"
End If
MSComm1.Output= js
MSComm1.PortOpen= False
End Sub
Private SubCommand5_Click() ’1#PLC 停止动电动机
Dim rd AsString
IfMSComm1.PortOpen = False Then
MSComm1.PortOpen= True '打开串行端口
End If
MSComm1.InputLen= 0 '串行数据接收缓冲区初始化
rd ="01FFBWAY00010200"
MSComm1.Output= Chr(5) + rd + SumCHk(rd) '准备向PLC发送的读取数据命令字符串
AA: IfMSComm1.InBufferCount < 24 Then GoTo AA '等待收数据
rdh =MSComm1.Input '读取接收缓冲区数据
pd = Mid(rdh,20, 5) '取字符串中的部分字符
'Print "收到的数据是:"; rdh
'Print "头是"; pd '取PLC应答字符串的前5位
If pd =Chr(6) + "01FF" Then '判断读取是否正确
Text1.Text ="NO.1PLC 停止成功"
js = Chr(6) +"01FF"
Else
Text1.Text ="NO.1PLC 停止失败"
js = Chr(15)+ "01FF"
End If
MSComm1.Output= js
MSComm1.PortOpen= False
End Sub
Private SubCommand6_Click() ’2#PLC 强制运行
Dim rd AsString
IfMSComm1.PortOpen = False Then
MSComm1.PortOpen= True '打开串行端口
End If
MSComm1.InputLen= 0 '串行数据接收缓冲区初始化
rd ="02FFRRA"
MSComm1.Output= Chr(5) + rd + SumCHk(rd) '准备向PLC发送的读取数据命令字符串
AA: IfMSComm1.InBufferCount < 15 Then GoTo AA '等待收数据
rdh =MSComm1.Input '读取接收缓冲区数据
pd = Mid(rdh,11, 5) '取字符串中的部分字符
'Print "收到的数据是:"; rdh
'Print "头是"; pd '取PLC应答字符串的前5位
If pd =Chr(6) + "02FF" Then '判断读取是否正确
Text1.Text ="NO.2 PLC 强制RUN 成功"
Else
Text1.Text ="NO.2 PLC 强制RUN 失败"
End If
MSComm1.PortOpen= False
End Sub
Private SubCommand7_Click() ’2#PLC 强制停止
Dim rd As String
IfMSComm1.PortOpen = False Then
MSComm1.PortOpen= True '打开串行端口
End If
MSComm1.InputLen= 0 '串行数据接收缓冲区初始化
rd ="02FFRSA"
MSComm1.Output= Chr(5) + rd + SumCHk(rd) '准备向PLC发送的读取数据命令字符串
AA: IfMSComm1.InBufferCount < 15 Then GoTo AA '等待收数据
rdh = MSComm1.Input'读取接收缓冲区数据
pd = Mid(rdh,11, 5) '取字符串中的部分字符
'Print "收到的数据是:"; rdh
'Print "头是"; pd '取PLC应答字符串的前5位
If pd =Chr(6) + "02FF" Then '判断读取是否正确
Text1.Text ="NO.2 PLC 强制STOP 成功"
Else
Text1.Text ="NO.2 PLC 强制STOP 失败"
End If
MSComm1.PortOpen= False
End Sub
Private SubCommand8_Click() ’2#PLC 电动机星形启动
Dim rd AsString
IfMSComm1.PortOpen = False Then
MSComm1.PortOpen= True '打开串行端口
End If
MSComm1.InputLen= 0 '串行数据接收缓冲区初始化
rd ="02FFBWAY000103110"
MSComm1.Output= Chr(5) + rd + SumCHk(rd) '准备向PLC发送的读取数据命令字符串
AA: IfMSComm1.InBufferCount < 25 Then GoTo AA '等待收数据
rdh =MSComm1.Input '读取接收缓冲区数据
pd = Mid(rdh,21, 5) '取字符串中的部分字符
'Print "收到的数据是:"; rdh
'Print "头是"; pd '取PLC应答字符串的前5位
If pd =Chr(6) + "02FF" Then '判断读取是否正确
Text1.Text ="NO.2PLC 星形启动成功"
js = Chr(6) +"02FF"
Timer1.Enabled= True
Else
Text1.Text ="NO.2PLC 星形启动失败"
js = Chr(15)+ "02FF"
End If
MSComm1.Output= js
MSComm1.PortOpen= False
End Sub
Private SubCommand9_Click() ’2#PLC 电动机停止
Dim rd AsString
IfMSComm1.PortOpen = False Then
MSComm1.PortOpen= True '打开串行端口
End If
MSComm1.InputLen= 0 '串行数据接收缓冲区初始化
rd ="02FFBWAY000103000"
MSComm1.Output= Chr(5) + rd + SumCHk(rd) '准备向PLC发送的读取数据命令字符串
AA: IfMSComm1.InBufferCount < 25 Then GoTo AA '等待收数据
rdh =MSComm1.Input '读取接收缓冲区数据
pd = Mid(rdh,21, 5) '取字符串中的部分字符
'Print "收到的数据是:"; rdh
'Print "头是"; pd '取PLC应答字符串的前5位
If pd =Chr(6) + "02FF" Then '判断读取是否正确
Text1.Text ="NO.2PLC 停止成功"
js = Chr(6) +"02FF"
Else
Text1.Text ="NO.2PLC 停止失败"
js = Chr(15)+ "02FF"
End If
MSComm1.Output= js
MSComm1.PortOpen= False
End Sub
Private SubTimer1_Timer() ’2#PLC 星形启动时间到转到三角形运行
Dim rd AsString
IfMSComm1.PortOpen = False Then
MSComm1.PortOpen= True '打开串行端口
End If
MSComm1.InputLen= 0 '串行数据接收缓冲区初始化
rd ="02FFBWAY000103101"
MSComm1.Output= Chr(5) + rd + SumCHk(rd) '准备向PLC发送的读取数据命令字符串
AA: IfMSComm1.InBufferCount < 25 Then GoTo AA '等待收数据
rdh =MSComm1.Input '读取接收缓冲区数据
pd = Mid(rdh,21, 5) '取字符串中的部分字符
'Print "收到的数据是:"; rdh
'Print "头是"; pd '取PLC应答字符串的前5位
If pd =Chr(6) + "02FF" Then '判断读取是否正确
Text1.Text ="NO.2PLC 三角形运行成功"
js = Chr(6) +"02FF"
Else
Text1.Text ="NO.2PLC 三角运行失败"
js = Chr(15)+ "02FF"
End If
MSComm1.Output= js
MSComm1.PortOpen= False
Timer1.Enabled= False
End Sub
四、结束语
通过上面的回波通讯例子的我们可以知道,当发生回波通讯时原来PLC返回给计算机的数据被加长,加上了计算机发送给PLC的命令及数据,因此我们收取PLC返回数据的时候数据位就要加上计算机发送的命令及数据位,当计算机收完数据后还要把那一部分数据区分出来,使用取字符函数的时候就要注意从哪一位开始取数据,取多少位后再做判断。
以上是我对回波通讯的理解和计算机的处理方法,本文也只是抛砖引玉罢了,还希望以上的例子对对回波通讯处理困惑的你有一定的帮助,当中或许存在谬误之处,还望批评指正。
提交
<a href=http://download.gongkong.com/file/company/1249/tougao/2007712132800.pdf target=_blank>三菱FX系列PLC与计算机无协议通讯 /a>