首页 上一页 1 2 下一页 尾页

雷赛人员浅析运动控制卡应用编程技巧几招(1) 点击:22762 | 回复:23



aohongmei12

    
  • 精华:0帖
  • 求助:0帖
  • 帖子:36帖 | 37回
  • 年度积分:1
  • 历史总积分:752
  • 注册:2012年8月08日
发表于:2012-10-15 09:08:58
楼主

声明一下,写下这些编程技巧,即不是什么祖传秘籍,也不是什么必杀招或绝招,在此只为方便同仁们在编程控制软件时,对此可以进行适当的斟酌。以下展现的编程思想及奉上的源代码都非常简易,但并不是随手写写,可都是在雷赛做研发几年下来实践的。若没有成功经验作后盾,我也就没有必要在此打字练五笔了。

事实上,正如一个编程大师所言(Michael
Abrash),当你的软件正常而且有效率的运行起来时,好像一切都是那么显而易见。故,在此,我仍坚持那句编程口号,将事情变得越简单越好,越简单就越有效率,越稳定

在以下的介绍中,我将尽可能的展示本人的编程思想,运用雷赛1000系列控制卡最大可能的给出知其然也知其所然的解释。若你有更好的见解,希望能得到你的指正。人长大了明显标志就是变得不太负责,而且不敢承认自己还需要努力,害怕面对自己的错误。若是这样,放心,我还没长大。因为我无法保证我能面面俱到。

关于源代码的阅读,需要读者有一定的C++编程基础,至少对以下表示形式不会产生误解:
constchar*pString; //指定pString邦定的数据不能被修改
char * const pString; //指定pString的地址不能被修改
constchar* const pString; //含上面两种指定功能
当然,随便提醒一下,这些源代码若需要加入你的软件工程当中,还需要作一些调整和修改,因此,这些源代码实质上称为伪代码也可以,之所以展现它们,是让程序员们有个可视化的快感,特别是那些认为源代码就是一切的程序员。

同时,为了提高针对性,大部分控制卡调用的函数会明确指出是邦定哪些卡的,实际应用时,程序员可自行选择,以体现一下自己的智商是可以写写软件的。


一、 控制卡类的单一实例实现
把控制卡类作一个类来处理,几乎所有C++程序员都为举双手表示赞同,故第一个什么都没有的伪代码就此产生,如下表现:
class CCtrlCard
{
public:
…Function
public:
…attrib
}

于是,用这个CctrlCard可以产生n多个控制卡实例,只要内存足够。然而,针对现实世界,情况并不那么美好。通常情况下,PC机内只插同种类型的控制卡1到2张,在通过调用d1000_board_init或d3000_board_init函数时,它们会负责返回有效卡数nCards,然后从0-nCards*4
-
1自行按排好轴数。初始化函数就是C++的new或malloc的操作,取得系统的资源,但是控制卡的资源与内存不一样,取得资源后必需要释放才可以再次获取,即控制卡资源是唯一的。

既然控制卡资源是唯一的,那么最好Cctrlcard产生的实例也是唯一的,这样,我们可以方便的需要定义一个全局变量即可:
CctrlCard g_Dmcard;
在其它需要调用的地方,进行外部呼叫:
extern CctrlCard g_DmcCard;

以上方法实在太简单了,很多人都会开心起来。实质上,方法还有很多,即然可以产生n多对实例,我们的核心是只要保证调用board_init函数一次即可,故也可以单独定义一个InitBoard函数:

class CctrlCard
{
public:
static int InitBoard(); //定义一个静态函数,以表警示

}
int CctrlCard::InitBoard()
{
return d1000_board_init();
}

还有一种方法,情况稍加复杂,但表达的功能也要强一些,以下展现可以稍微安慰一下代码狂。

Class CctrlCard
{
public:
CctrlCard(); //请注意这个构造函数的定义
}

