首先感谢以下博客的博主提供的参考公式:https://blog.csdn.net/pengzhihui2012/article/details/52228822?locationNum=6

首先在本设计中采用的步进电机控制方案为,单片机+16位定时器比较匹配中断(最好是16位及其以上)+步进电机驱动+42步进电机。较高的定时器精度能够实现更好的控制。

在步进电机控制中往往需要对步进电机进行加减速控制,以达到平缓启停或者达到较高转速而不失步停转的目的,而在加减速控制中控制方法有两类:

1.查表法;

查表法简单来说就是通过曲线公式预先计算出加速过程的各个点,再将该点转化为定时器的比较匹配值,载入数组中,查询数组值即可达到加减速的目的。优点是运算速度快,占用较少的CPU资源,缺点也很明显。    1.占用较大的存储空间,一般加速的点数都在300-2000点(细分更高的画可能会更高),若想获得更平滑的效果,点数甚至更高,这将会占用大量的单片机内存或者程序存储空间,如果系统支持一般推荐将数组保存在单片机的程序存储空间,以节省宝贵的Ram资源,例如在Arduino uno 中,若直接采样2000点放到数组里内存直接爆满(328的运行内存2K....)!,好在他提供了 PROGMEM 的操作方式,可以将数组保存到程序存储空间。再用 OCR1A =  pgm_read_word_near(&AccStep[acc_count]);将数组读出。具体实现方法文后有详细说明。2.更改速度、加速度等不方便,每次更改速度都需要重新生成一次表格,加速度的值更是难以设置,对于我目前的水平是这样的,应该是可以通过算法增大或者缩放加减速表格的,貌似开源3D打印固件Marlin中是这样的。

2.实时生成法;

实时生成法,可能会要求更高的CPU计算能力,比较出名的算法是AVR446:Linear speed control of stepper motor,里面提供了详细的计算以及详细的实现方法,加速过程中实时计算下一个比较匹配值,以实现加减速的实时控制,优点挺多,控制加减速度,速度等参数更加方便,因为可以通过设定参数实时计算出来,缺点就是比较考验单片机的运算能力,但在AVR446提到的算法中也能在运算能力较低的单片机中实现。具体AVR446的实现将在另一个文章中说明。

加速过程实现方法曲线一般有梯型曲线法以及S(Sigmoid)曲线法,其他接触过的还有修正正弦曲线法(用在机械臂的轨迹规划中),梯形曲线法一般通过加速度公式(S = a*t*t/2)直接求解,S曲线法则是通过SigMoid函数变形后求解。

本文章主要介绍SigMoid函数用以步进电机的控制方法。

1.基础知识:

步进电机速度计算,做过步进电机控制都知道步进电机的速度跟脉冲频率是直接挂钩的,单片机每发出一个脉冲,步进电机运行一步(转过一个步距角),步距角与步进驱动细分挂钩,例如常用42步进电机步距角参数是1.8°/step,假设通过步进驱动细分后,细分为2,则电机实际每脉冲将运行1.8/2 = 0.9 °。单片机输出脉冲一般通过比较匹配中断的方式使脉冲引脚发出脉冲,则可以计算出单片机发出脉冲的时间间隔为(运行一步的时间)  = 比较匹配值 * (1/ 定时器计数频率 ),那这样我们知道了路程(步距角),时间(定时器频率及比较匹配值),就可以计算速度了,但是我们需要将角度换算一下采用弧度制(我在设计的时候采用了 弧度制,且AVR446中采用的也是弧度制,这里是为了统一),rad =  π/180×角度,这里我们就能算出1rad ≈ 57.3°,那我们的 步距角 = (π / 180) x (1.8/div) div是步进细分数。设角速度为1rad/s 则  他等于 57.3°/s = (57.3/360)*60/min = 9.55r/min。具有以上知识后就可以将转速(r/min)转换到定时器的比较匹配值了,例如:在我的设计中单片机定时器的计数频率为250Khz、我希望电机运行在300r/min,步进驱动不细分,则有(1.8x(π/180))/(OCR/250000)=300/9.55  所以OCR =   (Fcnt * Math.PI) / (100 * Div * (StepSpeed / 9.55))其中Fcnt是定时器计数频率,Div是驱动细分,StepSpeed是转速。,其中,OCR下的实际电机频率为 Fcnt/OCR ,请自行推导一下,强化记忆。

