zoukankan      html  css  js  c++  java
  • 西门子 S7-1500 PLC,使用手轮控制伺服电机

    西门子 S7-1500 PLC,使用手轮控制伺服电机

    本文描述了一种,1500PLC使用叠加定位的方法,实现手轮操作的方法。

    手轮操作需要的功能

    数控机床等设备上的电子手轮,起源于机械手轮。机械手轮是通过一个圆的摇柄,经过减速箱,带动机床上的滑台进行移动。

    数控机床的进给轴、主轴已经实现了电气化。由伺服电机替代了人力来驱动滑台。相应的,电子手轮也替代了机械手轮作为伺服轴的操作部件。
    ![]

    • 定量进给,根据“倍率”的选择,手轮每摇一格,滑台移动一个增量。
    • 快速响应,机床(设备)操作者在摇动手轮时,不能有明显的之后。
    • 立即停止,摇动停止后,滑台立刻停止运动。
    • 平稳,电子手轮每圈分辨率为100,分辨率不高,并且人的操作有微观的抖动,但滑台的运动需要相对平稳。

    1500PLC可以将伺服电机配置为轴工艺对象,可以将手轮配置为编码器工艺对象。然而,1500PLC支持相对齿轮同步。看似我们可以使用齿轮同步方式来使用手轮,然而配置时发现,编码器不能作为同步运动的主轴。

    如果希望使用编码器作为主轴,需要选择1500T PLC,价格会更贵一些。

    手轮和PLC,SIMOTION 的硬件连接方式

    方式1

    手轮连接到驱动侧,使用SMC30编码器接口模块连接
    手轮作为驱动DO(Drive object),驱动和PLC(或simotion)之间通过81报文通讯,PLC侧建立编码器(TO)工艺对象
    参考:《simotion 使用齿轮同步方式连接手轮》

    方式2

    手持型触摸屏MP277/MP377等上的电子手轮,手轮信号是两个byte的整数信号,通过PROFINET通讯方式连接到PLC/SIMOTION。可以通过累加计数方式控制伺服电机,也可以通过建立工艺对象,并将工艺对象
    参考:《将变量值写入simotion encoder位置》
    http://www.cnblogs.com/lion-zheng/p/7657811.html

    方式3

    手轮连接到PLC的位置输入模块上,例如TM PosInput 2, 6ES7551-1AB00-0AB0
    PLC(或simotion)和位置输入模块之间通过81报文通讯,PLC侧建立编码器工艺对象

    控制思路

    本文讲的是方式3的配置和调试方法
    ,由于1500PLC不支持轴和编码器之间齿轮同步,我选择使用 叠加定位 的进行控制。

    1. 按照100ms周期执行程序
    2. 判断编码器位置是否发生改变,如果发生改变,进行增量定位
    3. 读取增量定位的余程(distance-to-go),本周期定位长度 = 余程 + 编码器增量
    4. 如果手轮位置没有改变,stop计数器加1
    5. stop计数器值大于阈值(2),轴执行stop指令
    6. 程序中的加速度为固定值,速度和倍率开关 X1 X10 X100 的位置相关

    函数接口和调用方式

    1)程序接口

    因为是一个近似定位功能,我把程序块(Function_block)的名字叫做stupid_handwheel

    name datatype function
    handwheel_position lreal encoder position
    TO_Axis TO_PositioningAxis Axis tech object
    enable BOOL 手轮功能使能
    cycle_trig BOOL 周期信号
    X1 BOOL 手轮倍率 X1
    X10 BOOL 手轮倍率 X10
    X100 BOOL 手轮倍率 X100

    2)调用方式

    手轮控制轴运行时的特性

    图中可以看到,定位过程中,速度被限制为10mm/s,轴的运行比较平稳。

    词汇

    PLC -------------Programmable Logic Controller 可编程逻辑控制器
    S7-1500 --------西门子在21世纪推出的中高端PLC,是S7-300/400的升级产品
    DO ---------------Drive object S120驱动内部的对象

    source code

    stupid_handwheel 程序块的源程序

    FUNCTION_BLOCK "Stupid_handwheel"
    { S7_Optimized_Access := 'TRUE' }
    VERSION : 0.1
    //count handwheel numbers, and pos relative
       VAR_INPUT 
          handwheel_position : LReal;
          TO_Axis {OriginalPartName := 'TO_PositioningAxis'; LibVersion := '3.0'} : TO_PositioningAxis;
          enable : Bool;
          cycle_trig : Bool;
          X1 : Bool;
          X10 : Bool;
          X100 : Bool;
       END_VAR
    
       VAR 
          cycle_TRIG_Instance {OriginalPartName := 'R_TRIG_1500'; LibVersion := '1.0'} : R_TRIG;
          cycle_TrigQ : Bool;
          handwheel_position_old : LReal;
          diff : LReal;
          DistanceToGo : LReal;
          MC_MOVERELATIVE_Instance {OriginalPartName := 'MC_MOVERELATIVE'; LibVersion := '3.0'} : MC_MOVERELATIVE;
          MC_HALT_Instance {OriginalPartName := 'MC_HALT'; LibVersion := '3.0'} : MC_HALT;
          Pos_CMD : Bool;
          Pos_CMD_ID : Int;
          Stop_CMD : Bool;
          Pos_Velocity : LReal;
          Pos_Distance : LReal;
          Pos_Acc : LReal;
          Pos_Jerk : LReal;
          Length_Factor : LReal;
          PosTon {OriginalPartName := 'IEC_TIMER'; LibVersion := '1.0'} : TON_TIME;
          StopTon {OriginalPartName := 'IEC_TIMER'; LibVersion := '1.0'} : TON_TIME;
          StopCycleCounter : Int;
       END_VAR
    
    
    BEGIN
    	#cycle_TRIG_Instance(CLK:=#cycle_trig);
    	
    	IF #X1 THEN
    	    #Length_Factor := 0.001;
    	    #Pos_Velocity := 1;
    	ELSIF #X10 THEN
    	    #Length_Factor := 0.01;
    	    #Pos_Velocity := 2;
    	ELSIF #X100 THEN
    	    #Length_Factor := 0.1;
    	    #Pos_Velocity := 10;
    	END_IF;
    	    
    	
    	IF #cycle_TRIG_Instance.Q THEN
    	    //position difference in one cycle
    	    #diff := #handwheel_position - #handwheel_position_old;
    	    #handwheel_position_old := #handwheel_position;
    	    IF #diff > 50 THEN
    	        #diff := #diff - 100;
    	    END_IF;
    	    
    	    IF #diff < -50 THEN
    	        #diff := #diff + 100;
    	    END_IF;
    	    
    	    //Distance to go
    	    IF #TO_Axis.StatusPositioning.TargetPosition > #TO_Axis.Position THEN
    	        #DistanceToGo := #TO_Axis.StatusPositioning.Distance;
    	    ELSE
    	        #DistanceToGo := -#TO_Axis.StatusPositioning.Distance;;
    	    END_IF;
    	    
    	    //New command length
    	    IF ABS(#diff) > 0.5 AND #enable THEN
    	        #Pos_Distance := #diff * #Length_Factor + #DistanceToGo;
    	        #Pos_CMD := true;
    	        #Pos_CMD_ID := 99;
    	    END_IF;
    	    
    	    //stop cmd
    	    IF ABS(#diff) < 0.5 AND #Pos_CMD_ID = 99 THEN
    	        #StopCycleCounter := #StopCycleCounter + 1;
    	    END_IF;
    	    
    	    IF #StopCycleCounter > 1 THEN
    	        #Stop_CMD := TRUE;
    	        #Pos_CMD_ID := 0;
    	        #StopCycleCounter := 0;
    	    END_IF;
    	END_IF;
    	
    	//IF #TO_Axis
    	#MC_MOVERELATIVE_Instance(Axis := #TO_Axis,
    	                          Execute := #Pos_CMD,
    	                          Distance := #Pos_Distance,
    	                          Velocity := #Pos_Velocity,
    	                          Acceleration := 500,
    	                          Deceleration := 500,
    	                          Jerk := 8000.0);
    	
    	IF #MC_MOVERELATIVE_Instance.Done THEN
    	    #Pos_CMD_ID := 0;
    	END_IF;
    	
    	#MC_HALT_Instance(Axis:=#TO_Axis,
    	                  Execute:=#Stop_CMD,
    	                  Deceleration:= 500,
    	                  Jerk:= 10000,
    	                  AbortAcceleration:= TRUE);
    	
    	//reset pos CMD
    	#PosTon(IN:=#Pos_CMD,PT:=t#30ms);
    	IF #PosTon.Q THEN
    	    #Pos_CMD := FALSE;
    	END_IF;
    	//reset stop CMD
    	#StopTon(IN:=#Stop_CMD,PT:=t#30ms);
    	IF #StopTon.Q THEN
    	    #Stop_CMD := FALSE;
    	END_IF;
    	
    	
    END_FUNCTION_BLOCK
    
    
  • 相关阅读:
    imx6------watchdog导致不进系统
    嵌入式 Linux 如何操作 GPIO ?
    Linux下用文件IO的方式操作GPIO(/sys/class/gpio)
    一张图看懂AI、机器学习和深度学习的区别
    男生拍照姿势大全,这样拍才帅
    OpenCV/OpenCL/OpenGL区别
    设计简单算法体验Vivado HLS的使用
    FMC简介
    Android 开机Process xxx (pid xxxx) has died问题分析
    g711u与g729比较编码格式
  • 原文地址:https://www.cnblogs.com/lion-zheng/p/7847957.html
Copyright © 2011-2022 走看看