CctrlCard::CctrlCard()
{//呵呵,也很明了
static int n(0); //注意,是个静态变量

n++; //每次调用CctrlCard生成实例时,都会计数一次
assert( n == 1 ); //在DEBUG版本下,只有n==1的情况下可以通过
//否则,会出现致命错误,还好,它会告诉你错在哪个文件,
//哪一行,呵呵,是个好东东啊。
}
通过强行报警处理,当你有g_DmcCard这个实例时,其它的所有控制卡的定义都只能是以引用或指针的方式进行了,不会再产生新有效的实例了,对于由小组编程的项目软件,而你又恰好负责编程控制卡这一块的话,以上的显性报警,会让其它人心领神会。当然,你也可以将上面的方法加入到InitBoard当中去,可以避你的无意识的多次调用了。


附:无意识的多次调用经常发生,特别是那些对MFC机制不明确的程序员,在多文档框架下,不知道这个CctrlCard::InitBoard函数到底是应该放在CmainFrame的OnCreate里面,还是应该放在CchildFrame的OnCreate,或者是Cview的OnInitUpdate里面进行调用。

在一言难尽MFC的情况下,我建议两个小方法:
No.1 将CctrlCard的函数置于Cmainframe的OnCreate或者Capp::Initstance内调用
No.2 将InitBoard函数稍加改造成这样:
Int CctrlCard::InitBoard()
{
static int n(-1000);//注意,-1000是控制卡函数不可能返回的值
if( n == -1000 )
n = d1000_board_init();
return n;//这样,即使多次调用也不样怕了,呵呵,雕虫小技也可以除虫啊
}

必须额外声明一下,我们不是不重视资源的释放,而是作为一个C++程序员写下这些代码是基本的义务(这也是我为什么要交待读者必须要有一定的C++基础):
class CctrlCard
{
public:
~CctrlCard()
{//定义析构函数,在此释放资源,对此,我不想再转到读者的眼球了
d1000_board_close();
}
}

二、 数据结构及数据类型的定义,部分相关声明
调用控制卡驱动函数时,经常会有如下形式:
单轴相对运动 d1000_start_t_move( axis, pulse, start, speed, accel );
单轴绝对运动 d1000_start_ta_move( axis, pulse, start, speed, accel );
两轴相对插补 d1000_start_t_line( axisArray, distArray, start, speed, accel );
两轴绝对插补 d1000_start_ta_line( axisArray, distArray, start, speed, accel );
圆弧相对插补 d3000_start_t_arc( axisArray, C1, C2, E1,E2, dir, start, speed, accel );
圆弧绝对插补 d3000_start_ta_arc( axisArray, C1, C2, E1,E2, dir, start, speed, accel );


以上的调用,很多重复枯燥,又不直观,难于理解,并且在面向客户时,常常是指每分多少米,或者每秒多少毫米,很少有人问每秒多少脉冲,移动多少脉冲作距离,故需要单位之间的换算。显然,对于这些问题,我想,C++程序员应该找到用武之地了,所以我们一步一步来,慢慢统一各个问题。实质上,在以下的几个技巧,也需要在此澄清一些概念。

我们先来几个宏定义提高一下情绪:
# define MAX_AXIS 4 //最多轴数
# define XCH 0 //定义X轴的值
# define YCH 1
# define ZCH 2
# define UCH 3
…..(其它以次类推)

# define M_ABS 0x01 //定义一个绝对标志位
# define M_INP 0x02 //定义一个插补位

接下来深入一点点,再来几个结构定义:

typedef struct tag_ARC
{
tag_ARC( double ox=0.0, double oy=0.0, double ex=0.0, double ey=0.0, int dir=0
):
ox(ox), oy(oy),
ex(ex), ey(ey),
dir(dir)//定义这样一个构造函数需要勇气,看似不合理,但是好用麻
{
}
double ox,oy;
double ex,ey;
int dir;
}ARC;

