[汇川] 汇川PLC-EtherCAT通讯方式多轴程序封装

[复制链接]
查看57686 | 回复0 | 2025-3-26 08:10:36 | 显示全部楼层 |阅读模式
‖ 系统学习

人生就像一场马拉松,偶尔停下来摸摸鱼,才能走得更远

近期工控PLC项目居多,所以接下更新内容大多数是关于工控PLC内容。所有程序知识由项目组成员“糖芦卢”提供晓煜做整理和讲解,不足之处欢迎指出。


上期我们说了一个信捷PLC简单的多轴封装FB程序,本期我们来说说汇川PLC的多轴封装FB块。我们这边是用了中型PLC AC800做演试,使用了ST语言做为程序的主体,汇川这几年也是相继的使用ST语言居多,所以就不用梯形图了。注:本期内容需要懂ST语言人员,不然看起来很蒙

本期设备:PLC为AC801,伺服驱动器为:InoSV630N。使用的软件:InoProShop(V1.9.0.1)

指令问题
我们使用单轴驱动指令,至于怎么使用大家可以在汇川官网下载《中型PLC编程手册(运动控制篇)》手册里面详细介绍了指令的使用方式

    Power        :MC_Power;//使能
    Home        :MC_Home;//回原点
    Reset         :MC_Reset;//重置轴
    Stop          :MC_Stop;//轴停止
    Halt          :MC_Halt;//立即停止轴
    JOG          :MC_Jog;//点动
   
    MoveA       :MC_MoveAbsolute;//绝对位置
    MoveR       :MC_MoveRelative;//相对位置
    SetPosition :MC_SetPosition;//设定当前轴位置
    PersistPosition1:SMC3_PersistPosition;//该指令用来保持记录实轴绝对值编码器的位置(断电重启控制器后,恢复断电前位置记录值)
    ReadParameter  :MC_ReadParameter;//读取轴的状态
MC指令才是我们的指令我只是给它实例化了,这些就是我们常用的轴控指令

EtherCAT通讯配置
外我们使用EtherCAT通讯时需要进行组网,添加相对应的PLC和伺服。



这样我们就添加好了对应的伺服驱动器和PLC,我们在底部可以看到Axis为我这个伺服电机的轴名称,点击它可以看到相对应的设置,这里没什么复杂的,字面意思理解就可以了,这边不多缀述


封装FB块
我们在PLC逻辑Application处右键点击添加结




输入我们结构体名称,比如我这边的命名:St_Axis_Date

我们把一个轴需要用的变量用写进去,这样我们就不需要一个一个重建了。



创建FB

我们在PLC逻辑Application处右键点击添加FB块(程序组织单元)选择FB块就可以民



创建好后,我们需要给MC指令实例化,我这边命名如下:
VAR_OUTPUT
END_VAR

VAR_IN_OUT
    St_AXIS  :St_Axis_Date;  //调用结构体
    PersistPosition_Data :SMC3_PersistPosition_Data;//断电保存寄器
   
END_VAR

VAR
    Power       :MC_Power;//使能
    Home        :MC_Home;//回原点
    Reset       :MC_Reset;//重置轴
    Stop        :MC_Stop;//轴停止
    Halt        :MC_Halt;//立即停止轴
    JOG         :MC_Jog;//点动
   
    MoveA       :MC_MoveAbsolute;//绝对位置
    MoveR       :MC_MoveRelative;//相对位置
    SetPosition :MC_SetPosition;//设定当前轴位置
    PersistPosition1:SMC3_PersistPosition;//该指令用来保持记录实轴绝对值编码器的位置(断电重启控制器后,恢复断电前位置记录值)
    ReadParameter  :MC_ReadParameter;//读取轴的状态
    ReinitDrive     :SMC3_ReinitDrive;
   
END_VAR


FB程序

//=================使能=========================
Power(
    Axis := St_AXIS.Axis^,     //轴名字指针
    Enable  := TRUE,
    bRegulatorOn:= St_AXIS.i_Power,     //开关
    bDriveStart := St_AXIS.i_Power,
    Status  => ,
    bRegulatorRealState => ,
    bDriveStartRealState=> ,
    Busy    => ,
    Error   => ,
    ErrorID => );//=================回原=========================
