2016年4月18日

浅谈MES的通用设计之:过程数据的上传


MES的另一个常见应用是过程数据的上传。
车间现场的设备会产生大量过程数据,需要上传到MES,主要基于以下两个考虑:
1、        过程数据经过整理,可以用于统计分析。
2、        结果数据上传到MES后,MES会根据结果来判断产品的后续工序。
通常来说,不同行业有自己的专属工具,特别是自动测试台架有很强的定制性,软件也往往是高度定制的。
下面我尝试以实例说明,来探讨过程数据上传的通用设计。
某测试台架产生测试数据后,将关键数据写入PLC,上传到MESMES根据传入数据的结果来决定将产品送入包装工位还是返修工位。
大致的设计思路是:
1、        MESPLC的原始数据按照某种规则转换成标准的过程数据结构。
2、        MES判断结果,并执行对应的业务流程。

比如说,PLC的数据结构是:
字段
起始位
长度
示例
说明
String Length
0
3
011
PLC有效字符长度11
Result
3
1
P
测试结果,P表示成功,其它值表示失败
Item1
4
2
20
测试项1的值
Item2
6
3
120
测试项2的值
String End
9
2
OK
结束字符

现在我们在数据库中建一个表来表达通用的数据结构:
字段名
数据类型
说明
STATION
VARCHAR2(20 BYTE)
工位
ITEMNO
NUMBER(2,0)
参数序列
ITEMNAME
VARCHAR2(200 BYTE)
参数名
ITEMLENGTH
NUMBER(3,0)
参数长度
ITEMUNIT
VARCHAR2(20 BYTE)
参数单位
STATUSMARK
NUMBER(1,0)
值为1表示此参数用于判定测试结果
STATUSVALUE
VARCHAR2(20 BYTE)
判定测试通过的有效数据

那么此PLC数据结构在此表中这样定义:
STATION
ITEMNO
ITEMNAME
ITEMLENGTH
ITEMUNIT
STATUSMARK
STATUSVALUE
1234
1
Test Status
1

1
P
1234
2
Item1
2
G


1234
3
Item2
3
MM



有了这个结构作为参照,当我们接收到PLC的原始数据后,我们就可以解析出测试结果,以及测试项1、测试项2的值。
附加上产品序列号、测试工位、测试时间、测试人员这些基本数据,我们就得到完整的测试过程数据。
下面我们进一步就可以把过程数据保存到数据库中。
在数据库中建立一个主表,一个从表,其中主表保存产品序列号、测试工位、测试时间、测试人员、测试结果。从表保存所有测试项的名称、值和单位。
在数据库中再建立一个触发器,监控主表的创建,一旦有新的数据,则立即查询测试结果,根据结果的不同来执行对应的业务逻辑。

下面是实现数据解析及结果处理的示例代码(Oracel数据库)
  DECLARE
   uploadstring VARCHAR2(2000);
       leftstring VARCHAR2(2000);
       itemname VARCHAR2(20);
       itemvalue VARCHAR2(2000);
    itemunit VARCHAR2(2000);
       itemlength INTEGER;
       statusmark VARCHAR2(1);
       statusvalue VARCHAR2(1);
       passfail INTEGER;
      
    CURSOR mycur IS
    SELECT
      t.itemno,
      t.itemname,
      t.itemlength,
      t.itemunit,
      t.statusmark,
         t.statusvalue
    FROM t -- à t是定义结构的表
    WHERE t.station = I_STATION
    ORDER BY t.itemno;
 
  BEGIN
 
       uploadstring := I_UPLOADSTRING;
       leftstring := uploadstring;
       itemname := 0;
       itemvalue := uploadstring;
    itemunit := '';
       itemlength := 0;
       statusmark := 0;
       statusvalue := '';
       passfail := 1;
 
    -- 1. get all items 查询得到所有数据
    FOR rec IN mycur
    LOOP
      itemname := rec.itemname;      
         itemlength := rec.itemlength;
         statusmark := rec.statusmark;
         statusvalue := rec.statusvalue;  
         itemvalue := SUBSTR(leftstring, 1, itemlength);
       -- 1.1 check test status mark 找到判断结果的参数
         IF statusmark = 1
         THEN
           if itemvalue = statusvalue
              THEN
                passfail := 1;
              ELSE
                passfail := 0;
              END IF;
         END IF;
         leftstring := SUBSTR(leftstring, length(itemvalue)+1,1000);
        
    END LOOP;   
      
    -- 1.2 add test data master 插入数据到主表         
       SP_INS_TESTDATAMST
         (
        I_ESN,
I_STATION,
I_TIME,
I_OPERATOR,
        passfail,
        O_MSTID -- à 主表流水号
      );
      COMMIT;
        
       -- 2 add test data detail插入数据到从表
    leftstring := uploadstring;
       FOR rec2 IN mycur
    LOOP
      itemname := rec2.itemname;    
         itemlength := rec2.itemlength;
         statusmark := rec2.statusmark;
         statusvalue := rec2.statusvalue;
      itemunit := rec2.itemunit;
         itemvalue := SUBSTR(leftstring, 1, itemlength);
       -- 1.1 check NOT test status mark
         IF statusmark = 0
         THEN
        SP_INS_TESTDET
              (     
          O_MSTID,
          itemname,
          itemvalue,
          itemunit
         );         
         COMMIT;

         END IF;
         leftstring := SUBSTR(leftstring, length(itemvalue)+1,1000);
    END LOOP;       
             
  END;




