PLC, HMI, SCADA, INVERTERS, TUTORIALS, INDUSTRIAL AUTOMATION

21:10
SCL SINA_POS FB284 S7-1200/S7-1500 TIA V19 V1.2 2024-09-01 CaiMiao

TYPE "St_SetAxisData_Epos"
VERSION : 0.1
   STRUCT
      原点 : Bool;
      额定转速 : DInt;
      最大转速 : DInt;
      最大位置 : Real;
      最小位置 : Real;
      回原模式 : Int;
      激活软限位 : Bool;
      激活硬限位 : Bool;
      每一圈多少lu : DInt;
      伺服每转位移 : Real;
      设备标识符 : HW_IO;
   END_STRUCT;

END_TYPE

TYPE "St_AxisIn_Epos"
VERSION : 0.1
   STRUCT
      i_xPowerOn : Bool;   // 轴使能
      i_xHome : Bool;   // 轴回原
      i_xJogP : Bool;   // 轴正向点动
      i_xJogN : Bool;   // 轴反向点动
      i_xAbsGo : Bool;   // 轴绝对定位触发
      i_xReset : Bool;   // 轴复位
      i_xStop : Bool;   // 轴停止
      i_xHalt : Bool;   // 轴暂停
      i_fJogVel : Real;   // 轴点动速度
      i_fAbsPos : Real;   // 轴绝对定位位置
      i_fAbsVel : Real;   // 轴绝对定位速度
      i_fRunAcc : Int := 100;   // 轴运行加速度(绝对定位、相对定位、速度模式等)
      i_fRunDec : Int := 100;   // 轴运行减速度(绝对定位、相对定位、速度模式等)
   END_STRUCT;

END_TYPE

TYPE "St_AxisOut_Epos"
VERSION : 0.1
   STRUCT
      o_iActMode : Int;   // 当前模式
      o_xPowerDone : Bool;   // 使能完成
      o_xAbsDone : Bool;   // 绝对定位完成
      o_xHomeFind : Bool;   // 原点有效信号
      o_xStandstill : Bool;
      o_xLimitP : Bool;   // 轴正限位
      o_xLimitN : Bool;   // 轴负限位
      o_rActPosition : Real;   // 当前位置
      o_rActVelocity : Real;   // 当前速度
      o_axGetActPos : Array[0..19] of Bool;   // 当前到达的位置点
      o_wsStatus : WString[15];
      o_xAxisError : Bool;   // 轴错误
      o_xError : Bool;   // 块错误
      o_xErrorID : Word;   // 错误代号
   END_STRUCT;

END_TYPE

TYPE "St_AxisWorkPosition"
VERSION : 0.1
   STRUCT
      i_fPosition : Real;
      i_fVelocity : Real;
   END_STRUCT;

END_TYPE

TYPE "系统输入"
VERSION : 0.1
   STRUCT
      "手动/自动" : Bool;
      暂停 : Bool;
      停止 : Bool;
      急停 : Bool;
      复位 : Bool;
   END_STRUCT;

END_TYPE

TYPE "St_Axis_Epos"
VERSION : 0.1
   STRUCT
      配置参数 : "St_SetAxisData_Epos";
      in : "St_AxisIn_Epos";
      out : "St_AxisOut_Epos";
      WorkPosition { S7_SetPoint := 'False'} : Array[0..19] of "St_AxisWorkPosition";
   END_STRUCT;

END_TYPE

