造福大家,哈哈,发一个能用的步进电机S加速曲线的算法...
本帖最后由 myqiang1990 于 2013-2-23 13:00 编辑大家看看上面的参数,然后对照程序,自己可以仿制一个,程序生存的数据是将3段S曲线,包括加加速和加减速段,这个程序是将S曲线离散成你想要的升频和对应频段内步值,然后分段升频,程序中查表加速就OK了~~(支持变细分哦!!!!抵挡单片机跑高速的福音~~~{:lol:} )软件是delphi7啊~~没有大家就去网上下巴~~
不懂的,大家可以讨论讨论哈~~~因为版权问题,这个软件就不公开了,大家对照我贴的图片的参数,然后对照下面的代码,就懂了,子不过是自己自己建一个新工程而已,注意我用了iocmp控件,没有的童鞋,在这里下载~~http://www.amobbs.com/thread-5267464-1-1.html{:smile:}
//////////////////////////////////S曲线生产////////////////////////////////
//////////////////////////////////S曲线生产////////////////////////////////
//////////////////////////////////S曲线生产////////////////////////////////
//////////////////////////////////S曲线生产////////////////////////////////
procedure TForm1.SCurve();
var
aa:double;//加加速度
v1:integer;//拐点速度
t1:double;//拐点时间
dt:double;//时间间隔
vstart, vend:integer;//起始速度(HZ)
xifen:integer;//细分数
freq:integer;//定时器频率
i,j, allsteps:integer;//脉冲个数
T, time:double;
freqleves:array of integer;
freqsteps:array of integer;
timerdata:array of integer;
showstr : string;
begin
aa := StrToFloat(edit17.Text);//加加速度
vstart := StrToInt(edit18.Text);//启动频率
vend := StrToInt(edit19.Text);//启动频率
xifen := StrToInt(edit37.Text);//细分数
freq := StrToInt(edit16.Text) ;//定时器频率
time := StrToFloat(edit20.Text);//频段保持时间
T := 0;
i := 0;
allsteps := 0;
showstr := ' ';
v1 := trunc((vstart + vend) / 2);//求出拐点频率
t1 := Sqrt(2 * (v1 - vstart) / aa);//求出拐点时间(s)
dt :=time / 1000; //求出时间间隔 (s)
//////////////调试模式 /////
if checkbox12.Checked then
begin
memo1.Lines.Add('v1(拐点频率)------->' + InttoStr(v1));
memo1.Lines.Add('t1(拐点时间)------->' + FloattoStr(t1));
memo1.Lines.Add('dt(减速间隔)------->' + FloattoStr(dt) + #13);
memo1.Lines.Add( #13);
end;
//求出运加速度段
while (T <= t1) do
begin
freqleves := trunc(vstart + 1 / 2 * aa * T * T);
freqleves := freqleves;//按细分数扩大倍速
freqsteps := trunc(dt * freqleves);//求出频点的内部步数
//allsteps := allsteps + freqsteps; //求出总脉冲数
//if freqsteps = 0 then
//freqsteps := freqsteps+ 1;
timerdata := trunc(freq / (freqleves * xifen) + 0.5);//求出定时器初值
//调试模式
if checkbox12.Checked then
begin
memo1.Lines.Add('freqleves(台阶频率)'+IntToStr(i)+'------->' + inttoStr(freqleves));
memo1.Lines.Add('freqsteps(台阶步数)'+IntToStr(i)+'------->' + inttoStr(freqsteps));
memo1.Lines.Add('timerdata(定时器初值)'+IntToStr(i)+'------->' + inttoStr(timerdata));
memo1.Lines.Add('T(已累加时间)------->' + Format('%.3f', ) + #13);
memo1.Lines.Add( #13);
end;
iXYPlot1.Channel.AddXY(i, freqleves);//画出频率曲线
iXYPlot1.Channel.AddXY(i, freqsteps); //步值曲线
if not checkbox13.Checked then
iXYPlot1.Channel.AddXY(i, timerdata); //定时器初值曲线
T := T + dt;//递增到下一个频点的时间
i := i + 1;
end;
//求出运减速段
i :=i - 1 ;
while (freqleves<= vend) do
begin
i :=i + 1 ;
freqleves := trunc((2 * aa * T * Sqrt(2* (v1 - vstart) / aa))-(1 / 2 * aa * T * T) - (2 * v1) + (3 * vstart));
freqleves := freqleves;//按细分数扩大倍速
freqsteps := trunc(dt * freqleves);//求出频点的内部步数
//allsteps := allsteps + freqsteps; //求出总脉冲数
//if freqsteps = 0 then
// freqsteps := freqsteps+ 1;
timerdata := trunc(freq / (freqleves * xifen) + 0.5);//求出定时器初值
//调试模式
if checkbox12.Checkedthen
begin
memo1.Lines.Add('freqleves(台阶频率)'+IntToStr(i)+'------->' + inttoStr(freqleves));
memo1.Lines.Add('freqsteps(台阶步数)'+IntToStr(i)+'------->' + inttoStr(freqsteps));
memo1.Lines.Add('timerdata(定时器初值)'+IntToStr(i)+'------->' + inttoStr(timerdata));
memo1.Lines.Add('T(已累加时间)------->' + Format('%.3f', ) + #13);
memo1.Lines.Add( #13);
end;
iXYPlot1.Channel.AddXY(i, freqleves);//画出频率曲线
iXYPlot1.Channel.AddXY(i, freqsteps); //步值曲线
if not checkbox13.Checked then
iXYPlot1.Channel.AddXY(i, timerdata); //定时器初值曲线
T := T + dt;//递增到下一个频点的时间
if(trunc((2 * aa * T * Sqrt(2* (v1 - vstart) / aa))-(1 / 2 * aa * T * T) - (2 * v1) + (3 * vstart)) < freqleves) then
break;
end;
///////////////////////////统计总步数
for j:=0 to i do
begin
if freqsteps = 0 then
freqsteps := freqsteps+ 1;
allsteps := allsteps +freqsteps;
end;
//变细分处理---->主要处理频率
if checkbox13.Checked = true then
begin
j := 0;
//安细分调节第一段
while((freqleves <= StrToInt(edit50.Text)) and (j <= i)) do
begin
timerdata := trunc(freq / (freqleves * StrToInt(edit51.Text)) + 0.5);//求出定时器初值
iXYPlot1.Channel.AddXY(j, timerdata); //定时器初值曲线
j := j+1;
end;
//调节第二段
while((freqleves <= StrToInt(edit47.Text)) and (j <= i)) do
begin
timerdata := trunc(freq / (freqleves * StrToInt(edit48.Text)) + 0.5);//求出定时器初值
iXYPlot1.Channel.AddXY(j, timerdata); //定时器初值曲线
j := j+1;
end;
//调节第三段
while((freqleves <= StrToInt(edit44.Text)) and (j <= i)) do
begin
timerdata := trunc(freq / (freqleves * StrToInt(edit45.Text)) + 0.5);//求出定时器初值
iXYPlot1.Channel.AddXY(j, timerdata); //定时器初值曲线
j := j+1;
end;
//调节第四段
while((freqleves <= freqleves) and (j <= i)) do
begin
timerdata := trunc(freq / (freqleves * StrToInt(edit54.Text)) + 0.5);//求出定时器初值
iXYPlot1.Channel.AddXY(j, timerdata); //定时器初值曲线
j := j+1;
if j > i then
break;
end;
end;
//非调试模式显示数据
if not checkbox12.Checked then
begin
////生成数据//////////////////////////////////
showstr := showstr + '//////////////////////////////////////////三段式S加速曲线///////////////////////////////'+#13;
showstr := showstr +'//启动频率:' + Format('%d', ) + 'HZ'+#13;
showstr := showstr +'//最高频率:' + Format('%d', ) + 'HZ'+#13;
showstr := showstr +'//加加速度:' + Format('%.3f', ) + 'm*s^-3'+#13;
showstr := showstr +'//频段保持时间:' + Format('%.3f', ) + 's'+#13;
showstr := showstr +'//定时器频率:' + Format('%d', ) + 'HZ'+#13;
showstr := showstr +'//加速频率总段数:' + Format('%d', ) + '段'+#13;
showstr := showstr +'//加速总脉冲数:' + Format('%d', ) + '个'+#13;
showstr := showstr +'//最高运行速度(按电机步距角为1.8度算):' + Format('%d', / (360 /1.8) * 60)]) + 'RPM(转/分)'+#13;
if checkbox13.Checked = true then//变细分
begin
showstr := showstr + '//'+edit49.Text+'HZ--->'+edit50.Text+'HZ--->'+edit51.Text+'细分'+#13;
showstr := showstr + '//'+edit46.Text+'HZ--->'+edit47.Text+'HZ--->'+edit48.Text+'细分'+#13;
showstr := showstr + '//'+edit43.Text+'HZ--->'+edit44.Text+'HZ--->'+edit45.Text+'细分'+#13;
showstr := showstr + '//'+edit52.Text+'HZ--->'+edit53.Text+'HZ--->'+edit54.Text+'细分'+#13;
end
else
showstr := showstr +'//细分数:' + Format('%d', ) + '细分'+#13;
showstr := showstr +'//////////////////步值表//////////////////////////////'+#13;
showstr := showstr +'const u16 MX_LevesStepsTable[]='+#13;
showstr := showstr +'{'+#13;
for j := 0 to i do
begin
if not checkbox11.Checked then //10进制显示
showstr := showstr + format('%d,', ])//+#13;
else //16进制显示
showstr := showstr +format('0x%.4x,', ]);//+#13;
if (j+1) mod 30 = 0 then
showstr := showstr+ #13;
end;
showstr := showstr +#13+'};'+#13;
showstr := showstr +#13;
showstr := showstr +'//////////////////定时器初值表///////////////////////////'+#13;
showstr := showstr +'//启动频率:' + Format('%d', ) + 'HZ'+#13;
showstr := showstr +'//最高频率:' + Format('%d', ) + 'HZ'+#13;
showstr := showstr +'//加加速度:' + Format('%.3f', ) + 'm*s^-3'+#13;
showstr := showstr +'//频段保持时间:' + Format('%.3f', ) + 's'+#13;
showstr := showstr +'//定时器频率:' + Format('%d', ) + 'HZ'+#13;
showstr := showstr +'//加速频率总段数:' + Format('%d', ) + '段'+#13;
showstr := showstr +'//加速总脉冲数:' + Format('%d', ) + '个'+#13;
showstr := showstr +'//最高运行速度(按电机步距角为1.8度算):' + Format('%d', / (360 /1.8) * 60)]) + 'RPM(转/分)'+#13;
if checkbox13.Checked = true then//变细分
begin
showstr := showstr + '//'+edit49.Text+'HZ--->'+edit50.Text+'HZ--->'+edit51.Text+'细分'+#13;
showstr := showstr + '//'+edit46.Text+'HZ--->'+edit47.Text+'HZ--->'+edit48.Text+'细分'+#13;
showstr := showstr + '//'+edit43.Text+'HZ--->'+edit44.Text+'HZ--->'+edit45.Text+'细分'+#13;
showstr := showstr + '//'+edit52.Text+'HZ--->'+edit53.Text+'HZ--->'+edit54.Text+'细分'+#13;
end
else
showstr := showstr +'//细分数:' + Format('%d', ) + '细分'+#13;
if Combobox4.ItemIndex = 1 then //显示模式1
begin
showstr := showstr +'const u16 MX_SpeedLevesTable[]='+#13;
showstr := showstr +'{'+#13;
for j := 0 to i do
begin
if not checkbox11.Checked then //10进制
showstr := showstr +format('%d, ', ])
else //16进制
showstr := showstr + format('0x%.4x, ', ]);
if (j+1) mod 15 = 0 then
showstr := showstr + #13;
end;
showstr := showstr +#13+'};'+#13;
end
else
begin
showstr := showstr +'const u16 MX_SpeedLevesTable[] ={'+#13;
showstr := showstr +'//{频率,定时器初值,台阶步数}'+#13;
for j := 0 to i do
begin
if not checkbox11.Checked then//10进制
showstr := showstr +'{'+ format('%d', ])+ ', '+ format('%d',])+', '+format('%d', ])+'},'+'//'+format('%d',)+#13
else //16进制
showstr := showstr +'{'+ format('%d', ])+ ', '+ format('0x%.4x',])+', '+format('0x%.4x', ])+'},'+'//'+format('%d',)+#13;
end;
showstr := showstr +#13+'};'+#13;
end;
end;
memo1.Lines.Text := showstr;
end; 如果大家想实时计算,按照里面说的方法自己实现,实现了大家就贴一下思路吧~~~哈哈~~因为我没实现啊~~{:lol:} 顶一下LZ 本帖最后由 kinsno 于 2013-2-23 13:04 编辑
楼主是90年的伙计,相当厉害了啊;
1、软件是公司内部自行开发的软件吗,还是采购的商业软件啊?内部软件就不用说了,必须保密。如果是商业软件,是否提供一个名称啊,去寻找破解版。
2、你的算法和软件是根据这个PDF实现的吗?经过实际应用了吗?还是沿且在实验中没经过现场的锤炼? 很厉害啊 本帖最后由 myqiang1990 于 2013-2-23 13:09 编辑
kinsno 发表于 2013-2-23 12:59 static/image/common/back.gif
楼上的是90年的伙计,相当厉害了啊;软件是公司内部自行开发的软件吗,还是采购的商业软件啊?内部软件就不 ...
我自己写的~~~我为公司开发的,所以东西就归公司了,哈哈,平时用电机很多,觉得没有工具帮助,很麻烦啊~~所以索性就写了一个~~~~~肯定用过啦~~~只不过我不经常用S加速而已,因为不太适合我们的东西,因为他加速太慢了(因为他开始有一段加加速,就是比较平滑那段,怎么都比人家启动的慢~~,或许是加速程序处理不够好~~)~~我用的指数型或者梯形~~~ myqiang1990 发表于 2013-2-23 13:05 static/image/common/back.gif
我自己写的~~~我为公司开发的,所以东西就归公司了,哈哈~~~肯定用过啦~~~只不过我不经常用S加速而已,因 ...
现在这种文档满天飞,年前看了一些,但真正应用起来,发现多半是书生一拍脑门想出来的或者是拿个信号发生器或示波器证实出来的,并不能在现场应用的,一上应用歇菜。
你是这方面的应用专家,发现你在这方面搞了好几年了,如果方便的话,指数型或T形的,能否给介绍些实用文档,经过验证证实现场可靠应用的文档,我下载两个去,偶最近也在弄步进电机方面的算法。
本帖最后由 myqiang1990 于 2013-2-23 13:16 编辑
kinsno 发表于 2013-2-23 13:09 static/image/common/back.gif
现在这种文档满天飞,年前看了一些,但真正应用起来,发现多半是书生一拍脑门想出来的或者是拿个信号发生 ...
指数的我已经发了,你去看我的帖子找找,有的,我都不知道去哪里了,你去我发的帖子找找~~~我悄悄告诉你,指数只要变一下参数就变成了梯形~~~哈哈~~~我自己无意中发现的~~{:lol:} 你还可以参考AVR那个
AVR446_Linear speed control of stepper motor 文档,代码算法都有,梯形的~~~
myqiang1990 发表于 2013-2-23 13:14 static/image/common/back.gif
指数的我已经发了,你去看我的帖子找找,有的,我都不知道去哪里了,你去我发的帖子找找~~~我悄悄告诉你 ...
太感谢了,学习去。 kinsno 发表于 2013-2-23 13:09 static/image/common/back.gif
现在这种文档满天飞,年前看了一些,但真正应用起来,发现多半是书生一拍脑门想出来的或者是拿个信号发生 ...
专家就不是,我也半路出家,菜鸟一只,我也是站在巨人的肩膀上啊~~哈哈~~{:lol:} 来这里那么久,我从来都没穿过裤子,这次又图有代码,能穿一只吗?{:lol:}阿莫大哥,发一条裤子给我吧~~~ 好东西,下载来看看改成自己的 zhichi 支持一下你 支持下,老大给个裤子吧 支持你 {:victory:} 支持楼主!{:victory:} lz,牛人啊,都为大家造福啊。 学习 有那个加速度曲线生成器吗?麻烦上传一个啊 学习学习delphi等 支持一下楼主。..桌面上就有个小电机正在转. 多谢楼主分享 mark…… 顶起来啊 哈哈 学习一下.... 支持楼主,收藏了!!! mark。。。。。。 记录一下 freqleves := freqleves;//按细分数扩大倍速
这是什么意思, 不错好东西 收了 没接触过,先顶,试着看看 好东西啊,顶一个 MARK一下,最近在搞这个啊 ,头都大了 好东西,MARK一下 没有接触,学习下 mark.................... {:handshake:}学习了~很强大 mark{:smile:} 好资料
{:victory:}好东西,收藏一下! 楼主厉害!
支持一下你 好东西,学习了 最近正在学习驱动电机mark一下很有必要!!! 学习中。。。
记号,收藏 仔细研究下,以前我的一个实现方法就是将一个S曲线折线话,然后用线性函数实现,不过如果要光滑的话程序就很长了,一直没有好的算法 好东西,收藏一下 学习中。。。
LZ太牛了,没看懂也MK一下 大牛不敢当,小伎俩而已,,,,我对电机加减速还有如何控制步进电机方面有点点经验,欢迎大家跟帖交流。。。{:smile:} 必须顶,修炼内功 收下 以后看看 DIY 小车有用 怎么感觉个 fpba的语言有点像啊 是fpga的语言 支持
{:smile:} mar…
顶一个… 牛人呀………
标记一下 Mark{:biggrin:}{:biggrin:} myqiang1990 发表于 2013-2-23 13:14 static/image/common/back.gif
指数的我已经发了,你去看我的帖子找找,有的,我都不知道去哪里了,你去我发的帖子找找~~~我悄悄告诉你 ...
楼主太牛逼了····哈啊哈···别怪我挖坟哈····步进电机s加速算法··记得当时老师讲的时候,让后排睡觉的都起来听···大学真是作孽啊··· 实时计算也可以啊,不过稍微麻烦一点,我用的是STM32—FPGA这种模式,性能很稳定。 myqiang1990 发表于 2013-2-23 13:22 static/image/common/back.gif
专家就不是,我也半路出家,菜鸟一只,我也是站在巨人的肩膀上啊~~哈哈~~...
有没有试过在换向桥电路上用PWM实现加减算法与电流力矩动态平衡! myqiang1990有没有联系方式,很想认识一下你.Q号是21836769. nishuizhou 发表于 2013-9-12 16:56 static/image/common/back.gif
实时计算也可以啊,不过稍微麻烦一点,我用的是STM32—FPGA这种模式,性能很稳定。 ...
恩,,可以的,,但是应用场所不一样~~在国内~~舞台灯整个FPGA,或者高端ARM是不现实滴~~~外国的有~~我看过~~FPGA的~~但是人家一台就买几万,甚至10几万~~~~国内很多厂商还是51呢~~ hxhz123456 发表于 2013-9-12 17:20 static/image/common/back.gif
myqiang1990有没有联系方式,很想认识一下你.Q号是21836769.
一零八五二二六六久六 本帖最后由 myqiang1990 于 2013-9-14 17:28 编辑
hxhz123456 发表于 2013-9-12 17:14 static/image/common/back.gif
有没有试过在换向桥电路上用PWM实现加减算法与电流力矩动态平衡!
我不怎么懂电路,公司的软件是我一个人不负责编写的~~电路又其他工程师负责,,他们怎么画,我就怎么写~~~呵呵~~这个没弄过~~ mark{:smile:} 记号,收藏! 好东西,学习下 步进电机 ding ding , thanks{:biggrin:} 顶一个!! 必须留个号
好东西,收藏一下! 好东西,标记一下。我做的一个项目也涉及到了电机加减速。回头学习下。三克油! 编译成功,谢谢楼主 好帖,收藏! 谢谢分享!! 顶!顶顶
好东西,MARK一下 收藏,记号 关注中,正在学习步进电机 谢了 进来看看。。 myqiang1990 发表于 2013-2-23 13:22
专家就不是,我也半路出家,菜鸟一只,我也是站在巨人的肩膀上啊~~哈哈~~...
太厉害了吧。。。半路出家,我也想半路出家搞那么厉害。。。 这是电脑所用的源码? 学习!!!!! mark,好东西,正在学习这一块知识 mark下要研究下才行 支持楼主 标记一下,研究研究 好裤,{:smile:} 好东西,收藏了 谢谢楼主学习了 三克油喂了吗吃{:victory:} 厉害厉害 nishuizhou 发表于 2013-9-12 16:56
实时计算也可以啊,不过稍微麻烦一点,我用的是STM32—FPGA这种模式,性能很稳定。 ...
您好,能详细指点一下吗?谢谢!
好东西,赞一个。 larry.wong 发表于 2014-3-10 16:28
您好,能详细指点一下吗?谢谢!
可以用STM32的FSMC 的A模式与FPGA通讯,STM32可以做计算和IO控制,FPGA发脉冲。定制FPGA的脉冲频率。不知你要参与什么项目,说不太清楚 果断收藏 感谢LZ哈,LZ的头像也太萌了哈,受不鸟了。。。 nishuizhou 发表于 2014-3-10 16:51
可以用STM32的FSMC 的A模式与FPGA通讯,STM32可以做计算和IO控制,FPGA发脉冲。定制FPGA的脉冲频率。不知 ...
明白了,谢谢!一直用PLC控制,可不用位置模块性能差。一直想自动设计一块控制板.
页:
[1]
2