⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.~pas

📁 利用delphi跟西门子s5系列PLC通讯
💻 ~PAS
📖 第 1 页 / 共 2 页
字号:
unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, ADODB, StdCtrls, ExtCtrls, Inifiles,OleCtrls, CERTWIZLib_TLB;

type
    MyArray = array[0..15] of  integer;  //在定义函数返回值为数组时用,
    Tmainfrm = class(TForm)
    GroupBox1: TGroupBox;
    ADOCLocal: TADOConnection;
    ADOQLocal_eq: TADOQuery;
    ADOQLocal_output: TADOQuery;
    ADOQLocal_fault: TADOQuery;
    Tm_Output: TTimer;
    Label1: TLabel;
    Edt_product: TEdit;
    Tm_Fault: TTimer;
    Label2: TLabel;
    Label3: TLabel;
    Edt_dw1: TEdit;
    Edt_dw2: TEdit;
    GroupBox2: TGroupBox;
    ADOConnServer: TADOConnection;
    ADOQuery1: TADOQuery;
    ADOQ_output: TADOQuery;
    ADOQueryFault: TADOQuery;
    ADOQueryParaChange: TADOQuery;
    Label4: TLabel;
    lbl_ConnState: TLabel;
    Tm_ConnState: TTimer;
    Tm_NowData: TTimer;
    Label5: TLabel;
    lbl_Machine_id: TLabel;
    Label6: TLabel;
    lbl_Plc2Movicon: TLabel;
    Tm_ParaChange: TTimer;
    lbl_ParaChange: TLabel;
    ADOQLoacl_techpara: TADOQuery;
    procedure Tm_OutputTimer(Sender: TObject);
    procedure Tm_FaultTimer(Sender: TObject);
    procedure Tm_ConnStateTimer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Tm_NowDataTimer(Sender: TObject);
    procedure Tm_ParaChangeTimer(Sender: TObject);

  private
  //----------------------基本变量定义-----------------------------------------
    Guige_id: Integer;                //规格代号
    Machine_type: string[10];         //机型
    Machine_id: Integer;              //机台号

   //---------------------故障相关变量定义-----------------------------------------


    //NoFault: boolean;                //主副机是否无故障
    FaultTime1: array[0..15] of TDateTime;     //故障开始时间
    FaultTime2: array[0..15] of TDateTime;
    //--------------------实时数据相关变量定义-----------------------------------------
    Plc2Movicon:boolean;                 //plc能否连接到movicon
    SysTime0,SysTime : TDateTime;        // 系统时间,在设备实时数据定时器中使用 System Time
    LocalTime0,LocalTime: TDateTime;     //本地时间,用来判断PLC与Movicon的通讯
    Data:array[0..6] of integer;         //用来存放七个设备实时数据


    //------------------------工艺参数变更相关变量----------------------------
    TempData  :array[0..15] of integer;      //临时工艺参数temporary data
    TechPara  :array[0..15] of integer;      //工艺参数 technics parameter
    TempGuige_id:integer;                    //临时规格代号, temporary  Guige_id

    //------------------------产量上传相关变量----------------------------

    ProductCount:Integer;             //PLC产量计数器的当前值       Product Count值
    Product_countMax:Integer;         //PLC产量计数器的最大记数值
    OnDuty:integer;                 //上下班即时状态
    OnDuty0:integer;                //上下班过度状态

    { Private declarations }
  public
    { Public declarations }
  end;

var
  mainfrm: Tmainfrm;
  myinifile: Tinifile;
implementation

{$R *.dfm}
function  IntToArray(Value:integer): myarray;  //将一个十进制数转换成二进制放在一个16位数组里面。
  var
      i:Integer;
      myarray1: myarray;
    begin
      for   i:=15 downto 0 do
          if Value and (1 shl i) <>0 then
              myarray1[i]:=1
          else
              myarray1[i]:=0;
      result:= myarray1;
end;