Home(
    Axis:= St_AXIS.Axis^,
    Execute:=St_AXIS.i_Home,
    Position:= 0,
    Done=> ,
    Busy=> ,
    CommandAborted=> ,
    Error=> ,
    ErrorID=> );//=================重置轴=========================
    Reset(Axis:= St_AXIS.Axis^,
        Execute:= St_AXIS.i_Reset,
        Done=> ,
        Busy=> ,
        Error=> ,
        ErrorID=> );
        //=================停止=========================         
    Stop(
        Axis:= St_AXIS.Axis^,
        Execute:= St_AXIS.i_Stop,
        Deceleration:= 500,
        Jerk:= 5000,
        Done=> ,
        Busy=> ,
        Error=> ,
        ErrorID=> );//=================立即停止轴=========================         
    Halt(
        Axis:= St_AXIS.Axis^,
        Execute:= St_AXIS.i_Halt,
        Deceleration:= 1000,
        Jerk:= ,
        Done=> ,
        Busy=> ,
        CommandAborted=> ,
        Error=> ,
        ErrorID=> );    //=================绝对位置=========================           
    MoveA(
        Axis:= St_AXIS.Axis^,
        Execute:= St_AXIS.i_MoveAbs,
        Position:= St_AXIS.i_Abs_pos,
        Velocity:= St_AXIS.i_Abs_Vel,
        Acceleration:= St_AXIS.i_ACC,
        Deceleration:= St_AXIS.i_Dec,
        Jerk:= ,
        Direction:= ,
        BufferMode:= ,
        Done=> ,
        Busy=> ,
        Active=> ,
        CommandAborted=> ,
        Error=> ,
        ErrorID=> );    //=================相对位置=========================      
    MoveR(
        Axis:= St_AXIS.Axis^,
        Execute:= St_AXIS.i_MoveRel,
        Distance:= St_AXIS.i_Abs_pos,
        Velocity:= St_AXIS.i_Abs_Vel,
        Acceleration:= St_AXIS.i_ACC,
        Deceleration:= St_AXIS.i_Dec,
        Jerk:= ,
        BufferMode:= ,
        Done=> ,
        Busy=> ,
        Active=> ,
        CommandAborted=> ,
        Error=> ,
        ErrorID=> );//=================设定当前轴位置为0========================           
    SetPosition(
        Axis:= St_AXIS.Axis^,
        Execute:= St_AXIS.i_set_pos,
        Position:= 0, //可以使用变量,这边是直接设置为0
        Mode:= ,
        Done=> ,
        Busy=> ,
        Error=> ,
        ErrorID=> );      
//=================断电保存编码器值========================        
    PersistPosition1(
        Axis:= St_AXIS.Axis^,
        PersistentData:= PersistPosition_Data,
        bEnable:= FALSE,    //TRUE 功能块执行,FALSE 不执行功能块若要在初始化期间还原上次存储的位置,则必须从应用程序启动时将该值置为TRUE
        bPositionRestored=> ,
        bPositionStored=> ,
        bBusy=> ,
        bError=> ,
        eErrorID=> ,
        eRestoringDiag=> ); //=================点动========================  
JOG(
    Axis:= St_AXIS.Axis^,
    JogForward:= St_AXIS.i_JOG_FWD,
    JogBackward:= St_AXIS.i_JOG_REV,
    Velocity:= St_AXIS.i_JOG_Vel,
    Acceleration:= St_AXIS.i_ACC,
    Deceleration:= St_AXIS.i_Dec,
    Jerk:= ,
    Busy=> ,
    CommandAborted=> ,
    Error=> ,
    ErrorId=> );
//=================轴状态========================

St_AXIS.o_fAct_pos := LREAL_TO_REAL(St_AXIS.Axis^.fActPosition);   //显示当前轴位置
St_AXIS.o_fAct_Vel := LREAL_TO_REAL(St_AXIS.Axis^.fActVelocity);   //显示当前轴速度
St_AXIS.o_fAct_Tor := LREAL_TO_REAL(St_AXIS.Axis^.fActTorque);     //显示当前轴扭矩
St_AXIS.o_wCommunicationState := St_AXIS.Axis^.wCommunicationState; //轴通讯状态



使用ST语言编程序时,需要注意的是要定义好程序中的变量,大家可以用到很多的St_AXIS.xxxx的这个是因为我这边把结构体给实例化了,就是一开始我们定义好结构体,使用St_AXIS这个变量代替了我们的结构体,这样我们在输入的时候直接输入St_AXIS.它就会出来。大大节省了我们起变量的时间。


主程序设计
我们需要在PLC逻辑Application处右键点击添加主程序,再把程序拉入到EtherCAT任务周期中,我们的程序才能运行。


程序我们先来配置二个全局变量一个是调用FB块的全局变量,你有多少个轴你就写多大的数组,我边有200个轴,我的数组长度就是200,你有10个轴你的数组长度就是10,当然你也可以和我一个写多一点无所谓的。

我这边还重新闻实例化了结构体,名称为StAxis,这个变量是在EtherCAT使用的,与FB块的那个分开来这样就不会弄混了,当然你也可命个好名,这样也行。



进入主程序优先,配置轴的参数



先配置轴名字才能配置轴FB实例化,不然会报错,实例化前没有说轴名字就会报这个错。这个是要注意的



轴数量判断我这边是用了for循环判断的,这个To 5大家可以用变量代替代,我边做例子就写死了判断是不是有5个轴,如果是就正常加1。

if语句中的100是EtherCAT通讯正常的输出标志

1000是错误标志



总结
本期内容说的有点急了,大家可能不太理解,因为这个中型PLC会使用的一说就很清楚,如果没用过的需要去看一下操作手册和视频,这不是一篇文章就能看明白的,本期的主要目的还是和上期一样分享程序逻辑,和一些注意事项。需要有一定的基础才行。不足之处欢迎大家指出程序有需要的可以自取:
网盘下载:https://pan.quark.cn/s/07f4b58e95e5
本地下载:












本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册哦

x
您需要登录后才可以回帖 登录 | 注册哦

本版积分规则