2.SigMoid 曲线

曲线的原型是:

其值域是0~1,因此需要进行变形以便于使用,具体变形请参考文章开头的博客,这里不再赘述,仅做简单描述,可能形式略有不同但它们都是一样的。

关于中心点(a,b)对称的变形公式:

y = 2b / 1+E^(4k(a-x))

参数说明
中心点 (a,b)
过中心点时变化速率 k
y最大值是2b  b
改变a可以改变中心点的位置 a

其中需要注意的是,一般步进电机启动不会从0开始,而从某个频率开始启动,所以Y需要加上一个启动频率,正如文章前面博客中的公式一样,请各位自行理解体会里边的变形方法。

本设计采用VB.NET(.NEF FRAMEWORK 4.6.2)实现上位机生成一个加速数组,数组值就为比较匹配值,直接复制就能使用,界面设计如下:

设定好各个参数,点击生成,就能在右边的文本框中显示一个生成的数组,(生成速度受点数影响,技术太渣 还不会解决这个文本框显示过慢的问题),点击导出就能将文本框内容导出为.txt文件,方便使用。

示例,假设步进电机步距角为1.8°,步进驱动的细分为8,启动频率500Hz,计数器频率为250Khz,期望速度为500r/min,加速步数为1000.则有以下运行结果;

VB.NET核心代码实现如下:

    Dim img As New Bitmap(500, 500)Private Sub GeneratAcc_Click(sender As Object, e As EventArgs) Handles GeneratAcc.ClickDim G = Graphics.FromImage(img)'Dim G As Graphics = PictureBox1.CreateGraphics '定义picturebox 绘图Dim Gpen As New Pen(Color.Black, 1)     '定义笔参数Dim cnt As Integer = 0                  '循环数Dim OldX As Int32 = 0                   '保存前一次绘图坐标Dim OldY As Int32 = 500Dim tmpx As Single                      'X轴缩放因子Dim tmpy As Single                      'Y轴缩放因子dataTextBox1.Text = ""              '清零数组显示Fcnt = Val(TimFreBox.Text) * 1000   '获取定时器计数频率 单位HzMinFre = Val(StartFreBox.Text)      '最小启动频率Steps = Val(AccStepBox.Text)        '加减速步数Div = Val(DivBox.Text)              '获取驱动细分StepSpeed = Val(MaxSpeedBox.Text)   '获取最大速度Fle = Val(FleBox.Text)              '设置加速区间大小num = Steps / Val(NumBox.Text)      '设置曲线对称系数MaxFre = (Fcnt * Math.PI) / (100 * Div * (StepSpeed / 9.55)) '求出最大速度时匹配寄存器的值'MaxFre = (1.8 * Math.PI * Fcnt * StepSpeed) / (180 * 9.55 * Div)MaxFre = Fcnt / MaxFre              '求出设定的最大速度匹配值下的频率SpeedFre.Text = MaxFre & " Hz"tmpy = 500 / MaxFre '求出缩放因子tmpx = 500 / StepsDim mydata(Steps) As String'求解并绘出曲线For cnt = 0 To StepsFre = MinFre + ((MaxFre - MinFre) / (1 + Math.E ^ (-Fle * (cnt - num) / num))) '计算曲线频率数据mydata(cnt) = Math.Round(Fcnt / Fre) 'Convert.ToInt32(Fcnt / Fre)            '转化为OCR匹配值G.DrawLine(Gpen, OldX, OldY, cnt * tmpx, 500 - (Fre * tmpy)) '画线OldX = cnt * tmpx           '保存前一次绘图坐标OldY = 500 - (Fre * tmpy)PictureBox1.Image = imgNext'保存数组格式dataTextBox1.Text = "#define ACC_STEP_NUM " & Steps & vbCrLf & "unsigned short AccStep[ACC_STEP_NUM] = {"'dataTextBox1.Text = '保存数组格式ProgressBar1.Maximum = StepsProgressBar1.Visible = TrueFor cnt = 0 To StepsIf (cnt Mod 10) = 0 Then            '每10个数据一行dataTextBox1.Text += vbCrLfEnd IfIf cnt = Steps Then'dataTextBox1.Text += mydata(cnt)dataTextBox1.Text += "};"ElsedataTextBox1.Text += mydata(cnt) & ","End IfProgressBar1.Value = cntNextProgressBar1.Visible = FalseEnd Sub

