技术论坛

 回复:【MODBUS】跑在以太网上的MODBUS

返回主题列表
作者 主题
万泉河
至圣

经验值:29190
发帖数:10900
精华帖:131
楼主    2015-03-16 22:53:10
主题:【MODBUS】跑在以太网上的MODBUS

 modbus】跑在以太网上的modbus
万泉河

介绍一个比较典型的规模比较大的modbus通讯的项目,2013年做的。

甲方已经运转的一批14套单机设备,都是S7-200PLC控制的,后来为实现能源优化管理,想加上电度表,加上WINCC中央监控,以监控设备在每一生产环节的能耗情况。

最初报的方案是买485接口的电能表,通过S7-200的空闲的一个通讯口接入到PLC(另一个通讯口被KTP触摸屏占用),然后每台PLC再增加一个CP243-1,通过光纤以太网,接入到车间办公室的WINCC。同时还增设了IP摄像头,也同样走此以太网线路。

因为每台设备具体细节还有不一样,到具体设计的时候,竟然才发现,有2个柜子,CPU的I/O模块已经达到7个模块,无法再扩展CP243-1模块了。

所以临时改变设计,改为:每套设备,增加串口服务器,以太网转换为RS485串口,并作为modbus MASTER,下挂2个从站,分别是电能表和S7-200. 上位使用KEP SERVER软件,读取到每一个串口服务器,每一个电能表或者CPU作为一个设备单元。

最后选定的智能电表是上海ForLong DRT-301C-II modbus,串口服务器则为MOXA NPORT 5130。本来也可以直接选用modbus TCP转modbus的网关型号,但我还惦记着希望能从以太网远程修改调试S7-200程序,所以选用了简单的485类型。

这个系统复杂的地方还是在最后的报表统计方面。具体的通讯部分,调试过程还算比较顺利。其实得益于准备工作比较充分,并且以前也多次调试MOBUS通讯,对协议比较熟悉。

总结经验如下:

1,通讯项目,打通通讯第一重要!不管水平有多高,经验多丰富,在遇到新产品的时候都尽量先在家打通通讯,然后再去现场施工调试。如果有问题提前不重视,拖到现场再试,总有困难等着你,让你难堪,丢人。

2,modbus通讯,工具很重要。特别是在打通通讯阶段。电脑上的两个重要的modbus测试工具MODSCAN和MODSIM都一定要是必备的,调试中对任何一个设备没把握,都可以把电脑替换进去,来做模拟实验。最终确定谁有问题。

现在的笔记本大都没串口,可以买USB/485转换器。反正你电脑即便有232口,也要232/485的转换,所以直接转换为485,也很方便。最好是能有两个,电脑上可以同时做主站和从站,就不需要两头倒腾了。没事的时候电脑上自己访问自己,熟悉下两个软件的使用,侦听一下数据包,也很有意思。

3,接线很重要。要尽量避免在现场调试过程中焊通讯头的情况。设备元件,尽量买端子型的。但我这次买到的串口服务器只能是DB-9孔的,所以我在拿到样品 之后第一时间做了通讯实验,确定了接线的管脚,然后从淘宝找到能做模铸线的厂家,给定做的线。对他们来说一般都只做0.3以下细线,0.75的线手里没 有。我们又专门发了几十米DP紫色线给他,让他只是给做上了模铸的通讯头,这样整体线缆一致,好看,接线还容易。

做一根线才几块钱!比在现场用组装的通讯头焊线,省下的精力和不知道有多少。况且我自己还不会动焊。

4,选用的电能表,有一点很讨厌,就是它的通讯参数,缺省是1200bps,但修改到9600却只能需要通过485通讯方式发指令去修改,据说是行业规定。早知道应该要求出厂前都给设置好。

5,通过以太网远程映射COM端口方式直接下载S7-200程序的问题,通讯测试打通了。但除了需要停止CPU运行之外,还需要修改N5130的参数与正常运行时不同,所以现场调试遇到需要修改PLC程序的那几次,我还是端着笔记本跑到现场做了。

这是变更后的方案与原方案差异的地方。但由于CP243-1比串口服务器价格贵很多,modbus方案性价比还是比较高的。






微信公众号:PLC标准化编程,ZHO6371995
疆拓自动化
侠客

