DCS项目调试踩坑记录

        最近在调试一个DCS项目(集散控制系统),实际上就是一个新建厂区的控制系统。PLC用的是西门子1500,控制画面使用组态王7.5。

        在调试过程中,发现给西门子DB块的变量转移到组态王太难了,因此记录一下,有需要的朋友可以参考我的做法,我这做法不一定是最简单的方法,如果哪个大神有更简单的方法,麻烦请告知一下。

        首先介绍一下DCS系统。DCS系统基本包含下面几个部分:

        1:设备部分,包含工厂生产需要的设备,以及设备的运转所需要的配电箱。设备的配电箱一般包含控制器(就是PLC,用来对设备本身运转做控制),传感器,变频器,等等。
        如果没有DCS系统,在条件具备的情况下,也是可以由工人在控制箱上按按钮来控制设备。但是很明显现场让工人控制设备明显不太可行,因为设备太多,距离太远,突发情况根本来不及控制。

        2:总控部分,就是在现有设备基础上,增加一层控制器,这一层控制器负责接入具体设备的配电箱,来代替人工在箱子上按按钮,以及读取设备的状态。也可以实现一定的逻辑判断,可以根据条件将多个连锁设备一同开启或者关闭。

        3:中控部分,这一部分,就说开发一个控制画面,从总控PLC里面读取全厂设备状态,以及实现在中控室对全厂设备进行控制。

        DCS系统大致结构图如下。中控和几个配电室组成一个环网,需要专门的环网交换机,环网的好处是中间断一下不影响。比如中间某个配电室突然断电,不影响其他。

         DCS系统里面,设备本身的控制逻辑,在设备随机的控制器都已经做好了,这个是设备厂家做的,一般也不对外开放。控制箱保留一些控制接口(如硬接线,485,网口等)。

        总控PLC一般是需要根据特定的场景和需求来进行编程。这个编程大致的意思,就是在什么情况下,启动某个设备。在什么情况下关闭某些设备。

        最后是中控画面控制总控PLC,从而达到控制全厂设备的目的。

        那么,中控是怎么控制PLC呢,答案很简单,就是通过修改PLC内部的变量(实际上就是内plc的内存,内存连续存了很多变量,short,float,bool,int 等)。PLC一般对外提供通讯协议,让上位机软件来读取和修改内部变量。例如西门子的S7协议,modbus_rtu,modbus_tcp,can,等等。

        中控画面要修改PLC内部的变量,就需要要在组态软件知道plc内部变量的地址,因为变量太多,一般情况下,都是几千个变量起步,如果地址没有对上,中控点击启动,可能会产生严重后果。所以对变量是一个体力活。

        这里要吐槽的第一点就是博图(西门子PLC编程软件)居然没有办法把DB块导出到excel,来方便其他组态工具导入变量。但是博图可以打印DB块到PDF。

        吐槽的第二点:组态王导出结构体变量居然报错。见下图:

 再咨询过组态王技术以后,技术表示不支持导出结构变量,也不支持导入结构变量。但是我PLC里面全是结构变量。因为结构变量用起来更方便,不容易记错。

不过技术说可以通过另外一种方法,就是再工程管理界面,导入和导出DB。如下图:

 导出的DB内容如下。这个要注意,组态王导出和导入,调用的excel,如果电脑上没有安装excel,这个功能是没法用。安装wps也不行。强烈建议组态王支持国产,支持wps。

 有了这个文件,剩下的就是想办法把博图导出的变量表(PDF文件见下图),按照这个格式转换一下。

当然直接读取PDF是不太可行的,不过WPS可以将PDF转换成excel,只要不是图片版的excel就行。刚刚这个就不是图片。所以还得是WPS帮忙。转换为excel见下图。看起来还是有点乱,不过不影响。

有了DB格式文件,有了excel,那剩下的就简单了。上py代码:

##############################################################
# 用于将博图DB块里面批量定义的结构体,转换为组态王格式,方便导入  #
# 博图DB块需要先打印成PDF,然后再用WPS将PDF转换为excel          #
#  qujia 20241022                                            #
##############################################################

import pandas as pd             #用于读取excel,如果没有需要pip install pands
from openpyxl import Workbook   #用于写入excel,如果没有需要pip install openpyxl
#定义db块中,需要被导入的变量名称,下面的下标一一对应
keys = ['bStart','bStop','StartAllowed','StopAllowed','rPinlv_Geiding','rPinlv_Geiding_A','MA','bReset','EM',
        'bOpen','bClose','bStop','bOpen_A','bClose_A','bStop_A'
        ]
