V90通过EPOS位置控制

硬件组态

  • 选择西门子报文111

V-ASSISTANT的设置

  • 选择EPOS
  • 选111报文
  • 设置IP
  • 设置减速比
  • 设置限位及原点传感器
  • 设置控制字以启用输入输出
  • 设置回零参数
  • 电机抱闸设置
  • 在线检查
  • 设置完毕后,自动优化电机
  • 设置点动速度的控制字
  • 电机监控和诊断状态字
  • 参数保存后需重启驱动器才能生效。
  • LU单位和长度的对应关系:需要设置正确的齿轮比,以及设置负载转动一圈物体移动距离所对应的长度单位(LU)。如果定义1LU对应0.001mm,负载转动一圈移动10mm,则此时负载转动一圈对应的长度单位为10000LU。

程序设置

  • FB284的使用
#FB_SINA_POS_Instance(ModePos := #Servo.ModePos,//2绝对定位 4回零 7点动
                      EnableAxis := #Servo.EnableAxis,//使能
                      CancelTraversing := #Servo.CancelTraversing,//0 = 拒绝激活的运行任务 1 = 不拒绝(停止)
                      IntermediateStop := #Servo.IntermediateStop,//中间停止:0 = 中间停止运行任务 1 = 不停止(急停)
                      Positive := #Servo.Positive,//正方向
                      Negative := #Servo.Negative,//负方向#Servo.Negative
                      Jog1 := #Servo.Jog1,
                      Jog2 := #Servo.Jog2,
                      FlyRef := #Servo.FlyRef,//不选择运动中回零
                      AckError := #Servo.AckError OR #In_Mode.Reset,//故障复位
                      ExecuteMode := #Servo.ExecuteMode,
                      Position := #Servo.Position,
                      Velocity := #Servo.Velocity,
                      OverV := #Servo.OverV,//加速度
                      OverAcc := #Servo.OverAcc,//加速倍率
                      OverDec := #Servo.OverDec,//减速倍率
                      ConfigEPos := #Servo.ConfigEPos,//EPOS配置值
                      HWIDSTW := #Servo.HWIDSTW,//硬件标识符
                      HWIDZSW := #Servo.HWIDZSW,//硬件标识符
                      Error => #Servo.Error,//驱动故障
                      Status => #Servo.Status,//状态显示
                      DiagID => #Servo.DiagID,//扩展的通讯故障
                      AxisEnabled => #Servo.AxisEnabled,//驱动已使能
                      AxisError => #Servo.AxisError,
                      AxisWarn => #Servo.AxisWarn,
                      AxisPosOk => #Servo.AxisPosOk,
                      AxisRef => #Servo.AxisRef,//驱动器已回零
                      ActVelocity => #Servo.ActVelocity,
                      ActPosition => #Servo.ActPosition,
                      ActMode => #Servo.ActMode,//当前运行模式
                      Lockout => #Servo.Lockout,
                      EPosZSW1 => #Servo.EPosZSW1,//状态字
                      EPosZSW2 => #Servo.EPosZSW2,//状态字
                      ActWarn => #Servo.ActWarn,//当前报警代码
                      ActFault => #Servo.ActFault);//当前故障代码
//正负限位及原点
        //伺服位置反馈,无硬限位时的反馈逻辑
        IF #In_Home_HWLimitActive THEN
            #Status.Home_Done := #Servo.AxisRef;
            #Status.LM_Zero := #FB_SINA_POS_Instance.sxRecvBuf.Reserve.%X2;//原点
            #Status.LM_Postive := #FB_SINA_POS_Instance.sxRecvBuf.Reserve.%X0;//正限位
            #Status.LM_Negative := #FB_SINA_POS_Instance.sxRecvBuf.Reserve.%X1;//负限位
            //没有软限位及零点的时候需要考虑逻辑上设计软零位
        ELSIF NOT #In_Home_HWLimitActive THEN
            #Status.Home_Done := #Servo.AxisRef;
            #Status.LM_Zero := #FB_SINA_POS_Instance.sxRecvBuf.Reserve.%X2; //原点
            #Status.LM_Postive := TRUE;//正限位
            #Status.LM_Negative := TRUE;//负限位
        END_IF;