procedure Tmainfrm.Tm_OutputTimer(Sender: TObject);
var
//productcount0: integer;   //计算一天产量是的过度变量
output: integer;          //当天产量
maxT,minT: double;        //每胎间隔最大最小值
ProductCountL: integer;   //计算产量报警时的变量
DiffTime: double;           //产量变化的时间差  单位为分钟
ProductChangeTime:string;  //产量变化的实时时间
Output_alarm: integer;      //产量报警信号
productcount_onduty:integer;      //上班时的产量plc值
output_realtime: integer;        //实时产量
begin
     if Plc2Movicon then
       begin
     //************************从本地Access读取PLC产量计数器的当前值******************************************
            ADOQLocal_output.Close;
            ADOQLocal_output.SQL.Clear;
            ADOQLocal_output.SQL.Add('SELECT TOP 1 * FROM dtc_cxx_output_now_s5_local ORDER BY 本地时间 DESC');
            ADOQLocal_output.Open;
            ProductCount:=ADOQLocal_output.FieldByName('Output_number').AsInteger;
            Edt_product.Text:=inttostr(ProductCount);

            //产量报警上、下限(分钟)及轮胎报警条数的求取
           ADOQ_output.SQL.Clear;
           ADOQ_output.SQL.Add('dtc_cxx_output_alarmpara_search :Guige_id,:Machine_id');
           ADOQ_output.Parameters.ParamByName('Guige_id').Value :=Guige_id;
           ADOQ_output.Parameters.ParamByName('Machine_id').Value :=Machine_id;
           ADOQ_output.Open;
           minT:= ADOQ_output.fieldbyName('Alarm_min').AsInteger;
           maxT:= ADOQ_output.fieldbyName('Alarm_max').AsInteger;

     //************************上下班信号的求取*************************************

            ADOQ_output.SQL.Clear;
            ADOQ_output.SQL.Add('dtc_cxx_output_xiaban_get :Machine_id');
            ADOQ_output.Parameters.ParamByName('Machine_id').Value := Machine_id;
            ADOQ_output.Open;
            OnDuty:=ADOQ_output.fieldbyName('Xiaban_id').AsInteger;

    //**********当刚上班时把产量值保存在ini文件中,等下班是调用*******************
           if (OnDuty-Onduty0)=1 then
                begin
               ProductCount_onduty:=productcount;
               myinifile.WriteInteger('product','productcount_onduty ',productcount_onduty);
               end
           else if (OnDuty-Onduty0)=-1 then
             begin
                productcount_onduty:= myinifile.readInteger('product','productcount_onduty',ProductCount_onduty);
                if ProductCount-productcount_onduty>0 then
                    output:=ProductCount-productcount_onduty
                else
                    output:=Product_countMax-productcount_onduty+ProductCount+1;
             //****************************************
                ADOQ_output.SQL.Clear;
                ADOQ_output.SQL.Add('dtc_cxx_output_insert :Guige_id,:Machine_id,:Output_number_all');
                ADOQ_output.Parameters.ParamByName('Guige_id').Value := Guige_id;
                ADOQ_output.Parameters.ParamByName('Machine_id').Value := Machine_id;
                ADOQ_output.Parameters.ParamByName('Output_number_all').Value :=output;
                ADOQ_output.ExecSQL;
                myinifile.WriteInteger('product','productcount_onduty',ProductCount_onduty);
             end;
             OnDuty0:=OnDuty;   //将上班状态赋值给临时上班状态,等下一次调用

        productcountL:= myinifile.readInteger('product','productcountL',10);
        ProductChangeTime:=myinifile.readstring('product','ProductChangeTime',ProductChangeTime);
        DiffTime:=(now-strtodatetime(ProductChangeTime))*24*60;
        Output_alarm:= 0;
        if  productcountL- productcount<>0 then
        begin
             if DiffTime<minT then           //超速
               Output_alarm:= 2
             else
                if DiffTime>maxT then
                Output_alarm:= 1        //超时
             else
                Output_alarm:= 0;        //正常
            myinifile.Writestring('product','ProductChangeTime',datetimetostr(now));
        end;
         //*************上传产量状态(实时产量+产量报警信号)***********

         productcount_onduty:= myinifile.readInteger('product','productcount_onduty',ProductCount_onduty);
         if ProductCount-productcount_onduty>0 then
            output_realtime:=ProductCount-productcount_onduty
         else
            output_realtime:=Product_countMax-productcount_onduty+ProductCount+1;

          ADOQ_output.SQL.Clear;
          ADOQ_output.SQL.Add('dtc_cxx_output_update :Guige_id,:Machine_id,:Output_number');
          ADOQ_output.Parameters.ParamByName('Guige_id').Value := Guige_id;
          ADOQ_output.Parameters.ParamByName('Machine_id').Value := Machine_id;
          ADOQ_output.Parameters.ParamByName('Output_number').Value := output_realtime;
          ADOQ_output.ExecSQL;

          ADOQ_output.SQL.Clear;
          ADOQ_output.SQL.Add('dtc_cxx_output_alarm_update :Guige_id,:Machine_id,:Output_alarm');
          ADOQ_output.Parameters.ParamByName('Guige_id').Value := Guige_id;
          ADOQ_output.Parameters.ParamByName('Machine_id').Value := Machine_id;
          ADOQ_output.Parameters.ParamByName('Output_alarm').Value :=Output_alarm;
          ADOQ_output.ExecSQL;
         //*************上传产量状态(实时产量+产量报警信号)***********
    end;