typedef struct tag_SPEED
{
tag_SPEED( double start=0.0, double speed=0.0, double accel=0.0, double
decel=0.0,
double scc=0.0 ) :
start(start),
speed(speed),
accel(accel),
decel(decel),
scc(scc)
{
}

double start;
double speed;
double accel;
double decel;
double scc;
}SPEED;

以上两个ARC和SPEED的结构定义,把几个参数变成一个参数。比如要实现的单轴驱动函数,就变得非常明了:
void Move( int nAxis, double fMM, const SPEED &speed, int nFlag = M_ABS
);//往后我们再具体完善其实现。

以上的结构具有类的特性,但是由于其每个成员都可以给外部直接使用,故就不需要什么类的public及其析构函数的定义了。之所以全都采用double的数据类型,是面向客户习惯及单位计算方便的。

接下来是对控制卡常用的单位计算及部分常用变量的声明:
class Cctrlcard
{
public:
…(其它略去)
public:
//属性
mutable int ORGIN; //指定原点状态位
mutable int LIMIT_A, LIMIT_B; //指定左右限位状态位
private:
//以下的属性不给外部访问的
struct tag_AXIS{//单轴属性
double fUnitPM; //脉冲当量
long nRP; //每转脉冲数
double fJourey; //行程
};
tag_AXIS m_axis【MAX_AXIS】;
};

定义ORGIN,LIMIT_A, LIMIT_B为变量,是有两个意义:
No.1 当你访问它们的状态时,不需要每次调用d1000_get_axis_status函数,你可以这样:
Int nStatus = d1000_get_axis( XCH );
If( nStatus & g_DmcCard.ORGIN == g_dmcCard.ORGIN )
If( nStatus & g_DmcCard.LIMIT_A == g_DmcCard.LIMIT_A )
If( nStatus & g_DmcCard.LIMIT_B == g_DmcCard.LIMIT_B );
No.2
你可以扩展不同的卡,当外部调用的程序逻辑已被确定时,当你需要从DMC1000控制卡升级到DMC3000控制卡时,只需要给ORGIN等状态位指定不同的值即可。指定状态位的值也有一个小小的技巧,以ORGIN为例,在DMC1000控制卡,其位值在2位,则可以这样:

ORGIN = 1<<2;
在DMC3000控制卡,其值在第9位,则这样:
ORGIN = 1<<9;
方法都很简单,关键是要想得到。

对于tag_AXIS定义,引出几个函数的声明,专门为其服务:
void SetUP( nit nAxis, double fMM, double nPulse, double fMax );//设定当量
double P2M ( int nAxis, long nPulse ); //脉冲转成毫米 pulse to metric
long M2P( int nAxis, double fMM ); //毫米转成脉冲 mitric to pulse

现在,我们再回过头来完成Move函数的实现,以便获得一点点成就感,同时也展示一下以上的大堆表述是有其意义的。

void Move( int nAxis, double fMM, const SPEED &speed, int nFlag = M_ABS )
{
( nFlag & M_ABS == M_ABS ) ?
d1000_start_ta_move( nAxis, //绝对
M2P( nAxis, fMM),
M2P( nAxis, speed.start ),
M2P( nAxis, speed.speed),
Speed.accel ): //注意是冒号,?:是一个表达式
d1000_start_t_move( nAxis, //相对
M2P( nAxis, fMM),
M2P( nAxis, speed.start ),
M2P( nAxis, speed.speed),
Speed.accel );
}

是不是很简单呢,当外部调用时,客户的观念就直接面对Metric即可,如:

Move( XCH, 10.0, SPEED(5,10,0.1), M_ABS );//达到绝对位置10.0毫米处。

以上罗嗦了一大堆,对于刚开始C++编程的程序员来说应该是收益不小,对于高手,则希望能够体会一下我的良苦用心。在以下的技巧介绍当中,我将变得很简易。一般来讲,程序员的基础不是太差的话,至少能够在1分钟内明白是什么道理。




