故事作者:拾起

最近创作

看看TA的故事

再说说WINCC与串口通讯

已锁定

拾起

  • 帖子

    335
  • 精华

    6
  • 被关注

    52

论坛等级:奇侠

注册时间:2010-08-24

普通 普通 如何晋级?

再说说WINCC与串口通讯

5557

29

2016-06-13 10:54:58

star star star star

再说说WINCC与串口通讯

题记:刚开始接触WINCC是在10年左右,当时用WINCC6.2的版本,因为要将数据写入数据库,但客户没有购买Connectivity Pack软件,也不清楚这个软件在连接数据库中起什么作用,只是西门子技术支持说要连数据库就要这个,于是我只好通过用户归档的方式实现了项目要求。刚开始技术论坛和找答案中没有太多相关的介绍,后面介绍我的方法后,类似的通过用户归档的方式跟数据库相关就雨后春笋般的出来了。也由这个项目,感受到了WINCC的强大,好用,看了两本跟WINCC相关的书不解渴,后来就又买了一本专门介绍VB的书,再结合后面的项目,才真正的初窥WINCC的门径。

言归正传,说说WINCC与串口的故事。在当下,很多制造业有追溯的需求,需要将生产加工的数据存储起来以便于生产管理,比如MES,在将来的工业4.0下,这样的需求只会更多。针对旧的生产设备,其PLC不一定有空余的串口,而且可能生产设备需要同时识别条形码和二维码,简单的在PLC端增加串口不切实际,而且不一定有多余的安装位置,在这样的情况下,通过WINCC与串口通讯就显得靠谱,而且借助脚本语言,可以很方便的分析条码信息,比在PLC中处理方便多了。

项目的案例,应用在某装配车间的一条装配线,属于改造原生产线具备生产追溯的功能,除数据存储和记录外,还需要上工位加工的NG产品,在下工位是不允许设备动作等防错功能。总共7个工位,其中3个工位还需要扫描金属制品的二维码标签,共计10个串口,客户有一台利用PCI总线扩容出来的16个串口的设备,7个工位统一用一台电脑控制,现场设备到该电脑的串口线长度没有超过串口允许的长度15米。现场7个工位,其中两台S7-300,其余为三菱Q系列和FX系列,将FX通过CC-Link与Q系列组网,然后与WINCC走以太网交换数据,除CC-Link模块新购买,其余均利用原来设备。

 

一、串口控件MSCOMM32.OCX的注册。以下是网上下载的流程,特别提示WIN7要以管理员方式运行“命令提示符”,不然注册可能失败

1下载MScomm控件。

2解压后将Mscomm.srg, Mscomm32.ocx,Mscomm32.dep三个文件复制到系统文件夹system32中,(C:\windows\system32)

3用Windows下的注册工具regsvr32注册该OCX控件,点击“开始”->"运行",打开dos界面后输入:Regsvr32 C:\windows\system32\Mscomm32.ocx,进行注册,会提示注册成功(win7要管理员身份打开)。

4接着要修改下注册表:点击“开始”->"运行",再在中填入regedit命令打开注册表,找到HKEY_CLASSES_ROOT目录下的Licenses,在其中添加一个主值:4250E830-6AC2-11cf-8ADB-00AA00C00905并将内容设置为: kjljvjjjoquqmjjjvpqqkqmqykypoqjquoun(怎样创建主值:右击鼠标来创建)

 

二、串口的事件触发

串口的触发分为周期触发和事件触发。周期触发就是在全局脚本中定义某一周期,周期性获取缓冲区数据。事件触发就是事件触发OnComm事件,具体参考串口属性。因为条形码的长度不一,刚开始的获取数据,通过周期性触发,判断缓冲区字符长度来判定,但该方式有很多BUG,比如,再下一触发周期没到之前(缓冲区数据没有提取),扫了两次条码,那么缓冲区将是两次的数据,长度判断就不靠谱了。这次客户提出要求,就顺势改为事件触发。