浅谈MES的通用设计之:工艺参数的下载


MES是计划和执行层之间的桥梁,除了将工单下发到车间外,还有一个重要功能是将工艺参数下载到设备,从而起到指导现场作业的作用。
本文试以实例说明常见的两种设计思路,以及一种更为通用的设计方法。

业务场景及设计实例1
某发动机工厂支持混线生产,有两种发动机,排量分别为2L3L。当发动机到达加油机工位时,PLC需要判断发动机的排量,从而进行对应的加油作业,如2L发动机加20L油,3L发动机加30L油。
实现方法如下:
为此工位专门写一个程序,逻辑步骤为:
1、发动机到达时,PLC读取RFID存储的发动机序列号。
2、PLC将发动机序列号上传到MES服务器,执行查询请求。
3、MES根据发动机序列号查询得到工单号。
4、MES根据工单号查询得到制造BOM
5、MES根据油缸料号的命名规则,查询得到发动机对应的油缸类型。
6、MES将油缸类型数据下载到PLC
7、PLC根据油缸类型决定加油量,进行加油作业。

业务场景及设计实例2
某整车厂焊装车间支持混线生产,同一款车有两种车门配置,分别为4门、5门。当车身到达某焊装工位时,PLC需要判断车门配置,从而决定焊接机器人的取料路径。
实现方法如下:
扩展工单的属性表,为每个工单建立一个长长的配置单,包括车型、门数、天窗、颜色、内饰等所有工艺需要的配置参数。逻辑步骤为:
1、车身到达时,PLC读取RFID存储的车辆识别码。
2、PLC将车辆识别码上传到MES服务器,执行查询请求。
3、MES根据车辆识别码查询得到工单号。
4、MES根据工单号关联查询配置单,得到所有配置参数。
5、MES将所有配置参数下载到PLC
6、PLC读取指定的数据块位置,得到门数参数。
7、PLC根据门数参数决定取料路径。

方法1的缺点是几乎每个工位都要做客户化开发。
方法2的缺点是配置单的准备相当繁琐,并且下载到PLC的数据量相当大。

下面介绍一种更为通用的、基于工艺配方的脚本化设计方法。
1、首先提供一个界面,允许用户定义工艺配方。
决定工艺配方唯一性的条件有:产品料号、工位号、步骤号、工单执行时间等。
每个工艺配方允许用户定义解释性字段,如名称、说明、图片等。
每个工艺配方的输出值为不定长的字符串。
为每个工艺配方定义字符转换条件,如长度、空值处理等。
每个工艺配方对应的逻辑是一个数据库函数。
也就是说,每次查询一次工艺配方,相当于运行一次数据库函数,根据输入值及函数逻辑(通常是一次查询),得到输出值也就是工艺配方的值。
2、然后编写一段代码,实现:
1) 运行工艺配方,得到每个步骤对应的初始工艺参数。
2) 根据字符转换条件,得到更为规范的步骤工艺参数。
3) 将工位所有步骤号对应的步骤工艺参数,根据步骤顺序进行拼合,得到工位完整的工艺参数。
3、然后将完整工艺参数下载到PLC

工艺配方的示例:


表中,字段itemtype表示工艺配方的类型,其中类型0表示常量,工艺参数值为字段itemvalue的值;类型1表示变量,工艺参数值为字段itemfunction的值对应的数据库函数的执行结果。
字段itemlength表示步骤工艺参数的长度。
字段fillchar表示查询返回空值时的填充字符。