//回原点时的手动处理
    //ConfigEPos:bit0=OFF2自由停车 bit1=OFF3紧急停车 bit2=软限位开关激活
    //bit3=停止挡块激活 bit6=参考点挡块生效
    IF 4 = #Servo.ModePos AND #In_Home_HWLimitActive THEN
        #Servo.ConfigEPos := 16#3;//0011
    ELSIF 4 = #Servo.ModePos AND NOT #In_Home_HWLimitActive THEN
        #Servo.ConfigEPos := 16#3; (* 16#47;//0100 0111 *)
    END_IF;

    IF  #In_Home_HWLimitActive THEN
        #Servo.ConfigEPos := 16#B;//1011,硬限位激活
    ELSIF NOT #In_Home_HWLimitActive THEN
        #Servo.ConfigEPos := 16#7;//0111,软限位激活
    END_IF;
//想要获取报文内容的方法
// 读取伺服驱动器里面的数据12word,填硬件标识符,和284一致;输出用长度12个字的数组
#Tp_piRetSFC := DPRD_DAT(LADDR := #In_HW_ID, RECORD => #Tp_swRecvBuf);
#St_swDiagID := INT_TO_WORD(#Tp_piRetSFC);
//修改FB38002(Easy_SINA_Pos)作为修改回原点逻辑基础
//FB38002FB284的功能简化版,比FB284功能少,但是使用更加简单。-->此处用来手动修改回原点逻辑(不是一定要用FB38002才行,用FB284也能回原点)
(*
St_sxSendBuf	Struct	
STW1	Word	16#043e
EPosSTW1	Word	16#0
EPosSTW2	Word	16#0
STW2	Word	16#0
OverrideV	Word	16#4000
Position	DInt	0
Velocity	DInt	0
OverrideA	Word	16#4000
OverrideD	Word	16#4000
Reserve	Word	16#0

St_sxRecvBuf	Struct	
ZSW1	Word	16#0
EPosZSW1	Word	16#0
EPosZSW2	Word	16#0
ZSW2	Word	16#0
MELDW	Word	16#0
Position	DInt	0
Velocity	DInt	0
ErrNr	Word	16#0
WarnNr	Word	16#0
Reserve	Word	16#0
*)