在串口使用前,首先要打开串口,我的方法是,当主画面一打开,就执行以下脚本:

         Dim objMSComm3, tagConnection3

         Set objMSComm3 = HMIRuntime.Screens("MAIN").ScreenItems("OP30COM1")

         Set tagConnection3 = HMIRuntime.Tags("OP30_Connection1")

        

         If objMSComm3.PortOpen = False Then

                 

                  ' Assign com port number

                  objMSComm3.Commport = 9

                 

                  ' Values: 9600 Baud, N - No Parity, 8 - Databit, 1 - Stopbit

                  objMSComm3.Settings = "9600,N,8,1"

'                 objMSComm3.RThreshold = 1

'                 objMSComm3.SThreshold = 1

                  objMSComm3.InBufferCount = 0

                  objMSComm3.InputLen = 0

                  objMSComm3.PortOpen = True

                 

 

                  tagConnection3.Write (True)

                  HMIRuntime.Trace("9# Port open." & vbCrLf)

         Else

                  HMIRuntime.Trace("9# Port is already opened." & vbCrLf)

         End If

其他串口类似,请注意区分串口号。

三、串口的属性

请参与附件,如果不行,请网上下载相关资料《串口通信-MSComm控件使用详解》,因为是获取条码,故只列举RThreshold属性。

RThreshold属性: 通过该属性设置产生OnComm 事件(接收时产生)的阀值,若MSComm1.RThreshold:=0,不产生OnComm 事件,若MSComm1.RThreshold:=5,接收缓冲区每收到5字节时,则产生OnComm 事件

在实际的使用中,设定RThreshold属性的值为1,即1个字符触发一次OnComm事件,通过判断字符是否接收到末尾字符(案例中,条码的末尾字符是EOT(char(4))。扫描枪识别条码后会自动加上回车符char(13)),把没有检测到末尾字符就接收到数据放在一个WINCC的内部变量中,不断的累加。心想,50个字符应该会进行50次的OnComm事件吧?

四、模拟测试与实际调试

测试的环境如下:WIN7 32位,安装了CommTone6.0串口调试和Configure Virtual Serial Port Driver软件,用于发送数据和虚拟串口。

在模拟测试中发现,50个字符并没有产生50次的OnComm事件,在画面刚开始打开,也就是第一次打开串口,执行了2次,后面继续发送,每发送一次,产生3次时间,其中50个字符都是一次接受完成,其余均为空字符。(至于第一次是2,后面是3次,还是第一次是3,后面2次不记得了,最重要的信息是,无论多少个字符都是一次完成)

在虚拟测试中发现,把数据写入内部变量,比如Buffer1.write,在该代码后面出现Buffer1.read,发现仍然为空值,但是如果中间有MSGBOX弹出别的对话框,人工确定,那么后面弹出的Buffer1.read有值,说明Buffer1.write(内部变量的写入)也是有时间要求。(原先以为是整个代码执行完成后再写入,类似于PLC的IO寄存器一样,执行程序时先扫描,执行完成后再更新)。

虽然是一次完成,但我初步认为,虚拟的串口数据在内存或硬盘上,几乎是不用传送时间,所以实际中不见得也是一次接收到这么多字符,我还是按我的设想迎接实际调试。

以下是数据接收代码:

'=====================获取OP30手持扫描枪的信息======================’

      Dim objMSComm,Buffer1,ProcessLabel,Process_RUN,SGW

      Dim strTempTAG,strTemp,t1,t2

      Dim mm,nn,jj,kk,tt

      Dim pp,qq,BZ

      Dim MessageCode,MessageType,MessageText,r1,r2,r3,r4,r5

      Dim m,n,p,q

      Dim xx,zz,OUTMsgText

 

      Set objMsComm = HMIRuntime.Screens("MAIN").ScreenItems("OP30COM1")

      Set Buffer1 = HMIRuntime.Tags("OP30_Buffer1")

      Set ProcessLabel = HMIRuntime.Tags("OP30_ProcessLabel")