经验值:771
发帖数:295
精华帖:3
26楼    2015-04-14 08:53:38
精华帖  主题:回复:【MODBUS】跑在以太网上的MODBUS
我是自己用VB写的采集驱动,然后在WINCC建立内部变量(内部变量不算点),采集驱动采集到数据后,通过HMIruntime库函数写wincc的内部变量(我的大致有1万多个点,其实只需要买最低点数的wincc即可)

那阵子我观察了下,一般这种和上位机的通讯都需要在电脑上建立虚拟串口,但是建立虚拟串口太多,我的需要建208个虚拟串口,力控软件根本就支持不了这么多的串口设备。通过观察,我发现电脑跟串口跟服务器的通讯使用的依然是TCP的报文,我截取了报文看了,只是把串口的查询字符串和返回数据的字符串给封装了。

我自己尝试着用vb 使用winsock控件写了一下,发现是可以的,这样我的程序放到任何一个电脑上就可以直接使用,不需要建立虚拟串口了。用vb写的话,要使用它默认的端口号 961~968。是TCP报文 不是modbus-TCP,我用VB写比较方便,获得报文自己分析就可以了。

其实这么多表通讯,用网关是最直接的,由于种种原因,没办法。
代码大部分跟modbusrtu的代码差不多,附点部分代码吧,真要做完善还是要花时间的,我花了好多天的时间了,现在基本上正常用了。

Dim outputLen As Integer ' 发送数据长度
Dim outData As String ' 发送数据暂存
Dim SendArr() As Byte ' 发送数组
Dim TemporarySave As String ' 数据暂存
Dim dataCount As Integer ' 数据个数计数
Dim i As Integer ' 局部变量


outData = UCase(Replace(TxtSend, Space(1), Space(0))) ' 先去掉空格,再转换为大写字母
outData = UCase(outData) ' 转换成大写
outputLen = Len(outData) ' 数据长度
For i = 0 To outputLen - 1
TemporarySave = Mid(outData, i + 1, 1) ' 取一位数据
If (Asc(TemporarySave) >= 48 And Asc(TemporarySave) <= 57) Or (Asc(TemporarySave) >= 65 And Asc(TemporarySave) <= 70) Then
dataCount = dataCount + 1
Else
Exit For
Exit Sub
End If
Next i

If dataCount Mod 2 <> 0 Then ' 判断十六进制数据是否为双数
dataCount = dataCount - 1 ' 不是双数,则减1
End If

outData = Left(outData, dataCount) ' 取出有效的十六进制数据

ReDim SendArr(dataCount / 2 - 1) ' 重新定义数组长度
For i = 0 To dataCount / 2 - 1
SendArr(i) = Val("&H" + Mid(outData, i * 2 + 1, 2)) ' 取出数据转换成十六进制并放入数组中
Next


Main.WinsockClient(Index).SendData SendArr() ' 发送数据


SlaveNow(Index) = SlaveNow(Index) + 1 '从站依次轮询
If SlaveNow(Index) > SlaveNum(Index) Then
SlaveNow(Index) = 1
End If


==============================================================================

Private Sub WinsockClient_DataArrival(Index As Integer, ByVal bytesTotal As Long)


On Error Resume Next
Dim strData() As Byte


WinsockClient(Index).GetData strData()




'若接收的数据总长度 和 数据长度加上地址吗功能码以及校验码之和 不相等 说明接收到的数据不正确 就可以丢弃了
If (bytesTotal < 10) Then
DataOK(Index) = True
DataSendCounter(Index) = 0
Exit Sub
End If

GoodData(Index) = ""
For i = 0 To bytesTotal - 1
If strData(i) < 16 Then
GoodData(Index) = GoodData(Index) & "0" & Hex(strData(i))
Else
GoodData(Index) = GoodData(Index) & Hex(strData(i))
End If
Next i



'************************************************************************
'************************CRC16校验***************************************
Dim CRC_A As String
Dim CRC_B As String
Dim Txt1 As String
Dim Txt2 As String
Dim H1, H2 As String

Txt1 = UCase(Replace(GoodData(Index), Space(1), Space(0)))
Txt2 = Mid(Txt1, 1, Len(Txt1) - 4)

H1 = Mid(Txt1, Len(Txt1) - 3, 2)
H2 = Mid(Txt1, Len(Txt1) - 1, 2)
Call CRC_16(Txt2, CRC_A, CRC_B)
If (H1 <> CRC_A) Or (H2 <> CRC_B) Then
DataOK(Index) = True
DataSendCounter(Index) = 0