在Arduino Uno(ATmega328)上的运行示例:

如同前面提到的,大数组不应该直接放到内存,而是放在程序存储空间中,以免Ram不足,在设计中采用16位定时器1计数频率为250Khz,CTC模式,加减速曲线对称,数组太长不贴。

#define ARR_MAX 3000
const  unsigned short AccStep[ARR_MAX] PROGMEM  = {*******} ;//生成的加减速数组
#define ACCEL   1    //电机运行状态标志位
#define DECEL   2
#define RUN     3
#define STOP   0
long step_count;    //步数计数
int acc_count;      //加速计数
int dcc_count;      //减速计数
uint8_t flag = STOP;//开始时的状态void SetSteps(long steps);                //设定电机步数及方向 正值代表正传 负值代表反转
void StepRun(void);                    //启动电机void SetSteps(long steps)
{if(steps<0){digitalWrite(2,0);      //设定电机运行方向step_count = -steps;    //赋值步数}else{digitalWrite(2,1);step_count = steps;}
}void StepRun(void)
{TCCR1B = (1<<WGM12)|(0<<CS12)|(1<<CS11)|(1<<CS10);  //16M / 250kHZOCR1A = 15; //随便开始一次中断 flag = ACCEL; //进入加速状态
}
/*定时器1 初始化*/
void Timer1Init(void)
{TCCR1A = 0;TCCR1B &= ~((1<<WGM12)|(0<<CS12)|(1<<CS11)|(1<<CS10));TIMSK1 = (1<<OCIE1A);OCR1A = 15;sei();
}
/*初始化*/
void setup() {// put your setup code here, to run once:
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);Timer1Init();
}
/*主循环*/
void loop() {// put your main code here, to run repeatedly:SetSteps(-16000);StepRun();delay(5000);
}
/*OCR1A 比较匹配中断 CTC 模式*/
ISR(TIMER1_COMPA_vect)
{switch(flag)  //查询状态{case STOP  :{TCCR1B &= ~((1<<WGM12)|(0<<CS12)|(1<<CS11)|(1<<CS10));acc_count =0;step_count = 0;dcc_count = 0;}break;case ACCEL :{acc_count++;step_count--;digitalWrite(3,1); //输出一个脉冲digitalWrite(3,0);OCR1A =  pgm_read_word_near(&AccStep[acc_count]);//查表if(acc_count == ARR_MAX-1) flag = RUN;}break;case RUN   :{step_count--;digitalWrite(3,1);digitalWrite(3,0);if(step_count == ARR_MAX-1) {flag = DECEL;dcc_count = ARR_MAX-1;}    }break;case DECEL :{dcc_count--;step_count--;digitalWrite(3,1);digitalWrite(3,0);OCR1A =  pgm_read_word_near(&AccStep[dcc_count]);if(acc_count == 0 || step_count==0) flag = STOP;}break;}
}

编译结果:

可以看到,数组已经不占用可怜的Ram了。

这个算法生产的加减速表用起来还可以,就是中间加速过程有点太猛了,有点像直接甩上去一样,可能是我设置的速度太高了,加速步数太短,在低速时,运行状态还算不错。

学无止境,到最后怎么运用到各个项目中,还的需要大量的实践。

对步进电机控制,机械臂正逆解感兴趣的朋友可以留言一起交流,搞点事情什么的。

每错!这是我第一篇博客,记录一下学到的一些知识。

2018.7.28 更新:需要注意的是,这里仅仅计算出了每个离散加速点的频率,实际使用中不可能每个频率点只发出一个脉冲,否则就像没有加速一样,解决的办法就是根据实际情况来调整每个频点发送的脉冲数,低频到高频脉冲数最好相应的也由少变多,这样可以改善加速效果。感谢各位评论让我发现不足的地方!