yiyping

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 49回
  • 年度积分:0
  • 历史总积分:53
  • 注册:2009年3月31日
发表于:2012-10-23 11:48:32
1楼
本人熟悉雷赛控制卡6400,6480编程,有需要代笔的,请联系13459200729, 杨

  • 精华:0帖
  • 求助:1帖
  • 帖子:27帖 | 45回
  • 年度积分:0
  • 历史总积分:148
  • 注册:2007年8月31日
发表于:2014-11-28 16:37:00
2楼

可以使用简单易用的MPC014微型运动控制器,基于485通讯,代替运动控制卡。

  • 精华:0帖
  • 求助:1帖
  • 帖子:27帖 | 45回
  • 年度积分:0
  • 历史总积分:148
  • 注册:2007年8月31日
发表于:2014-12-14 21:24:41
3楼

mpc003,mpc006运动控制芯片模块采用新型FPGA设计,集成常用运动控制功能,DIP-30封装,只有芯片般大小,可与普通单片机通过串口通讯对步进电机或伺服电机控制。单模块最高六轴输出,多个模块组网工作可达120轴,最大脉冲输出频率为2MHz,任意两轴直线插补,任意两轴圆弧插补。只有十几条指令,使用简单方便。价格80元起!
MPC014微型运动控制器集成普通IO,模拟量输出,步进电机和伺服电机控制。RS485通讯,可多个控制器组网工作。7路光耦隔离输入,9路晶体管集电极开路输出。最大脉冲输出频率为2MHz,四轴独立运动控制,任意两轴直线插补,任意两轴圆弧插补,提供DLL动态链接函数库,可用于Window2000/XP/7平台二次开发。控制器仅有21条函数指令,输入输出口都带有独立指示灯,是目前全球最简单易用的运动控制产品,可靠替代运动控制卡用于各中小型机械设备。价格780元起!
MPC024脱机运动控制器集成普通IO,模拟量输出,步进电机和伺服电机控制。RS485通讯下载指令,8000条指令存储空间。7路光耦隔离输入,9路晶体管集电极开路输出。输入输出口都带有独立指示灯。最大脉冲输出频率为2MHz,四轴独立运动控制,任意两轴直线插补,任意两轴圆弧插补,带逻辑指令,带端口交互,可通过PLC,开关控制组成运动控制系统。提供MPC编程软件,控制器仅有15条指令,易学易用。,可靠替代运动定位模块用于各中小型机械设备。价格780元起!
联系电话:0755-32912587 ,详细资料请到产品官方网站www.mpc000.com下载。

zhangzhaoyi_225

  • 精华:0帖
  • 求助:0帖
  • 帖子:6帖 | 64回
  • 年度积分:0
  • 历史总积分:734
  • 注册:2015年5月11日
发表于:2015-05-11 17:14:32
4楼

自自在在惺惺惜惺惺事实上是是是是

liubing2012

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 1回
  • 年度积分:0
  • 历史总积分:1
  • 注册:2015年6月01日
发表于:2015-06-29 21:46:58
5楼

前辈赞一个vvvvvv

hefeishe

  • 精华:0帖
  • 求助:8帖
  • 帖子:9帖 | 38回
  • 年度积分:0
  • 历史总积分:43
  • 注册:2012年6月14日
发表于:2015-12-04 16:21:54
6楼


回复内容:

对: yiyping 本人熟悉雷赛控制卡6400,6480编程,有需要代笔的... 内容的回复!

控制卡编程如何??5000系列的

mrwangming

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 6回
  • 年度积分:0
  • 历史总积分:69
  • 注册:2006年11月11日
发表于:2016-01-26 13:52:20
7楼

不错!不错!不错!不错!不错!

alex石头

  • 精华:0帖
  • 求助:0帖
  • 帖子:3帖 | 267回
  • 年度积分:0
  • 历史总积分:263
  • 注册:2016年1月07日