End If
'************************CRC16校验***************************************
'************************************************************************


'现在开始判断仪表类型
'bytesTotal=105 ---SCK600B多功能电表(电流电压电能等)
'bytesTotal=13 or 14 ---安科瑞的电表 或者是电操的状态返回信号
'bytetotal= 21 ----斯菲尔电能表
'bytesTotal >= 40 And <= 56 ------SCK600B多功能电表 或者 SCK600A火灾报警
'bytesTotal >=109 ------PF3000电表处理
Dim CongZhanNumber As Integer
Dim DuanKou As Integer
Dim IP As Integer

Dim ShuJuA As Integer
Dim ShuJuB As Integer
Dim ShuJuC As Integer
Dim ShuJuD As Integer
Dim F(30) As Single
Dim B(4) As Byte



'///////获取表数据的公共部分//////////////////////////////////////////
CongZhanNumber = CLng("&H" & Mid(GoodData(Index), 1, 2))
DuanKou = WinSockPort(Index) - 960
IP = CInt(Right(WinSockHostName(Index), 3))
'///////获取表数据的公共部分//////////////////////////////////////////



'///////SCK600B 多功能电表处理//////////////////////////////////////////
If (bytesTotal = 105) Then

'基本的过程是:先找出从站编号,数据处理需要根据电表的数据格式来组合,然后分别找出12个电表数据,
For i = 1 To 21
ShuJuA = CLng("&H" & Mid(GoodData(Index), i * 7 + (i - 1), 2))
ShuJuB = CLng("&H" & Mid(GoodData(Index), i * 7 + (i - 1) + 2, 2))
ShuJuC = CLng("&H" & Mid(GoodData(Index), i * 7 + (i - 1) + 4, 2))
ShuJuD = CLng("&H" & Mid(GoodData(Index), i * 7 + (i - 1) + 6, 2))
B(0) = ShuJuA
B(1) = ShuJuB
B(2) = ShuJuC
B(3) = ShuJuD
' 根据实际情况 进行选择, 1234 4321 2143 3412
CopyMemory ByVal (VarPtr(F(i)) + 0), B(3), 1
CopyMemory ByVal (VarPtr(F(i)) + 1), B(2), 1
CopyMemory ByVal (VarPtr(F(i)) + 2), B(1), 1
CopyMemory ByVal (VarPtr(F(i)) + 3), B(0), 1
Next i

Ua(Index, DuanKou, CongZhanNumber) = F(1)
Ub(Index, DuanKou, CongZhanNumber) = F(2)
Uc(Index, DuanKou, CongZhanNumber) = F(3)
Ia(Index, DuanKou, CongZhanNumber) = F(7)
Ib(Index, DuanKou, CongZhanNumber) = F(8)
Ic(Index, DuanKou, CongZhanNumber) = F(9)
P(Index, DuanKou, CongZhanNumber) = F(13)
Q(Index, DuanKou, CongZhanNumber) = F(17)
PF(Index, DuanKou, CongZhanNumber) = F(19)
EP(Index, DuanKou, CongZhanNumber) = F(21)


End If
'//////////////////////SCK600B 多功能电表处理//////////////
..........................................



还有就是,我这光安科瑞的电能表就有800多块了,分布在50多层大楼里面,电表的地址都是缺省的,需要一个个的去改地址,但是电表本身没有任何按键,只能通过modscan等软件一个个的改,而且拿着笔记本一个个的楼层跑,麻烦死了,我跑了几层,实在受不了了(要接线,还要笔记本的电池有电),就让人把每个楼层的表的地址按照顺序记下来,自己写了一个软件,在电脑上搜索单条总线的从站,搜到后按照他们记得地址顺序改成自己需要的地址,很方便很快捷,以下是软件界面:(直接点击搜索到的从站,输入你想要的地址就可以直接成功修改)




常年奔波,是为的以后不奔波...............
疆拓自动化
侠客

经验值:771
发帖数:295
精华帖:3
27楼    2015-04-14 09:22:39
精华帖  主题:回复:【MODBUS】跑在以太网上的MODBUS
介绍一款软件 vspdconfig 自己搜索下,网上很多的,可以虚拟串口的,这样就可以自己模拟了 用一个modbusmaster 一个modbusslave 看报文啥的很方便,不需要硬件了 。
要是找不到留下邮箱,我发给你。
常年奔波,是为的以后不奔波...............
您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。