2018.8.06 更新: 看到回复中许多人对数组的使用方式存在疑问,并且之前我个人也存在误区认为每个频段只发 一个脉冲,实际上细想下来并不科学,例如我细分很大,5000,1.8度步距角,那么我转1.8度需要5000步,我加速点2000步 那加速 路程极短, 加速时间极短,那显然不符合逻辑, 查阅 一些资料发现,在加速时应该在每一个频段停留一段时间,或者说,每个频段多发一些脉冲,低频时脉冲少,高频时脉冲多,这里给大家提供几个思路,用来解决每个频段应该发多少脉冲的问题。首先我们根据以下数据生成曲线:步距角1.8°,细分8,定时器计数频率250K,启动频率600HZ ,最大转速500r/min,加速步数为600步。

第一种方法:将600个频段划分为10个部分,这10个部分的频段脉冲数分别为{5,5,10,10,20,20,30,30,40,40},这样每读取 一个频段就按该频段的步数发脉冲,当然这是一个想法、思路。需要注意的是,如果启动频率过低,或者低频时发出的脉冲太多将会影响加速时间,加速效果不好,所以应当合理选择启动频率和合理设计低频时的脉冲数。

第二种方法:这种方法是一种实时计算的方法,我目前正在测试,效果感觉良好,思路很简单,我添加一个加速时间的条件,然后将时间按自己需求离散为这个频段时间间隔,根据这个时间间隔以及频率可以轻易计算出这个频段的步数,比如我目前加速步数是600步,那么将加速时间设置为600ms,显然为了满足600ms的加速时间我可以简单暴力的将每个频段的持续时间划分为1ms,由已知条件计数频率以及当前频段的比较匹配值即可计算,按照以下公式即可,注意时间单位的换算。

那么根据我的已知条件,我的每个频段的脉冲为 = 250.0f / (float)OCR。具体看以下加速度段程序实现。

                 case ACCEL :{if(cstep==0){    cccv = 250.0f / (float)AccStep[acc_count];cstep = (cccv <= 1) ? 1 : ceil(cccv); OCR1A = AccStep[acc_count];acc_count++;if(acc_count==ARR_MAX-1) flag = RUN;}else{digitalWrite(3,1);step_count--;cstep--;digitalWrite(3,0);          }}break;

舍入函数看个人需求,ceil 或者floor 或者四舍五入,此算法解决频段脉冲数问题,并且需要给定加速时间,限制加速时间,算法还有优化空间,欢迎讨论,具体思路是高频段时间停留更久(目前是每个频段停留1ms,当然计算是有误差的,毕竟只能算出整数,控制加速时间在设定值附近吧),另外一个主意的问题是,在数组生成的最后几组中可能最高转速也包含在里边,根据需要可以适当修改数组,减少不必要的加速段。

20190125更新:实际上在中断里引入浮点运算是不可取的,在几个月前我已经找到了更好的计算每个频段应该发多少个脉冲的算法,只包含一个加法和比较,有时间再更新上来吧。

软件:https://download.csdn.net/download/renjiankun/10452200

测试视频:https://v.youku.com/v_show/id_XMzc2NzkyODg0OA==.html?spm=a2h3j.8428770.3416059.1

如有需要请移步最新软件,并支持一下小弟:

单片机步进电机加减速表生成软件_Renjiankun的博客-CSDN博客