end;

procedure Tmainfrm.Tm_FaultTimer(Sender: TObject);
var
i:integer;
DW1,DW2: integer;                    //真实故障位,存在plc里面的数
DW1_current,DW2_current: integer;
DW1_array0,DW2_array0:myarray;       //上一次故障数组
DW1_array: myarray;                  //dw1故障数组 (16位)
DW2_array: myarray;                  // dw2故障数组 (16位)
FaultCount: integer;                // 故障个数
FaultCount0: integer;                // 故障个数临时值
begin
  //***********************从本地Access读取主副机故障值***************************************
  ADOQLocal_fault.Close;
  ADOQLocal_fault.SQL.Clear;
  ADOQLocal_fault.SQL.Add('SELECT TOP 1 * FROM dtc_cxx_fault_now_s5_local ORDER BY 本地时间 DESC');
  ADOQLocal_fault.Open;
  DW1:= ADOQLocal_fault.fieldbyName('DW1').AsInteger;
  DW2:= ADOQLocal_fault.fieldbyName('DW2').AsInteger;


 //***********************判断主副机是否正常***************************************
  DW1_current:=(DW1 shr 2) and 31;        //截取DB45.DW1.D1.2~DB45.DW1.D1.6位,其它位屏蔽
  DW2_current:=DW2 and  16383;            //截取DB45.DW2.D2.0~DB45.DW2.D2.13位,其它位屏蔽
  DW1_array:=IntToArray(DW1_current);
  DW2_array:=IntToArray(DW2_current);      //将故障变量转换成数组
  DW1_array0:=inttoarray(myinifile.readInteger('fault','dw1',1));
  DW2_array0:=inttoarray(myinifile.readInteger('fault','dw2',1));  //读取上一次故障变量转换成数组
  FaultCount:= myinifile.readInteger('fault','FaultCount',0);
  FaultCount0:=FaultCount;
  Edt_dw1.Text:=inttostr(DW1_current);
  Edt_dw2.Text:=inttostr(DW2_current);
 //****************************************dw1故障位判断*************
  for i:=1 to 5 do
    begin
      if DW1_array[i]-DW1_array0[i]=1 then         //故障发生
        begin
        FaultCount:=FaultCount+1;
        FaultTime1[i]:=now;
        //myinifile.WriteInteger('fault','dw1',DW1_current);
        end
      else if DW1_array[i]-DW1_array0[i]=-1  then             //故障结束
        begin
          FaultCount:=FaultCount-1;
          if  ((now-FaultTime1[i])*24*60)>5 then
          begin
             ADOQueryFault.SQL.Clear;
             ADOQueryFault.SQL.ADD('dtc_cxx_fault_end_s5 :Machine_id,:Fault_id');
             ADOQueryFault.Parameters.ParamByName('Machine_id').Value :=Machine_id;
             ADOQueryFault.Parameters.ParamByName('Fault_id').Value :=i;
             ADOQueryFault.ExecSQL;
          end;
       //上传故障取消信息
        end
     end;
 //****************************************dw2故障位判断*************
  for i:=1 to 14 do
    begin
      if DW2_array[i]-DW2_array0[i]=1 then           //故障发生
        begin
        FaultCount:=FaultCount+1;
        FaultTime2[i]:=now;
                           //上传故障信息
        end
      else if DW2_array[i]-DW2_array0[i]=-1  then         //故障结束
        begin
          FaultCount:=FaultCount-1;
          if  ((now-FaultTime2[i])*24*60)>5 then
          begin
              ADOQueryFault.SQL.Clear;
              ADOQueryFault.SQL.ADD('dtc_cxx_fault_end_s5 :Machine_id,:Fault_id');
              ADOQueryFault.Parameters.ParamByName('Machine_id').Value :=Machine_id;
              ADOQueryFault.Parameters.ParamByName('Fault_id').Value :=i+5;
              ADOQueryFault.ExecSQL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -