今天同事打电话说现场6台宇电ai仪表,1台东辉8路巡检仪,3台富士frenic-vp变频器,2台日本rkc仪表,1台创盛流量计都要挂到wincc里(之前说是厂方自己弄的),因为厂方临时要求加的,邮寄cp340挂到s7300就算了,也没几个通信设备,都是rs485,一条通讯线挂一起,能省就省吧,同事随身带的有rs485转232模块。
平常项目都是自己写的软件,二年前就用过一次wincc6,外挂其它通讯设备也没试过,在网上搜了一圈,多是讲opc什么的,不了解,觉得对我来说不太合适。还有讲用mscomm控件的。mscomm控件就不提了,已废弃多年不用了,不可能再回到老路上。于是决定移植上位机的代码,用win32api来做成ocx,wincc里来调用,这样并非像网上说的要支持modbus协议或找opc什么,只要通讯设备有通讯协议,带通讯接口即可。我的方法看起来也许比较麻烦,但方便维护,去现场调试的人不需对通讯怎么懂,会设置通讯设备的地址参数就行了,其它都用默认参数,再说增加个新的通讯设备协议,也就一小会儿事。
1.先编个基类,定义接口,方法,属性,例如通讯com口,波特率、数据位、停止位、校验方式等等生成dll链接库。
2.从基类派生各个通讯设备类,如仪表,变频器,流量计,plc等等,通讯设备类负责将要读或要写的数据打包给串口类,并接收来自串口类的回送数据进行处理,生成dll链接库,这个库最大,包含了五十多种设备的通讯,以后新加通讯设备只需拷贝一个,稍加修改即可。
3.再编个通讯串口类,调用win32通信api函数,负责将通讯设备类打包过来的发送数据发送出去,再将接收到数据返回给通讯类自身处理,生成dll动态链接库。
4.再编个消息类,负责将通讯的发送字节,接收字节,当前通讯设备的通讯设置参数,通信成功或失败等信息作为事件触发,生成dll动态链接库.
5.后面的就简单了,编个ocx控件直接引用上面的dll库编几个小调用函数,再封装几个属性和消息事件触发,编译一下做个ocx安装程序。
6.发给同事ocx安装包,同事安装后直接注册下ocx即可用,只需在wincc里初始化下这个ocx挂的各个设备名称,通讯地址,端口,波特率,数据位,停止位。然后再在循环处理过程里编个通用的轮循过程,要读的设备号,要读的参数或要写的参数及要写的数据。读写成功失败或者收发的字节通过ocx的事件触发来处理。
7.如果现场新加的通讯设备协议在这个ocx中,wincc只需要改一下初始化过程,挂靠的ocx通讯设备名称,通讯参数即可,其它如轮循过程,变量处理根本不需要改动。
如果wincc只挂少量设备,也可以采用mscomm控件处理,毕竟mscomm简单,建议还是不要在wincc里直接用mscomm控件,代码很乱,不方便移植。还是自己编个ocx,在ocx里面用mscomm控件,再封装几个方法属性出来给wincc调用,也方便客户使用。
毕竟wincc我很少用它,但它确实很强大^_^,也许是我不熟的原因,觉得它通信慢。问下大家,读单字,双字大概算下来有合计800个16位字的通讯,mpi方式.下午顺便发了个测试代码给同事,同事说wincc一次大概只能读100多个字,也就是200多个字节,再多了就失败,而且每次耗时大概1~2秒.那800个字不得调8次?感觉这样不行。我用的gettagraw函数.但是我记得如果采用prodave方式,一次就可以读回来了,耗时感觉不到1秒,正考虑是不是把s7300/200plc通讯全移到ocx处理算了,不知有没这个必要。
利用循环。
第一个500ms读一个设备;
第二个500ms读第二个设备;
第32个500ms读第32个设备;
不要一起都读!分开读!