步进电机S(SigMoid)曲线加减速【查表法】相关推荐

  1. 基于STM32F103的步进电机S型曲线加减速算法与实现

    步进电机是将电脉冲信号转变为角位移或线位移的开环控制电机,是现代数字程序控制系统中的主要执行元件,应用极为广泛.在非超载的情况下,电机的转速.停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的 ...

  2. 步进电机S型曲线加减速算法与实现

    转载于http://blog.csdn.net/pengzhihui2012/article/details/52228822?locationNum=6 一年前做过的S型曲线加减速算法,再次做的时候 ...

  3. 【龙印】步进电机使用七段式抛物线型S曲线加减速和路径规划的理论分析和实现

    本文为在用龙芯1c做3D打印机过程中的笔记.龙芯1c做的3d打印机简称"龙印",Git地址"http://git.oschina.NET/caogos/marlin_ls ...

  4. 基于51单片机+ULN2003控制步进电机S曲线加减速

    目录 1.ULN2003功能简介 2.28BYJ48简介 3.S曲线加减速方法 4.proteus仿真及实物测试 1.ULN2003功能简介 ULN2003比较简单,相关资料也比较多.可以用来驱动四线 ...

  5. “S“型曲线加减速在42步进电机的位置控制和速度控制中的交叉应用

    "S"型曲线加减速在42步进电机位置和速度交叉控制应用 兴趣使然,兴趣使然-哈哈,花了一个多星期研究了一下S型曲线在步进电机的加速减速中应用,以及简单的结合了一下位置控制和速度控制 ...

  6. c语言s型曲线方程,电机控制 | S曲线加减速

    S型曲线加减速 1.  S型曲线 1.1 简介 Sigmoid函数是一个在生物学中常见的S型函数,也称为S型生长曲线.Sigmoid函数也叫Logistic函数,取值范围为(0,1),它可以将一个实数 ...

  7. S曲线加减速算法 VS 梯形加减速算法

    设计运动控制系统很多年,突然有人问我S曲线加减速算法跟梯形加减速算法的区别,我竟然拼凑了很多语言都没能讲清楚.作为一个技术男怎能善罢甘休,但介于个人能力有限只能借用网上大牛的讲解搞清楚.苦苦搜索了三天 ...

  8. matlab生成s加减速曲线,一种基于移动平均算法的S曲线加减速控制方法与流程

    本发明属于运动控制领域,具体涉及一种基于移动平均算法的S曲线加减速控制方法. 背景技术: 加减速技术是数控系统的关键技术之一,算法的优劣直接决定着加工效率和加工精度.一种优秀的加减速算法既可以保证机床 ...

  9. matlab拟合s型加减速曲线,运动控制系统s曲线加减速的实现方法

    运动控制系统s曲线加减速的实现方法 [专利摘要]一种运动控制系统S曲线加减速的实现方法,1)S曲线加减速的实现条件:S曲线加减速控制过程的基本限定条件公式如公式(6):完整的S曲线加减速过程应满足公式 ...

最新文章

  1. application
  2. 守望者逃离 java_守望者的逃离 (Java代码)
  3. EOS入门指南PART6——别忙着开发,先来看看智能合约数据是怎么存的
  4. 审计 Linux 系统的操作行为的 5 种方案对比
  5. boost::mpl模块实现logical相关的测试程序
  6. java switch语句_Java 14:查看更新的switch语句
  7. ios 查询mysql数据库操作系统_iOS数据库FMDB--增删改查(模糊查询)详细介绍
  8. [css] position跟margin collapse这些特性相互叠加后会怎么样?
  9. echarts散点图搭配时间轴
  10. 注册表使用次数修改_如何使用系统注册表编辑器来优化电脑系统
  11. Qt只有release
  12. Linux(CentOS6.5)修改默认yum源为国内的阿里云、网易yum源
  13. JAVA的包装类 【转】
  14. X5内核视频之问答汇总
  15. 【你好,windows】windows7 x64x86旗舰完整版(带驱动包usb3.0_nvme)2020.1.22
  16. HTML5七夕情人节表白网页制作【花瓣图片表白】HTML+CSS+JavaScript html生日快乐祝福网页制作
  17. 输入身份证号判断性别并求年龄
  18. 俄罗斯方块游戏开发 ——图形化编程java swing 项目
  19. gem5运行SPECCPU2017benchmark
  20. C语言_if_查询分数等级

热门文章

  1. 浅谈 yso的 Commons-Collections1 (cc1)反序列化链 如何手写这条链子
  2. 虚拟现实vr技术靠哪些设备进行空间定位
  3. ALC、AGC、DRC、EQ对比
  4. 从案例图学习stateflow学习en、ex、du
  5. 每日新闻:互联网企业收入同比增近20%;阿里巴巴云计算收入增长101%;哈哈零兽完成融资数千万;Red Hat推出新版RHEL...
  6. 大数据入门--hadoop(三)--MR编程
  7. n级阶梯,每次走一步或两步,问最多有多少种走法
  8. Netty in Action 读书
  9. CeoMax总裁主题-如何对接QQ\微信\Google社交账户一键登录
  10. 2022年最新江苏建筑特种工(施工升降机)模拟题库及答案