发表于:2016-01-28 10:19:35
8楼

这个论坛工控资料蛮多 喜欢 支持

Z~D

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 258回
  • 年度积分:0
  • 历史总积分:196
  • 注册:2016年10月20日
发表于:2017-12-15 11:26:19
9楼

谢谢楼主的分想  收益了

WALL.E

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 29回
  • 年度积分:0
  • 历史总积分:109
  • 注册:2017年12月10日
发表于:2017-12-25 21:23:43
10楼

谢楼主分享,正在学习雷赛的控制卡

sschangle

  • 精华:0帖
  • 求助:1帖
  • 帖子:2帖 | 81回
  • 年度积分:0
  • 历史总积分:254
  • 注册:2011年11月28日
发表于:2018-05-17 16:44:57
11楼
谢谢楼主分享,刚接触到

hanhuachizi

  • 精华:0帖
  • 求助:1帖
  • 帖子:1帖 | 234回
  • 年度积分:9
  • 历史总积分:665
  • 注册:2011年2月06日
发表于:2018-05-17 20:51:55
12楼

果然是高手,精通计算机高级语言。

gjk1022

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 12回
  • 年度积分:0
  • 历史总积分:70
  • 注册:2018年5月18日
发表于:2018-05-18 13:26:35
13楼

雷塞 可以识别CAD图吗

陈某And

  • 精华:0帖
  • 求助:0帖
  • 帖子:5帖 | 95回
  • 年度积分:17
  • 历史总积分:363
  • 注册:2018年2月24日
发表于:2018-05-30 21:43:10
14楼

厉害厉害,真佩服这种远见的大神

浪迹天涯

  • 精华:0帖
  • 求助:0帖
  • 帖子:6帖 | 170回
  • 年度积分:59
  • 历史总积分:595
  • 注册:2017年11月06日
发表于:2018-11-02 14:27:15
15楼

路过,看看学习学习

LICLIN

  • 精华:0帖
  • 求助:0帖
  • 帖子:2帖 | 407回
  • 年度积分:0
  • 历史总积分:380
  • 注册:2017年3月14日
发表于:2018-11-13 14:26:35
16楼

路过,看看学习学习

luofeng1984

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 151回
  • 年度积分:0
  • 历史总积分:221
  • 注册:2016年5月19日
发表于:2019-04-10 16:44:58
17楼

厉害厉害,真佩服这种远见的大神

DeanGoogle

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 10回
  • 年度积分:0
  • 历史总积分:12
  • 注册:2013年4月20日
发表于:2019-04-10 19:41:17
18楼

佩服这位大神分享经验!


但花时间去搞懂内存配置函示封装不小心还会蓝屏死机不如花时间去了解设备工艺!


开发设备不需这么累! 因为研华MAS板卡系列已经将楼主所说的封好了!

开发代码如下楼主可以参考一下也许以后用的上 http://mas.advantech.com.cn


BASE 0, 1         // 多轴运动

UNIT100        // 100 pulse = 1mm

GVL1000          // 设定初速度=1000mm/s

GVH = 10000       // 设定速度=1000mm/s

LINE  3000,2000      // X,Y轴移动 (3000mm, 2000mm)


BASE 0             // 单轴运动

UNIT100        // 100 pulse = 1mm

VL1000          // 设定初速度=1000mm/s

VH = 10000       // 设定速度=1000mm/s

MOVE  3000      // 移动 3000mm


小ZHOUZHOU

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 116回
  • 年度积分:0
  • 历史总积分:139
  • 注册:2018年8月31日
发表于:2019-08-26 16:03:42
19楼

非常感谢,感谢分享

何须太白

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 1回
  • 年度积分:0
  • 历史总积分:61
  • 注册:2020年12月24日
发表于:2020-12-24 15:09:59
20楼

非常感谢,感谢分享


热门招聘
相关主题

官方公众号

智造工程师
    首页 上一页 1 2 下一页 尾页