#定义在组态王中,结构体的变量名称,与上面的下标一一对应
names=['启动','停止','启动许可','停止许可','手动频率','自动频率','模式','复位','急停',
       '手动开','手动关','手动停','自动开','自动关','自动停'
       ]

def read_xlsx(file_path):                  #读取excel文件,返回一个集合
    df = pd.read_excel(file_path)           
    data = df.values.tolist()
    return data

data = read_xlsx('plc2write.xlsx')           #读取excel文件,这个文件是pdf转的
wb =Workbook()                              #用于导出excel文件
st1 = wb.create_sheet('结构体变量')          #结构体变量sheet
stInt = wb.create_sheet('基本变量_IO整数')   #整数变量表单
stFloat=wb.create_sheet('基本变量_IO实数')   #实数变量的表单
stBit=wb.create_sheet('基本变量_IO离散')     #bit变量表单
structId = 153                                #当前结构变量id,当前最大的编号
varId=1383                                    #当前基本变量id,当前最大的编号
deviceName=''                               #当前设备名称,结构体名称
dbName='DB6.'                             #DB块名称
structName='设备控制'                       #结构体名称
plcName='筛分站PLC'                         #plc名称
for r in data :
    name=r[1]                               #名称
    type=r[4]                               #类型
    add=r[6]                                #地址
    remark=r[17]                            #备注信息
    
    #print(name,type)
    if type == 'Struct' :                   #如果是Struct ,可能是结构体开头
        if name.find('Static') !=-1:        #如果是没有名字的设备,直接结束
            #print(r)
            print("end ")
            break
        else:
            print("device ",name , remark)          #控制台打印
            structId=structId+1                     #结构变量id增加1
            deviceName='W'+name.replace('-','_')    #结构名称转变一下,符合组态王规则
            structName='设备控制'                       #结构体名称
            if deviceName.find('A_VA')>=0  or deviceName.find('A_GA')>=0:
                structName='阀门控制'                   #结构体名称
            st1.append(['[结构变量]','变量ID','变量名','变量类型','变量使用记数','注释'])   #输出结构变量标题
            st1.append(['',structId,	deviceName,	structName,	0,	remark])        #输出结构变量名称和备注
            st1.append(['','[成员]','成员名称','成员基本变量ID','',''])	                  #输出成员变量标题
            continue                            #继续下一行

    
    if name == None :                           #直接跳过空行,提升效率
        continue
    if type=='Bool' and add==int(add):          #如果是bool类型,并且是***.0,excel里面会把.0去掉,这里再加上去
        add=dbName+str(add)+".0"
    else :
        add= dbName+str(add)
    if name in keys :                           #如果是目标变量
        remark=remark[0:35]                     #注释不能太长,组态王最大支持40个字符
        idx=keys.index(name)                    #根据名称,对应组态王里面属性名称
        vname=deviceName+"."+names[idx]         #根据名称,对应组态王里面属性名称
        if structName=='阀门控制' and name=='bStop' :
            vname=deviceName+'.手动停'
        print(name,vname,type,add,remark)       #输出到控制台
        varId=varId+1                           #基本变量编号增加一个
        st1.append(['','',vname,varId,'',''])   #结构体添加变量引用
        if type=='Int' :                        #输出到整数表单
            stInt.append([varId,vname,0,0,0,0,999999999	,0,999999999,'否','否',	plcName,add,'USHORT','只写',1000,'线性','无','','','','否','',1,'','','','','','','','','','','','','','','','','','','不记录','','','否','无',remark,144,''])
        elif type=='DInt':                      #输出到整数表单
            stInt.append([varId,vname,0,0,0,0,999999999	,0,999999999,'否','否',plcName,add,'LONG','只写',1000,'线性','无','','','','否','',1,'','','','','','','','','','','','','','','','','','','不记录','','','否','无',remark,144,''])
        elif type=='Real':                      #输出到浮点数表单
            stFloat.append([varId,vname,0,0,0,0,999999999,0,999999999,'否','否',plcName,add,'FLOAT','只写',1000,'线性','无','','','','否','',1,'','','','','','','','','','','','','','','','','','','不记录','','','否','无',remark,144,''])
        elif type=='Bool':                      #输出到bit类型表单
            stBit.append([varId,vname,0,'关','否','否',plcName,	add,'Bit','只写',1000,'否','',1,'否','','','','','','','','不记录','','否','无',remark,144,''])


wb.save('write2.xlsx')                             #写入目标文件

 最后生成的变量表文件,直接贴进去,然后DB导入,完事。不过强烈建议导入之前,对项目进行备份,万一出问题,后悔来得及。

猜你喜欢

转载自blog.csdn.net/qujia121qu/article/details/143169157
今日推荐