FUNCTION_BLOCK "FB_Axis_newEpos_ST_2"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT 
      i_stSystemIn : "系统输入";
   END_VAR

   VAR_IN_OUT 
      io_stAxis : "St_Axis_Epos";
   END_VAR

   VAR 
      SinaPos_Instance {InstructionName := 'SinaPos'; LibVersion := '2.1'} : SinaPos;
      绝对定位触发上升沿 {InstructionName := 'R_TRIG'; LibVersion := '1.0'} : R_TRIG;
      步数 : Int;
      点动步数 : Int;
      定位步数 : Int;
      回原步数 : Int;
      正向点动 { S7_SetPoint := 'True'} : Bool;
      反向点动 : Bool;
      停止 : Bool;
      模式 : Int := 7;
      激活模式 : Bool;
      设定位置 : Real;
      设定位置_1 : Real;
      设定速度 : Real;
      设定速度_1 : Real;
      控制字 : DWord;
      定位完成 : Bool;
      当前位置 : Real;
      当前速度 : Real;
      状态字1 : Word;
      状态字2 : Word;
      状态 : Word;
      报警代码 : Word;
      故障代码 : Word;
      设定定位位置不合理 : Bool;
      设定定位速度超过最大转速 : Bool;
      设定点动速度超过最大转速 : Bool;
      Error : Bool;
      需要的圈数 : Real;
      轴就绪 : Bool;
      最大速度 : Real;
   END_VAR

   VAR_TEMP 
      i : Int;
   END_VAR

   VAR CONSTANT 
      判断流程 : Int := 0;
      点动流程 : Int := 10;
      定位流程 : Int := 20;
      回原流程 : Int := 30;
   END_VAR


