步进电机的加减速_步进电机电机加减速 - CSDN
精华内容
参与话题
  • 步进电机S型曲线加减速算法与实现

    万次阅读 多人点赞 2016-08-17 20:49:51
    一年前做过的S型曲线加减速算法,再次做的时候竟然犯错,在此总结记录一下,方便...如要将此曲线应用在步进电机减速过程中,需要将方程在XY坐标系进行平移,同时对曲线进行拉升变化: 其中的A分量在y方向进行平移

    一年前做过的S型曲线加减速算法,再次做的时候竟然犯错,在此总结记录一下,方便以后查阅,同时希望帮助初学者提供简单的参考资料(注:本项目采用的带细分的驱动器,MCU的OC比较输出模块产生50%的PWM方波)。

    S型曲线的的方程,在[-5,5]的图形如下图所示:

    如要将此曲线应用在步进电机的加、减速过程中,需要将方程在XY坐标系进行平移,同时对曲线进行拉升变化:

    其中的A分量在y方向进行平移,B分量在y方向进行拉伸,ax+b分量在x方向进行平移和拉伸。

    项目中加速过程:从5600Hz加速到64000Hz,采用4细分。输出比较模块所用的定时器驱动频率为10M,采用1000个点进行加速处理。最终根据项目的需要,在加速过程中采用的曲线方程为:

    其中的Fcurrent为length(1000)个点中的单个频率值。Fmin起始频率为5600; Fmax为最大频率64000;  -flexible*(i - num)/num是对S型曲线进行拉伸变化,其中flexible代表S曲线区间(越大代表压缩的最厉害,中间(x坐标0点周围)加速度越大;越小越接近匀加速。理想的S曲线的取值为4-6),i是在循环计算过程中的索引,从0开始,num为 length/2 大小(这样可以使得S曲线对称)。在项目中i的区间[0,1000), num=1000/2=500。这些参数均可以修改。提供的计算接口如下。

    对应的计算接口code:

    /*  calculate the Period and Freq array value, fill the Period value into the Period register during the timer interrupt.

    *calculate the acceleration procedure , a totally 1000 elements array.

    * parameter    fre[]: point to the array that keeps the freq value.

    *   period[]: point to the array that keeps the timer period value.

    *   len: the procedure of acceleration length.it is best thing to set the float number, some compile software maybe transfer error if set it as a int

    *   fre_max: maximum speed, frequency vale.

    *   fre_min: start minimum speed, frequency vale.  mind : 10000000/65535 = 152, so fre_min can't less than 152.

    *   flexible:  flexible value. adjust the S curves

    */

    void CalculateSModelLine(float fre[],  unsigned short period[],   float  len,  float fre_max,  float fre_min, float flexible)
    {
        int i=0;
        float deno ;
        float melo ;
        float delt = fre_max-fre_min;
        for(; i<len; i++)
        {
            melo = flexible * (i-len/2) / (len/2);
            deno = 1.0 / (1 + expf(-melo));   //expf is a library function of exponential(e) 
            fre[i] = delt * deno + fre_min;
            period[i] = (unsigned short)(10000000.0 / fre[i]);    // 10000000 is the timer driver frequency
        }


        return ;
    }


    // start move motor

    void StartPWM()
    {
        DriverMotorFlag = TRUE;
        Index = 0;
        
        MOTOR_EN_DISABLE = ENABLE;
        OpenOC4(OC_ON | OC_TIMER_MODE16 | OC_TIMER3_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0);


        // map rc13 to oc4 output
        RPC13R = 11;


        // 50 percent duty
        OC4RS = OC_PERIOD_MIN / 2;
        OpenTimer3(T3_ON | T3_PS_1_8, OC_PERIOD_MIN);


        INTSetVectorPriority(INT_TIMER_3_VECTOR, INT_PRIORITY_LEVEL_6);
        INTSetVectorSubPriority(INT_TIMER_3_VECTOR, INT_SUB_PRIORITY_LEVEL_1);
        EnableIntT3;
    }


    //stop motor, hereis no deceleration 

    void StopPWM()
    {
        DriverMotorFlag = FALSE;
        Index = 0;
        
        MOTOR_EN_DISABLE = DISENABLE;
        OpenOC4(OC_OFF | OC_TIMER_MODE16 | OC_TIMER3_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0);
        // map rc13 to oc4 output
        RPC13R = 0;
        PORTCbits.RC13 = 0;
        
        CloseTimer3();
        DisableIntT3;
    }


    //change the timer Period value in the correspond timer rather than the other place, Or the motor will be stalled occasionally.

    // 刚开始我在另外的一个定时器中断中每隔1ms改变 应用在OC模块的timer3 的Period值,结构偶发的造成电机在加速过程中堵转。其实应该是在timer3的中断中修改。

    static unsigned short CountForAcc = 0;
    void __ISR(_TIMER_3_VECTOR, ipl6) Timer3OutHandler(void)
    {
        // clear the interrupt flag, or the interrupt will not occur again.
        mT3ClearIntFlag();

        if(CountForAcc++ > 2)    // here can adjust the totally time of acceleration
        {
            CountForAcc = 0;
            //if(DriverMotorFlag == TRUE && PR3 > OC_PERIOD_MAX + SPEED_STEP)
            if(DriverMotorFlag == TRUE && Index < ACC_TIMES)
            {
                PR3 = Period[Index++];
                OC4RS = PR3 / 2;
            }
        }
    }

    通过CalculateSModelLine接口得到如下不同的几条加速曲线:

    黄色:CalculateSModelLine(Freq, Period, 1000, 56000, 16000, 4);

    橙色:CalculateSModelLine(Freq, Period, 1000, 64000, 500, 8);

    蓝色:CalculateSModelLine(Freq, Period, 1000, 64000, 500, 15);

    灰色:CalculateSModelLine(Freq, Period, 1000, 40000, 500, 5);


    最后可以估算加速过程的时间和角位移,以橙色曲线为例:CalculateSModelLine(Freq, Period, 1000, 64000, 500, 8)为例(假设在中断中没有  if(CountForAcc++ > 2)  条件限制):

    时间:Period第一个点的值为10000000/500 = 20000,最后也点的值 10000000/64000=156,平均值为10000左右,timer中断的平均时间Tn=10000/10000000=1ms, 1000个点,总时间为1s,当然,起始频率大加速时间就越短,比如Fmin=16000Hz,Fmax=64000,则40ms左右即可完成加速过程。

    角位移:1.8(单步) * 1000(步数) / 4(细分)= 450°

    上述为加速过程,减速同样的道理,只要将方程改为: 

    可以得到减速曲线如下所示:

    以上为实际的项目数据,欢迎各位指正。





    展开全文
  • 一、加减速控制曲线 直线(梯形)加减速曲线--图略...《几种步进电机加减速方法的对比研究及其应用》-------算法原理《基于STM32的步进电机S形加减速控制曲线的快速实现方法》 -- 很实用,,,其他 --- 找度娘去.....

    一、加减速控制曲线

    • 直线(梯形)加减速曲线--图略
    • 指数型加减速曲线       --图略
    • S型加减速曲线           --图略

    二、参考资料

    • 《几种步进电机加减速方法的对比研究及其应用》-------算法原理
    • 《基于STM32的步进电机S形加减速控制曲线的快速实现方法》 --  很实用,,,
    • 其他 --- 找度娘去.....

    网盘资源下载--步进电机

    展开全文
  • 步进电机加减速——梯形算法

    千次阅读 2019-07-15 14:05:48
    1.声明 1、这是我第一篇博客文章,如有错误请各位...步进电机加减速算法目的:对于上述2、3的场合,步进电机容易出现丢步和过冲甚至无法启动的现象,所以加入该算法来解决这一问题。 3. 算法实现 3.1加减速期望曲线...

    1.声明

    1、这是我第一篇博客文章,如有错误请各位大佬指点,谢谢。
    2、该篇文章是适合了解了步进电机基础原理的学习者阅读。

    2.目的

    使用要求与场合: 1、步进电机
    2、速度变化较大
    3、启动停止频繁
    步进电机加减速算法目的:对于上述2、3的场合,步进电机容易出现丢步和过冲甚至无法启动的现象,所以加入该算法来解决这一问题。

    3. 算法实现

    3.1加减速期望曲线

    如图1所示,该曲线是期望的加减速曲线。横坐标t为时间,纵坐标ω为速度。以下三个参数有开发者设定。
    accel:加速度
    decel:减速度
    step:总行程
    在这里插入图片描述
    图1

    3.2速度与脉冲周期有何关系

    电机的调速与脉冲周期是有关系的,并且是正比例关系,脉冲周期越长,步进电机转速越慢。
    在梯形加速过程,速度变化是直线的,将该曲线截取加速过程放大并加入脉冲,如图2所示。
    在这里插入图片描述
    图2
    图中t0到t1这段时间为第一个脉冲的时间,t1到t2为第二个脉冲的时间
    C0为第一个脉冲的定时器计数值
    tt为定时器的计数周期,也就是频率的倒数
    距离=速度*时间
    每给一个脉冲,步进电机行走一步,这时候步进电机旋转的角度称为步距角,用α表示,单位为弧度。
    所以图2中每个长方形的面积就是一个步距角,所以每个长方形面积相等。

    3.3位置与加速度的关系

    根据牛顿定律位移S=V0t+1/2at²,由于步进电机启动初始速度为0,所以公式变成S=1/2at²。在这里用ω’表示加速度。所以公式变成S=1/2ω’t²。由于已知步距角和脉冲数(n),所以S=αn。
    从而得到1/2ω’t²=α
    n

    3.4脉冲周期与脉冲数和加速度的关系

    由于t表示从t0到tn的时间,由于t0为0,所以tn=t,通过转换,tn与加速度的关系如下:
    tn=√(2*n *α/ω’)­­­
    所以Cntt=t(n+1)-tn=(√(n+1)-√n)*√(2α/ω’)
    得到Cn=1/tt *(√(n+1)-√n)*√(2α/ω’)
    由上述的推导得到Cn与加速度和脉冲数和加速度的关系,因此可以求得在加速过程或者减速过程脉冲的周期。

    3.5何时减速

    得到了加减速度和脉冲周期的关系后还需要考虑电机什么时候开始减速。

    3.5.1斜率与脉冲数的关系

    如图3所示
    在这里插入图片描述
    图3
    n1:加速需要的脉冲数
    n2:减速需要的脉冲数
    ω’1:加速度
    ω’2:减速度
    斜率(K)=y/x,所以y=K*x,在图3中,由于该三角形高相等,所以n1 * ω’1=n2 * ω’2
    为了方便后面计算,等式左右两边加上n1 * ω’2,得到n1 * ω’1+n1 * ω’2=n2 * ω’2+n1 * ω’2
    最终得到n1=(n1+n2)*ω’2/(ω’1+ω’2)

    3.5.2实际曲线另外一种情况

    在实际的运动中,梯形曲线并不一定是图1那样,还有另外一种情况,如图4所示。
    在这里插入图片描述
    图4
    该图显示实际最大速度未达到设定最大速度。
    accle_lim:实际加速运动的脉冲数
    max_s_lim:达到设定最大速度需要的脉冲数
    根据公式n1=(n1+n2)*ω’2/(ω’1+ω’2)可以得到accle_lim=(step *decle)/(accel+decel)
    根据公式n *ω’=ω’n/2 *α可以得到max_s_lim=n=speed *speed/(2 *α *accel)
    从数学角度将模型的两种情况分为了accle_lim>max_s_lim的和accle_lim<max_s_lim这两种情况,而开始减速时间decel_val也会变得不同
    1.accle_lim>max_s_lim
    decel_val=(max_s_lim *accel)/decel
    2.accle_lim<max_s_lim
    decel_val=step-accle_lim

    4.结论

    通过上面的分析与计算得出了两个关系
    1、加减速度和脉冲周期的关系
    2、减速开始时刻

    展开全文
  • 步进电机S(SigMoid)曲线加减速【查表法】

    万次阅读 多人点赞 2019-01-25 17:40:38
     首先在本设计中采用的步进电机控制方案为,单片机+16位定时器比较匹配中断(最好是16位及其以上)+步进电机驱动+42步进电机。较高的定时器精度能够实现更好的控制。  在步进电机控制中往...

        首先感谢以下博客的博主提供的参考公式: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.Click
            Dim 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 = 500
            Dim tmpx As Single                      'X轴缩放因子
            Dim tmpy As Single                      'Y轴缩放因子
    
            dataTextBox1.Text = ""              '清零数组显示
    
            Fcnt = Val(TimFreBox.Text) * 1000   '获取定时器计数频率 单位Hz
            MinFre = 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 / Steps
    
            Dim mydata(Steps) As String
            '求解并绘出曲线
            For cnt = 0 To Steps
    
                Fre = 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 = img
            Next
            '保存数组格式
            dataTextBox1.Text = "#define ACC_STEP_NUM " & Steps & vbCrLf & "unsigned short AccStep[ACC_STEP_NUM] = {"
            'dataTextBox1.Text = 
            '保存数组格式
    
            ProgressBar1.Maximum = Steps
            ProgressBar1.Visible = True
            For cnt = 0 To Steps
                If (cnt Mod 10) = 0 Then            '每10个数据一行
                    dataTextBox1.Text += vbCrLf
                End If
    
                If cnt = Steps Then
                    'dataTextBox1.Text += mydata(cnt)
                    dataTextBox1.Text += "};"
                Else
                    dataTextBox1.Text += mydata(cnt) & ","
                End If
                ProgressBar1.Value = cnt
            Next
            ProgressBar1.Visible = False
        End 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 / 250kHZ
    	OCR1A = 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

    展开全文
  • 比较几种步进电机加减速控制方案

    千次阅读 2019-11-08 11:25:57
    加减速算法是运动控制中的关键技术之一,也是实现高速、高效率的关键因素之一。...当前运动控制系统中常用的减速算法主要有:梯形曲线加减速、S形曲线加减速、指数曲线加减速、抛物线曲线加减速等。 ...
  • 步进电机减速控制

    千次阅读 2016-02-29 15:09:42
    几种步进电机加减速方法的对比研究及其应用 http://www.docin.com/p-425915619.html 51单片机步进电机加速减速匀速演示 步进电机的加速减速 简单介绍几种控制步进电机加减速的方法
  • 步进电机的线速度控制

    万次阅读 2017-08-08 11:16:50
    AVR446:步进电机的线速度控制特征: 步进电机线速度控制 -控制加速、减速、最大速度运行的步数 通过一个定时器驱动 全步/半步驱动模式 支持所有带16位定时器的AVR设备 演示程序使用的是处理器ATmega48(8位AVR...
  • 步进电机选型的计算方法

    千次阅读 2017-10-19 09:58:07
    原文地址:步进电机选型的计算方法作者:三拓电气  随着工业自动化水平的不断提高,步进及伺服技术在各个领域的应用程度也在不断提升,步进电机和伺服电机越来越多的被用来替代传统的控制方式。而对于步进及伺服...
  • 步进电机减速电机的区别

    千次阅读 2017-08-07 13:10:19
    摘要: 在回答这个问题之前,先来了解下什么是步进电机减速电机?  步进电机是将电脉冲信号转变为角位移或线位移的开环控制元步进电机件。在非超载的情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲...
  • STM32F103步进电机梯形匀加速算法

    千次阅读 2019-04-17 08:45:14
    最近公司的一个项目用带驱动器的步进电机,奈何,经理让我搞个匀加速的启动和停止。以前从来没考虑过算法的我,走了很多弯路,不过最后还是解决了这个问题。 梯形加减速应该是指数加速算法和S型加速算法中最简单也...
  • fpga实现了脉冲发生器,s型加减速

    千次阅读 2017-06-04 01:42:54
    基础单元还是FPGA实现好一点,复杂的算法dsp或者arm来实现。不过也有全部用arm实现的。
  • 减速电机和步进电机小车

    千次阅读 2018-10-09 12:56:04
  • STM32步进电机加减速

    千次阅读 2017-09-13 16:11:40
    电机加减速为了,电机启动停止更加稳定,提高匀速速度。S曲线算法优化电机的运行。 整个过程就是,模仿S曲线设置电机的频率 程序采用,通过s_curve()函数映射一张小于1500个点的表, 输出一次pwm方波,中断...
  • 步进电机 - 转速与转矩特性(三)

    千次阅读 2020-07-16 09:07:49
    步进电动机转速-转矩特性图。 ■励磁最大静止转矩(TH) 通电状态下,电动机停止时可产生的最大自我保持力。 电动机停止时,因自动电流下降功能启动,约下降到50%。 ■最大同步转矩 各种运转速度下,能够进行运转...
  • 讲一下普通电机,减速电机、步进电机,舵机伺服电机指的是直流电的微型电机,平常我们接触到的也以直流电的居多。普通电机 普通电机是我们平时间的比较多的电机,电动玩具,刮胡刀等里面都有,一般为直流有刷电机。...
  • 步进电机失步(丢步)的原因和对策步进电机可以根据脉冲数和脉冲频率来对电机实现开环控制位置和速度,是一种便宜、简单好用的控制类电机,在自动化控制领域得到越来越广泛的应用。但由于步进电机不是闭环控制,选型...
  • 实验目的:利用Arduino+TB6600驱动模块控制两相四线42减速步进电机 材料: Arduino Nano *1 TB6600驱动器 *1 42减速步进电机*1 面包板 *1 12V电源适配器*1 导线 若干 接线: 12V电源适配器正负极分别接驱动器VCC...
  • 51单片机控制电动机正反转和调速

    万次阅读 多人点赞 2018-06-14 11:05:59
    经过不断地摸索和参考高手的设计,最终完成了单片机的步进电机控制,可以实现步进电机的实时正反转,加速,减速。  至于步进电机的工作原理,相信很多人都已经知道,本次采用的是四相步进电机,采用四相八拍的工作...
  • 步进电机 简介: 步进电机和直流电机 一样都是 将电能转换成机械能。步进电机将电脉冲转换成特定的旋转运动,每个脉冲所产生的运动是精确的,并可重复。通俗的讲就是,我们给步进电机 一个脉冲减速牙箱,...
  • http://blog.csdn.net/firestarway/article/details/51226701 不正确地驱动步进电机很容易导致电机发出“嗡嗡”的噪声和很大的振动。当驱动步进电机时,如果发现步进电机处于静止状态时,其内部都发出很明显的噪
1 2 3 4 5 ... 20
收藏数 1,044
精华内容 417
关键字:

步进电机的加减速