Oracle中利用动态游标技术拼合步骤工艺参数的方法示例,下面为部分代码:
  DECLARE
    tmp VARCHAR2(2000);
    tmp2 VARCHAR2(2000);
    tmpfun VARCHAR2(2000);
    allstr VARCHAR2(2000);
    type curtype is ref cursor;
      mycur2 curtype;
    CURSOR mycur IS
    SELECT
      t.itemno,
      t.itemname,
      t.itemtype,
      t.itemvalue,
      t.itemfunction,
      t.itemlength,
      t.fillchar
    FROM t -- 此处t应为工艺配方表
    WHERE t.station = I_STATION -- 此处可添加更多的筛选条件
    ORDER BY t.itemno;
  
  BEGIN

  -- 1. get all item for station
    tmp := '';
    tmpfun := '';
    allstr := '';
        
    FOR rec IN mycur
    LOOP
              IF rec.itemtype = 0
        THEN tmp2 := rec.itemvalue; --> get value
        ELSE --> get function
          tmpfun := rec.ITEMFUNCTION;   
          tmpfun := tmpfun || '(''' || TO_CHAR(I_SN) || ''')';
          tmpfun := 'SELECT ' || tmpfun || ' myvalue FROM dual'; 
          OPEN   mycur2   FOR   tmpfun;  --> get item function
          FETCH   mycur2 INTO tmp2;
          close mycur2;              
        END IF;
        tmp := LPAD(tmp2, rec.itemlength, rec.fillchar);
        allstr := allstr || tmp;          
    END LOOP;         
   
  RETURN allstr;




2016年3月29日

MES中的松耦合设计一例

 

在不少领域,MES深入地参与现场作业,如将防错、配方等指令下发给工位和设备PLC,以指导现场作业。

通常这种MES与设备PLC的交互是实时通过OPC进行的,并且伴随不少的握手互锁逻辑。

但是在一些工厂,业务部门出于对IT系统的不信任,明确要求在MES服务器宕机的情况下不影响现场作业,从而实现所谓的松耦合设计。

以发动机拧紧防错为例,通常拧紧防错的方法是在MES里配置的,比如将机型在各工位的防错方法分配到拧紧枪号,并定义方向、次数、套筒号、扭矩等参数,但是拧紧的实现操作是由工位PLC配合拧紧枪控制器实现的。

因此对于工位PLC来说,有两种执行防错的方式:

方式一:每次当发动机到达拧紧工位时,工位PLCMES下载拧紧防错参数,然后执行拧紧作业,此谓与MES的紧耦合设计,依赖与MES的实时通讯。

方式二:每次当发动机到达拧紧工位时,工位PLCMES之外的某个介质获取拧紧防错参数,然后执行拧紧作业,此谓与MES的松耦合设计,不需要与MES进行实时通讯。

方式二的介质主要有两种:RFID与条码。

如下图所示,防错配置数据通过MES服务器>>OPC服务器>>IT PLC>>工位PLC>>RFID进行传递,在上线工位由工位PLC写到RFID上,并可在实际上线作业发生之前提前下载并缓存到IT PLC上,从而实现上线工位的松耦合。

当发动机到达装配工位时,工位PLCRFID中提取防错配置数据,然后与拧紧枪控制器一起执行拧紧作业,因此拧紧作业发生时也不需要与MES进行实时交互。

利用条码进行防错也非常类似,在上线工位为每个拧紧工位打印一张拧紧参数条码,然后张贴到随车单上,当发动机到达拧紧工位时,操作工扫描对应工位的条码,即可将拧紧参数传递给工位PLC

 

前面提到的IT PLC可以起到一个关键的数据缓存作用,即在上线作业实际发生之前,提前将上线所需的工单和防错配方等数据下载到IT PLC,这样在上线时,工位PLC直接从IT PLC获取数据,从而绕开了MES上层应用环境。

此外,IT PLC还可以起到数据上传的缓存作用,即设备PLC将业务数据(如过站记录和追溯数据)同步给IT PLC(工位PLC在普通作业工位将数据写到RFID,然后在同步工位将数据提取出来同步给IT PLC),然后由IT PLCMES系统可用时同步到MES服务器,这样对于工位PLC而言,它无须与MES服务器进行通讯,更加专注于装配作业本身。

 

 



 

2016年3月17日

MES案例研究3 – 质量门检查


某发动机工厂的总装下线工位成为一个瓶颈工位,平均操作时间近2分钟。
该工位有一些简单的附件装配作业,并且配置了质量门检查。
由于业务逻辑较复杂,首先从数据库的层面进行检查,发现此工位的一个关键查询SQL查询时间较长,用了近86秒。于是先对硬件进行升级,把SGA4G升到8G,结果查询时间降低了18秒,略有改进,但还不能达到业务设定的节拍时间。
接下来进一步分析业务逻辑。
最终下线质量门是一个综合检查站,要检查:
1)       发动机的工单状态是否正常。
2)       发动机的质量状态是否正常。
3)       发动机是否被质量扣留。
4)       发动机的检测结果是否正常。
5)       发动机是否有未清除缺陷。
6)       发动机的AUDIT结果是否正常。
7)       发动机是否经过所有的关键工位。
8)       发动机是否存在少装或多装零件。
这其中,逻辑最复杂、最消耗资源的是最后一步少装检查。
少装检查的逻辑是:
少装/多装物料 = 应装物料(BOM) – 已装物料 + 实时替代件转换
技术方面的困难主要是因为:
1)       BOM是一个动态的结构,需要根据工单上线时间、结构有效时间、零件有效时间进行动态地计算。
2)       存在分装,并且BOM也有层级结构,这样计算BOM时需要进行递归查询。
为了减少动态计算BOM的时间,从技术上可以采取以下方法:
1)       建立一个视图,字段包含所有总成件、分装件、零件等对应的所有信息,用上线时间作为计算的依据。
2)       建一个物化视图,对应此视图的结构。
3)       定期刷新物化视图,从而提前得到需要的数据。
这个改进有效减少了实时递归查询所消耗的时间。
另一方面,对业务流程进行改进:把该工位拆分为两个工位,第一工位做装配,第二工位做检查,这样就减少了装配作业所占用的时间。
经由上述改进,终于把工位节拍减少到58秒,满足了生产的要求。



2016年3月9日

test

just a test...


 

MES案例研究2 – OPC网络阻塞


  
某工厂使用OPC SERVER作为协议转换层,实现MES SERVER与现场PLC的通讯。
现场有2个车间,约有近20个工位需要和MES SERVER通讯。
等到所有工位都调试通过,系统也上线运行了一段时间之后,突然发现一个很妖的问题:OPC响应会越来越慢,最后造成一些工位完全没有响应。
一开始我们怀疑是网络的问题,于是把两个车间的网络隔离观察,发现问题仍然没有解决。
后来我们怀疑是应用的问题,于是在后台查看OPC CLIENT通讯的日志,依然毫无头绪。
接着我们怀疑是OPC客户端配置的问题,于是把所有工位的OPC配置按照手册重新设置了一遍。
这样下来,我们几乎折腾了半个多月,但是问题依然象幽灵一般存在,搞得业务部门非常不满。
后来我们想到试着去看OPC SERVER的事件日志,因为每次OPC通讯建立连接时,客户端是作为一个远程用户登录到服务器的,所以服务器应该会记录登录验证的信息。于是我们按照这个方向去查,也确实发现了不少登录的日志,但并没有显示IP地址、HOSTNAME等有用的信息。
后来我想到我们是用域帐户作为OPC远程用户进行登录管理的,那么理论上每次登录验证都需要通过域控制器进行。于是赶紧联系域管理员,从域控制器上导出最近一个月的事件日志,然后把此日志经过处理,筛选得到所有指向OPC SERVER的登录验证信息。经过这样处理,果然大有发现:有2PC异常频繁地请求访问OPC SERVER,于是抄下这2PC的机器名和IP 地址,到现场了解情况,很快地真相大白:原来这2PC是用于HMI的,安装了XP操作系统,然后运行WINCC RUNTIME,由于PLC工程师不断地通过U盘拷贝程序和文件,结果感染了病毒,因此这2PC不断地申请访问OPC SERVER,进而形成类似DDOS攻击的效果,从而造成OPC网络瘫痪。于是我们将此2PC断网杀毒,车间的OPC网络马上恢复正常运行。
这个案例给我的教训是:
1.       一定要做好生产网络的隔离。首先务必要将生产网络从办公网络隔离,其次不同车间之间最好也划分VLAN进行隔离。
2.       不仅是运行MES客户端的PC要安装杀毒软件,HMI、测试机台等也都要安装杀毒软件,从而防止病毒的入侵。
3.       由于早期版本OPC采用DCOM进行远程通讯,在典型配置时OPC服务器的安全等级非常低,容易被入侵,此时条件允许的话,要考虑配置用域账户管理OPC远程登录,这样可以通过域控制器的事件日志回溯每次的登录请求,方便日后追查分析。