西门子 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不支持轴和编码器之间齿轮同步,我选择使用 叠加定位 的进行控制。
- 按照100ms周期执行程序
- 判断编码器位置是否发生改变,如果发生改变,进行增量定位
- 读取增量定位的余程(distance-to-go),本周期定位长度 = 余程 + 编码器增量
- 如果手轮位置没有改变,stop计数器加1
- stop计数器值大于阈值(2),轴执行
stop
指令 - 程序中的加速度为固定值,速度和
倍率开关 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
西门子 S7-1500 PLC,使用手轮控制伺服电机的更多相关文章
- 西门子S7系列PLC的主要种类及应用软件
德国西门子(SIEMENS)公司生产的可编程序控制器在我国的应用也相当广泛,在冶金.化工.印刷生产线等领域都有应用.西门子(SIEMENS)公司的PLC产品包括LOGO,S7-200,S7-300,S ...
- 开源纯C#工控网关+组态软件(三)加入一个新驱动:西门子S7
一. 引子 首先感谢博客园:第一篇文章.第一个开源项目,算是旗开得胜.可以看到,项目大部分流量来自于博客园,码农乐园,名不虚传^^. 园友给了我很多支持,并提出了很好的改进意见.现加入屏幕分辨率自 ...
- 西门子S7系列以太网通讯处理器安装调式操作
北京华科远创科技有限研发的远创智控ETH-YC模块,PLC转以太网型号有MPI-ETH-YC01和MPI-ETH-YC01,适用于西门子S7-200/S7-300/S7-400.SMART S7-20 ...
- (转载)一张表搞清楚西门子S7系列标准DB块与优化DB块
在TIA Portal中为S7-1200/S7-1500 CPU 添加一个 DB 块时,其缺省属性为优化的 DB ,优化的 DB 块与标准的 DB 块整体对比如下表所示: 项 标准 DB 优化 DB ...
- 西门子S7报文解析
1.报文的基本格式 1.1 第1和第2个字节是:固定报文头03 00,这里我们就用到三种报文: a.初始化 b. 读 c.写,都是这种格式: 1.2 第3和第4个字节是:整个报文的长度: 其它部分就是 ...
- 西门子与三菱PLC报文比较
1.西门子和三菱的几个区别(上位只关心的通讯层面):1. 西门子PLC通讯端口固定102,但是可以连接多个PC端(客户端),三菱PLC通讯端口可以自定义,最多好像8个,但是每个端口只能连接一个客户端: ...
- PLC采集与控制,实现MES工序管理与品质管控,记录产品的加工数据,工厂生产装配流水线的一次成功应用
1.通过程序与PLC的采集与控制,实现MES工序管理,品质管控,历史数据追溯的目的 2.大概的流程图 3.有三个地方相关联来实现以上功能,首先是MES的工序管理,设置指定的产品有那些工序,上位机程序扫 ...
- 西门子S7系列以太网通讯处理器功能介绍
北京华科远创科技有限研发的远创智控型号ETH-YC模块适用于西门子S7-200/S7-300/S7-400.SMART S7-200.西门子数控840D.840DSL.合信.亿维PLC的PPI/MPI ...
- iNeuOS工业互联平台,PLC监测与控制应用过程案例。新闻:.NET 6 RC1 正式发布
目 录 1. 概述... 1 2. 平台演示... 2 3. 应用过程... 2 1. 概述 iNeuOS工业互联网操作系统主要使用.netcore 3. ...
随机推荐
- C++_对象之间的关系与继承
派生类和基类之间的特殊关系是基于C++继承的底层模型的. 实际上,C++有3种继承方式:公有继承.保护继承.私有继承. 公有继承是最常见的关系,它建立一种is-a的关系,即派生类对象也是一种基类,可以 ...
- 转——.ashx文件与.ashx.cs
作者:PBDragon 原文连接:http://www.cnblogs.com/PBDragon/p/3811831.html 如果项目是“新建网站”,添加的ashx是没有ashx.cs的:如果是新建 ...
- P5021 赛道修建 (NOIP2018)
传送门 考场上把暴力都打满了,结果文件输入输出写错了.... 当时时间很充裕,如果认真想想正解是可以想出来的.. 问你 长度最小的赛道长度的最大值 显然二分答案 考虑如何判断是否可行 显然对于一个节点 ...
- C#工具类之Xml序列化扩展类
using System; using System.IO; using System.Linq; using System.Runtime.Serialization; using System.T ...
- Go语言基础之3--时间和日期序列
一.时间和日期类型 1. time包 2. time.Time类型,用来表示时间 3. 获取当前时间, now := time.Now() 实例1-1 打印输出当前时间 package main i ...
- oracle Clob类型转换成String类型
转载:https://www.cnblogs.com/itmyhome/p/4131339.html Clob类型转换成String类型 oracle中表结构如下: create table GRID ...
- 线程池ThreadPoolExecutor分析: 线程池是什么时候创建线程的,队列中的任务是什么时候取出来的?
带着几个问题进入源码分析: 1. 线程池是什么时候创建线程的? 2. 任务runnable task是先放到core到maxThread之间的线程,还是先放到队列? 3. 队列中的任务是什么时候取出来 ...
- 工作必备,五分钟如何搞定Excel甘特图
工作必备,五分钟如何搞定Excel甘特图 https://www.sohu.com/a/212628821_641930 EXCEL中如何给图表添加标题 1.选中图表 >> [布局] 菜 ...
- public class 与 class 的区别
public class 与 class 的区别 1.一个类前面的public是可有可无的 2.如果一个类使用 public 修饰,则文件名必须与类名一致 3.如果一个类前面没有使用public修饰, ...
- git使用笔记-基础篇
git使用手册:https://git-scm.com/book/zh/v1/ 一.分支 1.查看所有本地分支 git branch 2.查看所有本地分支和远程分支 git branch -a 3.查 ...