#St_P_clear(CLK := NOT #In_Execute);
IF #St_P_clear.Q THEN
    #St_sbJog1 := false;
    #St_sbJog2 := FALSE;
    #St_sbJogToRef := FALSE;
    #St_sbRefCamFallingFlag := false;
    #St_sbModeFlag := false;
    #St_sbExecute := false;
    #St_sbOff1 := 1;
    #St_ST_STEP := 0;
    #Out_Error := false; 
    RESET_TIMER(#time);
END_IF;

// 读取伺服驱动器里面的数据12word
#Tp_piRetSFC := DPRD_DAT(LADDR := #In_HW_ID, RECORD => #Tp_swRecvBuf);
#St_swDiagID := INT_TO_WORD(#Tp_piRetSFC);


//check the receiving communication error
/在软限位激活的情况下强制把物理正负限位置1
IF #Tp_piRetSFC <> 0 AND #Out_Error = false THEN
    #Out_Error := true;
    #Out_ErrorInfo := #St_swDiagID;
ELSE
    IF TRUE = #In_HWLimitActive THEN
        #St_sxRecvBuf.Reserve := #Tp_swRecvBuf[11];///DI状态
        
    ELSE
        #St_sxRecvBuf.Reserve.%X0 := TRUE;//正限位
        #St_sxRecvBuf.Reserve.%X1 := TRUE;//负限位
        //零位
        #St_sxRecvBuf.Reserve.%X2 := #Tp_swRecvBuf[11].%X2;
    END_IF;
    #St_sxRecvBuf.EPosZSW1 := #Tp_swRecvBuf[1];////正负限位原点Jog信息
    #St_sxRecvBuf.ZSW1 := #Tp_swRecvBuf[0];///其他信息
    #St_sxRecvBuf.Position.%W1 := #Tp_swRecvBuf[5]; //位置实际值
    #St_sxRecvBuf.Position.%W0 := #Tp_swRecvBuf[6];///位置实际值
    #St_sxRecvBuf.Velocity.%W1 := #Tp_swRecvBuf[7];///速度实际值
    #St_sxRecvBuf.Velocity.%W0 := #Tp_swRecvBuf[8];///速度实际值
    #St_sbRefOk := #St_sxRecvBuf.ZSW1.%X11;///已设置参考点
    #St_sbCWLActive := #St_sxRecvBuf.EPosZSW1.%X9;///正向停止挡块生效
    #St_sbCCWLActive := #St_sxRecvBuf.EPosZSW1.%X8;///负向停止挡块生效
    #St_sbDriveFault := #St_sxRecvBuf.ZSW1.%X3;///存在故障
    #St_sbDriveReady := #St_sxRecvBuf.ZSW1.%X0;//准备接通信号
    #St_sbDriveEnabled := #St_sxRecvBuf.ZSW1.%X2; //使能信号
    #St_sbJogEnabled := #St_sxRecvBuf.EPosZSW1.%X10;////JOG生效
    CASE #St_ST_STEP OF
        0:
            //#St_sbExecuteFlag := FALSE;
            #St_sbSetREF := false;
            #St_sbHWLimitActive := #In_HWLimitActive;
            #St_sbRefDir := #In_RefDir;
            IF #St_sxRecvBuf.Reserve.%X0 = TRUE AND #St_sxRecvBuf.Reserve.%X1 = TRUE AND #In_Execute THEN//X0表示正限位 X1表示负限位  X2表示原点
                #St_ST_STEP := 1;
            ELSE
                #St_sbJog1 := false;
                #St_sbJog2 := FALSE;
                #St_sbJogToRef := FALSE;
                #St_sbRefCamFallingFlag := false;
                #St_sbModeFlag := false;
                #St_sbExecute := false;
            END_IF;
        1:
            IF #St_sbModeFlag = false AND  #St_sxRecvBuf.Reserve.%X0 = TRUE AND #St_sxRecvBuf.Reserve.%X1 = TRUE  THEN
                #St_sbExecute := true; //开始回参考点信号
            END_IF;
            
            IF #In_RefCamPin = 1 THEN
                #St_sbRefCam := #St_sxRecvBuf.Reserve.%X2;
            ELSIF #In_RefCamPin = 2 THEN
                #St_sbRefCam := #St_sxRecvBuf.Reserve.%X1;
            ELSIF #In_RefCamPin = 3 THEN
                #St_sbRefCam := #St_sxRecvBuf.Reserve.%X2;
            ELSIF #In_RefCamPin = 4 THEN
                #St_sbRefCam := #St_sxRecvBuf.Reserve.%X3;
            ELSE
                #St_sbRefCam := false;
            END_IF;
            
            IF #St_sbModeFlag = FALSE AND (#St_sxRecvBuf.Reserve.%X0 = FALSE OR #St_sxRecvBuf.Reserve.%X1 = FALSE) THEN//修改20200731
                #St_sbExecute := false;
                #St_sbOff1 := false;
                #St_T_Delay(IN := NOT #St_sbOff1,
                            PT := T#200MS);
                IF #St_T_Delay.Q THEN
                     #St_sbHWLimitActive := FALSE;
                    
                    #St_sbAckError := true;
                    #time(IN := #St_sbAckError AND NOT #St_sbDriveFault,
                          PT := t#100ms);
                    IF #time.Q THEN
                        #St_sbModeFlag := true;
                    END_IF;
                END_IF;
                
            END_IF;
            IF #St_sbModeFlag = true THEN
                IF #St_sbDriveFault = false THEN
                    #St_sbAckError := false;
                    #St_sbOff1 := true;//使能
                END_IF;
                IF #St_sxRecvBuf.Reserve.%X0 = FALSE AND #St_sbDriveEnabled = true AND   #St_sbOff1 THEN//修改20200731
                // IF #St_sxRecvBuf.Reserve.%X0 = FALSE THEN
                    #St_sbJog1 := TRUE;
                    #St_sbJog2 := FALSE;
                END_IF;
                IF #St_sxRecvBuf.Reserve.%X1 = FALSE AND #St_sbDriveEnabled = true AND   #St_sbOff1  THEN//修改20200731
                // IF #St_sxRecvBuf.Reserve.%X1 = FALSE  THEN
                    #St_sbJog1 := FALSE;
                    #St_sbJog2 := true;
                END_IF;
                #St_sbRefCamFalling(CLK := #St_sbRefCam,
                                    Q => #St_sbRefCamFallingFlag);
                IF #St_sbJogToRef = true AND #St_sbJogEnabled = false THEN
                    #St_sbJogToRef := false;
                    #St_sbExecute := true;
                END_IF;
                IF #St_sbRefCamFallingFlag = true THEN
                    #St_sbJog1 := false;
                    #St_sbJog2 := FALSE;
                    #St_sbJogToRef := true;//已JOG至原点标志
                    #St_sbRefCamFallingFlag := false;
                END_IF;
            END_IF;
            IF #St_sbRefOk = true OR #In_Execute = false THEN
                // #St_sbHWLimitActive := TRUE;
                #St_sbModeFlag := false;
            END_IF;
    END_CASE;
END_IF;

//输出给V90信号
//Send data
#St_sxSendBuf.STW1.%X0 := #St_sbOff1 AND #In_EnableAxis;///使能
#St_sxSendBuf.STW1.%X7 := #St_sbAckError OR #In_AckError ;//应答故障
#St_sxSendBuf.STW1.%X8 := #St_sbJog1;///jog1信号
#St_sxSendBuf.STW1.%X9 := #St_sbJog2;///Jog2信号 
#St_sxSendBuf.STW1.%X11 := #St_sbExecute AND #In_Execute;///开始回参考点
#St_sxSendBuf.EPosSTW2.%X1 := #St_sbSetREF;///设置参考点
#St_sxSendBuf.EPosSTW2.%X2 := #St_sbRefCam;///参考点档位生效
#St_sxSendBuf.EPosSTW2.%X9 := #St_sbRefDir;////1=开始反向搜索参考点 0=开始正向搜索参考点
#St_sxSendBuf.EPosSTW2.%X14 := (NOT #In_HWLimitActive);//激活软限位开关
#St_sxSendBuf.EPosSTW2.%X15 :=  #St_sbHWLimitActive AND #In_HWLimitActive; ///1=停止挡块生效

#Tp_swSendBuf[0] := #St_sxSendBuf.STW1;
#Tp_swSendBuf[1] := #St_sxSendBuf.EPosSTW1;
#Tp_swSendBuf[2] := #St_sxSendBuf.EPosSTW2;
#Tp_swSendBuf[3] := #St_sxSendBuf.STW2;
#Tp_swSendBuf[4] := #St_sxSendBuf.OverrideV;
#Tp_swSendBuf[5] := #St_sxSendBuf.Position.%W1;
#Tp_swSendBuf[6] := #St_sxSendBuf.Position.%W0;
#Tp_swSendBuf[7] := #St_sxSendBuf.Velocity.%W1;
#Tp_swSendBuf[8] := #St_sxSendBuf.Velocity.%W0;
#Tp_swSendBuf[9] := #St_sxSendBuf.OverrideA;
#Tp_swSendBuf[10] := #St_sxSendBuf.OverrideD;
#Tp_swSendBuf[11] := #St_sxSendBuf.Reserve;
//send the command to the drive
IF #Out_Error = false THEN
    #Tp_piRetSFC := DPWR_DAT(LADDR := #In_HW_ID, RECORD := #Tp_swSendBuf);
    #St_swDiagID := INT_TO_WORD(#Tp_piRetSFC);
END_IF;

IF #Tp_piRetSFC <> 0 AND #Out_Error = false THEN
    #Out_Error := true;
    #Out_ErrorInfo := #St_swDiagID;
END_IF;
#Out_RefOK := #St_sbRefOk;
#Out_Zero := #St_sxRecvBuf.Reserve.%X2;
#Out_Postive := #St_sxRecvBuf.Reserve.%X0;
#Out_Negative := #St_sxRecvBuf.Reserve.%X1;
///注意1: 在触发回原点信号的时候要先保证 轴已经使能 而且没有点动信号
///注意2: 在模式选择为4的时候才可以触发回原点指令 在模式选择不为4的时候触发FB284
///注意3: 在触发回原点的时候  用沿触发来把模式选择进行调整 同时复位回原点信号
///注意4: 需要在此块外面 再加上别的一些程序进行处理

关于FB284,常遇到的一些问题汇总

posted @   不愿透露姓名的小村村  阅读(51)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示