Set Process_RUN = HMIRuntime.Tags("OP30_Process_RUN")

      Set SGW = HMIRuntime.Tags("OP30_Status_SGW")

      Set BZ = HMIRuntime.Tags("OP30_BarRead_BZ")

      Set MessageCode = HMIRuntime.Tags("OP30_MessageCode")

      Set MessageType = HMIRuntime.Tags("OP30_MessageType")

      Set MessageText = HMIRuntime.Tags("OP30_MessageText")

      Set OUTMsgText = HMIRuntime.Tags("OP30_Text")

strTemp = ""

         If objMSComm.PortOpen = True Then

                   strTemp = CStr(objMSComm.Input)

                   If strTemp<> "" Then

                   If InStr(strTemp,Chr(4)) Then '如果判断已经接收到停止符号,则判断条码接受完成

         strTempTAG = Mid(strTemp,1,Len(strTemp)-1)

                t1 = Len(Buffer1.Read)

                t2 = Len(strTempTAG)

         tt = t1 + t2

                Buffer1.Read

                Buffer1.Value = Buffer1.Value &strTempTAG

                Buffer1.Write

                'MsgBox T30

                            If tt> 50 Then    '判断为物料标签,超出45位,截取其中的字符

                                     mm = InStr(Buffer1.Read, "P")

                                     jj = InStr(Buffer1.Read, "2P")

                                     xx = InStr(Buffer1.Read, "Q")

                                     nn = InStr(Buffer1.Read, "3S")

                                     kk = InStr(Buffer1.Read, "1T")

                                     pp = Mid(Buffer1.Read, mm + 1, jj - mm - 1)

                                     zz = Mid(Buffer1.Read, xx + 1, 5)

                                     qq = Mid(Buffer1.Read, nn + 2, kk - nn - 2)

                                     ProcessLabel.Value = pp&qq&zz '将数据写入BUFFER

                                     ProcessLabel.Write

                                     objMSComm.InBufferCount = 0

                                     BZ.Write 1

 

                            End If

        

                            If tt<= 23 And tt>= 17 Then   '判断为过程标签,共计17位

                                Buffer1.Read

                            ProcessLabel.Value = Buffer1.Value  '将数据写入ProcessLabel

                                     ProcessLabel.Write

                                     objMSComm.InBufferCount = 0

                                     BZ.Write 1

                            End If

……

实际测试中,字符的获取在9600波特率的情况下,即使是最远的距离下,在该项目需求的60个字符都是一次全部接收,并没有分段接收,说明MSComm1.RThreshold:=1的情况下,接收数据产生的OnComm事件也只执行了一次(准确的说是多次,只是其他的都是空字符,只有一次非空字符,该字符数据长度就是接收的数据)。

五、经验总结

1、  注册MSCOMM32.OCX请用管理员身份运行。

2、  最好使用事件触发,通过判断某个特殊字符来确定是否数据接收完成。

3、  在接收阀值属性MSComm1.RThreshold:=1的设定下,9600的波特率,13米的距离(事实上距离对传输时间的影响几乎可以忽略),可以一起传送并接收。首先需要判断为非空字符,然后再判断是否有特殊字符,再执行其他语法。

4、  可以使用MSGBOX来诊断程序执行到哪一步,也可以用INPUTBOX来输入程序需要的数值。

 

后记:项目还没有进行完成,但关于串口的使用已经OK。从刚开始接触WINCC到如今,越来越感受到WINCC的开放性,利用脚本可以实现很多功能。从最初的“小白”到如今的“小白”是从形式到内涵的改变,这个旅途也是学习一点应用一点不断进步,项目做完不是终结,而是下一个项目的开始,能不能承接下一个项目,就需要在这个过程中有没有积累,不然即使机会来了也抓不住。工控行业博大精深,需要有不断学习的心,没有一招鲜或大杀器,只有不断积累不断学习,深刻掌握原理,才能举一反三。


串口通信-MSComm控件使用详解.docx


再说说WINCC与串口通讯 已锁定
编辑推荐: 关闭

请填写推广理由:

本版热门话题

网友专栏

共有3233条技术帖

相关推荐

热门标签

相关帖子推荐

guzhang

恭喜,你发布的帖子

评为精华帖!

快扫描右侧二维码晒一晒吧!

再发帖或跟帖交流2条,就能晋升VIP啦!开启更多专属权限!

top
您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。