BEGIN
        //================================================================================
        //库文件:无
        //功能描述:封装FB284
        //硬件平台:S7-1200/S7-1500
        //软件平台:TIA博途V19
        //-----------------------------------------------------------------------------------------------------------------------------------
        //版本记录
        //版本                  日期                       作者
        //V1.2                 2024-09-01          CaiMiao
        //================================================================================
        //说明
        //增加了20个位置点到达的信号判断,方便触摸屏上做位置信号,自动流程中还是只需要判断AxisOut中的AbsDone信号
        //修补了判断最大转速的bug
        //增加了解析控制字与状态字
        //================================================================================
        
        (********************************************************** 输入数据转换 **********************************************************)
        //解析控制字
        #控制字.%X0 := TRUE;
        #控制字.%X1 := TRUE;
        #控制字.%X2 := #io_stAxis.配置参数.激活软限位;
        #控制字.%X3 := #io_stAxis.配置参数.激活硬限位;
        #控制字.%X6 := #io_stAxis.配置参数.原点;
        
        //圈数=伺服每转位移/位移数
        #需要的圈数 := #io_stAxis.in.i_fAbsPos / #io_stAxis.配置参数.伺服每转位移;
        IF ABS(#io_stAxis.配置参数.最小位置 - #io_stAxis.配置参数.最大位置) >= ABS(#io_stAxis.in.i_fAbsPos) THEN
            #设定位置 := (#需要的圈数 * (DINT_TO_REAL(#io_stAxis.配置参数.每一圈多少lu)));
        ELSIF
            #io_stAxis.配置参数.最小位置 = 0 AND #io_stAxis.配置参数.最大位置 = 0
        THEN
            #设定位置 := (#需要的圈数 * (DINT_TO_REAL(#io_stAxis.配置参数.每一圈多少lu)));
        ELSE
            #设定定位位置不合理 := TRUE;
        END_IF;
        //速度=设定速度mm/s*60s
        //#设定速度mm/min=设定速度mm/s*60s
        //设定速度rpm/min=#设定速度mm/min   /     伺服每转位移*10
        #最大速度 := (DINT_TO_REAL(#io_stAxis.配置参数.最大转速) / 60.0 * #io_stAxis.配置参数.伺服每转位移);
        IF #io_stAxis.in.i_xAbsGo THEN
            IF #最大速度 >= #io_stAxis.in.i_fAbsVel THEN
                #设定速度 := ((#io_stAxis.in.i_fAbsVel * 60.0) / #io_stAxis.配置参数.伺服每转位移 * 10.0);
            ELSE
                #设定定位速度超过最大转速 := TRUE;
            END_IF;
        END_IF;
        
        IF (#io_stAxis.in.i_xJogP AND NOT #io_stAxis.in.i_xJogN)
            OR (#io_stAxis.in.i_xJogN AND NOT #io_stAxis.in.i_xJogP)
        THEN
            IF #最大速度 >= #io_stAxis.in.i_fJogVel
            THEN
                #设定速度 := ((#io_stAxis.in.i_fJogVel * 60.0) / #io_stAxis.配置参数.伺服每转位移 * 10.0);
            ELSE
                #设定点动速度超过最大转速 := TRUE;
            END_IF;
        END_IF;
        
        //复位
        IF #io_stAxis.in.i_xReset THEN
            #设定定位位置不合理 := FALSE;
            #设定定位速度超过最大转速 := FALSE;
            #设定点动速度超过最大转速 := FALSE;
        END_IF;
        
        (********************************************************** 点动与绝对定位的流程 **********************************************************)
        #绝对定位触发上升沿(CLK := #io_stAxis.in.i_xAbsGo);
        CASE #步数 OF
            #判断流程://进入点动的条件
                IF (#io_stAxis.in.i_xJogP AND NOT #io_stAxis.in.i_xJogN)
                    OR (#io_stAxis.in.i_xJogN AND NOT #io_stAxis.in.i_xJogP)
                    AND #SinaPos_Instance.AxisEnabled
                    AND #轴就绪
                    AND NOT #i_stSystemIn."手动/自动"
                THEN
                    #模式 := 3;
                    IF #SinaPos_Instance.ActMode = 3 AND #SinaPos_Instance.swStatus = 16#7002 THEN
                        IF (#io_stAxis.in.i_xJogP AND NOT #io_stAxis.in.i_xJogN) THEN
                            #设定速度_1 := #设定速度;
                            #反向点动 := TRUE;
                            #步数 := #点动流程;
                        ELSIF
                            (#io_stAxis.in.i_xJogN AND NOT #io_stAxis.in.i_xJogP) THEN
                            #设定速度_1 := #设定速度;
                            #正向点动 := TRUE;
                            #步数 := #点动流程;
                        END_IF;
                    END_IF;
                END_IF;
                //进入绝对定位条件
                IF #绝对定位触发上升沿.Q
                    AND #轴就绪
                    AND #SinaPos_Instance.AxisEnabled
                    AND #SinaPos_Instance.AxisRef
                THEN
                    #模式 := 2;//有绝对定位信号后,把数据给到sinapos功能块
                    IF #SinaPos_Instance.ActMode = 2 AND #SinaPos_Instance.swStatus = 16#7002 THEN
                        #设定位置_1 := #设定位置;
                        #设定速度_1 := #设定速度;
                        #步数 := #定位流程;
                    END_IF;
                END_IF;
                //进入回原的条件
                IF #io_stAxis.in.i_xHome
                    AND #SinaPos_Instance.AxisEnabled
                    AND #SinaPos_Instance.EPosZSW2 = 0
                    AND NOT #i_stSystemIn."手动/自动"
                THEN
                    #模式 := #io_stAxis.配置参数.回原模式;
                    #步数 := #回原流程;
                END_IF;
            #点动流程://点动自动流程
                CASE #点动步数 OF
                    0:
                        #激活模式 := TRUE;
                        IF NOT #io_stAxis.in.i_xJogP AND NOT #io_stAxis.in.i_xJogN THEN
                            #正向点动 := FALSE;
                            #反向点动 := FALSE;
                            #停止 := TRUE;
                            #激活模式 := FALSE;
                            #点动步数 := 10;
                        END_IF;
                    10:
                        #停止 := FALSE;
                        IF #SinaPos_Instance.AxisPosOk
                            AND #SinaPos_Instance.AxisSpFixed
                            AND #SinaPos_Instance.EPosZSW2 = 0
                        THEN
                            #点动步数 := 0;
                            #步数 := #判断流程;
                        END_IF;
                END_CASE;
            #定位流程://定位自动流程
                CASE #定位步数 OF
                    0:
                        #激活模式 := TRUE;
                        IF NOT #io_stAxis.in.i_xAbsGo OR (ABS(#设定位置_1 - #当前位置) < 1) THEN
                            #激活模式 := FALSE;
                            IF ABS(#设定位置_1 - #当前位置) < 1 THEN
                                #io_stAxis.out.o_xAbsDone := TRUE;
                            END_IF;
                            #定位步数 := 10;
                        END_IF;
                    10:
                        #定位步数 := 0;
                        #步数 := #判断流程;
                END_CASE;
            #回原流程://回原自动流程
                CASE #回原步数 OF
                    0:
                        #激活模式 := TRUE;
                        IF #SinaPos_Instance.AxisRef AND #当前位置 = 0 THEN
                            #激活模式 := FALSE;
                            #回原步数 := 10;
                        END_IF;
                    10:
                        #激活模式 := FALSE;
                        #回原步数 := 0;
                        #步数 := #判断流程;
                END_CASE;
        END_CASE;
        (****************************************************************** 功能块调用************************************************************************)
        #SinaPos_Instance(ModePos := #模式,
                          EnableAxis := #io_stAxis.in.i_xPowerOn,
                          CancelTraversing := NOT #io_stAxis.in.i_xStop AND NOT #停止 AND NOT #i_stSystemIn.停止 AND NOT #i_stSystemIn.急停,
                          IntermediateStop := NOT #io_stAxis.in.i_xHalt AND NOT #i_stSystemIn.暂停,
                          Positive := #正向点动,
                          Negative := #反向点动,
                          AckError := #io_stAxis.in.i_xReset,
                          ExecuteMode := #激活模式,
                          Position := REAL_TO_DINT(#设定位置_1),
                          Velocity := REAL_TO_DINT(#设定速度_1),
                          OverV := 100,
                          OverAcc := #io_stAxis.in.i_fRunAcc,
                          OverDec := #io_stAxis.in.i_fRunDec,
                          ConfigEPos := #控制字,
                          HWIDSTW := #io_stAxis.配置参数.设备标识符,
                          HWIDZSW := #io_stAxis.配置参数.设备标识符,
                          AxisEnabled => #io_stAxis.out.o_xPowerDone,
                          AxisPosOk => #定位完成,
                          AxisRef => #io_stAxis.out.o_xHomeFind,
                          ActVelocity => #当前速度,
                          ActPosition => #当前位置,
                          ActMode => #io_stAxis.out.o_iActMode,
                          EPosZSW1 => #状态字1,
                          EPosZSW2 => #状态字2,
                          ActWarn => #报警代码,
                          ActFault => #故障代码,
                          Error => #Error,
                          Status => #状态);
        
        (***************************************************************************************** 输出数据**************************************************************************************)
        //当前位置=lu的数量*每lu的距离
        #io_stAxis.out.o_rActPosition := ((#当前位置) * #io_stAxis.配置参数.伺服每转位移 / (DINT_TO_REAL(#io_stAxis.配置参数.每一圈多少lu)));
        //当前速度=额定转速*输出转速/1073741824/60s*每转位移
        #io_stAxis.out.o_rActVelocity := (DINT_TO_REAL(#io_stAxis.配置参数.额定转速) * #当前速度 / 1073741824.0) / 60.0 * #io_stAxis.配置参数.伺服每转位移;
        
        (********************************************************** 状态输出**********************************************************)
        CASE #状态 OF
            16#7002:
                #io_stAxis.out.o_wsStatus := WSTRING#'没错误,功能块正在执行';
            16#8401:
                #io_stAxis.out.o_wsStatus := WSTRING#'驱动错误';
            16#8402:
                #io_stAxis.out.o_wsStatus := WSTRING#'驱动禁止启动';
            16#8403:
                #io_stAxis.out.o_wsStatus := WSTRING#'运行中回零不能开始';
            16#8600:
                #io_stAxis.out.o_wsStatus := WSTRING#'DPRD_DAT错误';
            16#8601:
                #io_stAxis.out.o_wsStatus := WSTRING#'DPWR_DAT错误';
            16#8202:
                #io_stAxis.out.o_wsStatus := WSTRING#'不正确的运行模式选择';
            16#8203:
                #io_stAxis.out.o_wsStatus := WSTRING#'不正确的设定值参数';
            16#8204:
                #io_stAxis.out.o_wsStatus := WSTRING#'不正确的程序段号';
        END_CASE;
        
        IF #设定定位位置不合理 THEN
            #io_stAxis.out.o_wsStatus := WSTRING#'设定定位位置不合理';
        ELSIF #设定定位速度超过最大转速 THEN
            #io_stAxis.out.o_wsStatus := WSTRING#'设定定位速度超过最大转速';
        ELSIF #设定点动速度超过最大转速 THEN
            #io_stAxis.out.o_wsStatus := WSTRING#'设定点动速度超过最大转速';
        ELSIF #状态字1.%X9 THEN
            #io_stAxis.out.o_wsStatus := WSTRING#'轴到达正极限';
        ELSIF #状态字1.%X9 THEN
            #io_stAxis.out.o_wsStatus := WSTRING#'轴到达负极限';
        ELSIF #SinaPos_Instance.AxisError
            AND NOT #状态=16#8401
            AND NOT #状态=16#8402
            AND NOT #状态=16#8403
            AND NOT #状态=16#8600
            AND NOT #状态=16#8601
            AND NOT #状态=16#8602
            AND NOT #状态=16#8203
            AND NOT #状态=16#8204
        THEN
            #io_stAxis.out.o_wsStatus := WSTRING#'轴错误';
        ELSIF #轴就绪 THEN
            #io_stAxis.out.o_wsStatus := WSTRING#'轴就绪';
        ELSIF (#状态字2.%X4 OR #状态字2.%X5) AND #SinaPos_Instance.EnableAxis AND NOT #io_stAxis.out.o_xError THEN
            #io_stAxis.out.o_wsStatus := WSTRING#'轴在运动状态';
        END_IF;
        
            //解析状态字
        #io_stAxis.out.o_xStandstill:=  #轴就绪 := (NOT #状态字2.%X4
        AND  NOT #状态字2.%X5
       AND  NOT #io_stAxis.out.o_xError)
        AND #SinaPos_Instance.EnableAxis;
        
        #io_stAxis.out.o_xLimitP := #状态字1.%X9;
        #io_stAxis.out.o_xLimitN := #状态字1.%X8;
        #io_stAxis.out.o_xErrorID := #状态;
        #定位完成 := #SinaPos_Instance.AxisPosOk
        OR #定位完成;
        
        #io_stAxis.out.o_xAxisError := #SinaPos_Instance.AxisError
        OR #SinaPos_Instance.AxisWarn;
        
        #io_stAxis.out.o_xError := #Error
        OR #io_stAxis.out.o_xAxisError
        OR #设定定位位置不合理
        OR #设定定位速度超过最大转速
        OR #设定点动速度超过最大转速;
        
        (********************************************************** 位置到达信号输出**********************************************************)    
        //遍历当前位置大概在哪个工作位置,获取下标
        FOR #i := 0 TO 19 DO
            IF ABS(#io_stAxis.out.o_rActPosition - #io_stAxis.WorkPosition[#i].i_fPosition) < 0.5
                AND NOT #状态字2.%X4
                AND NOT #状态字2.%X5
            THEN
                #io_stAxis.out.o_axGetActPos[#i] := TRUE;
                EXIT;
            END_IF;
        END_FOR;
     
        //当轴再次开始运动时,把所有位置点完成信号都复位
        IF #状态字2.%X4 OR #状态字2.%X5 THEN
            #io_stAxis.out.o_xAbsDone := FALSE;
            FOR #i := 0 TO 19 DO
                #io_stAxis.out.o_axGetActPos[#i] := FALSE;
            END_FOR;
        END_IF;
        
END_FUNCTION_BLOCK

FB_Axis_newEpos_ST_2.scl

Категория: SIEMENS | Просмотров: 82 | Добавил: Admin | Теги: S7-1200, FB284, TIA V19, SCL, S7-1500 | Рейтинг: 0.0/0
Всего комментариев: 0
avatar