极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 13620|回复: 0

关于ARDUINO 驱动步进电机是否真正的匀速旋转的问题

[复制链接]
发表于 2014-12-21 15:51:30 | 显示全部楼层 |阅读模式
本帖最后由 liweisgg 于 2014-12-21 15:53 编辑

鄙人近期写了部分驱动两相步进电机的测试程序,但是经过分析与实测,发现步进电机其实并没有真正的进行匀速运动,下面附出具体代码及说明,望和大虾们交流讨论。

[pre lang="arduino" line="1" file="步进测试"]
//The program name:        Stepper motor speed test v1.0
//The procedure function:  完成基本的匀速、加速、减速运动测试,转速为2.5rps
//The development board:   Arduino UNO

//#define STEP 4
//#define DIR 5
//#define EN 6
int STEP_PIN        =     4;
int DIR_PIN         =     5;
int EN_PIN          =     6;

int Microstep       =   200;          //驱动器细分设置值
int Cyc             =     1;          //电机旋转速度置值(rps)
int speed_a         =    40;          //电机角加速度(°/s2)
int count_s         =     0;

char var;
void setup(void)
{

pinMode(STEP_PIN , OUTPUT);
pinMode(DIR_PIN , OUTPUT);
pinMode(EN_PIN , OUTPUT);


Serial.begin(115200);
}

void uniform_speed_a()
{
  float       time_us_old;
  time_us_old  = 1*100000/(2*Cyc*Microstep);

  int time     = time_us_old;
  
  digitalWrite (DIR_PIN,HIGH);

  digitalWrite (STEP_PIN,HIGH);
  delayMicroseconds(time_us_old);
  digitalWrite (STEP_PIN,LOW);
  delayMicroseconds(time_us_old);
}

void uniform_speed_b()
{
  float       time_us_old;
  time_us_old  = 1*100000/(2*Cyc*Microstep);
  int time     = time_us_old;
  
digitalWrite (DIR_PIN,LOW);

digitalWrite (STEP_PIN,HIGH);
delay(1);
digitalWrite (STEP_PIN,LOW);
delay(1);
}

void up_speed_a()
{
float time_us_old;
float Cyc_new;
Cyc_new = Cyc +count_s*((speed_a/360)/200) ;   //计算出第二步相对于上一步的新转速
time_us_old = 1/(Cyc_new*Microstep)*1000000;   //time_us_old为每步的二分之一时间
int time_us = time_us_old;

digitalWrite (DIR_PIN,HIGH);

digitalWrite (STEP_PIN,HIGH);
delayMicroseconds(time_us);
digitalWrite (STEP_PIN,LOW);
delayMicroseconds(time_us);
count_s=count_s+1;
}

void up_speed_b()
{
float time_us_old;
float Cyc_new;
Cyc_new = Cyc +count_s*((speed_a/360)/200) ;   //计算出第二步相对于上一步的新转速
time_us_old = 1/(Cyc_new*Microstep)*1000000;   //time_us_old为每步的二分之一时间
int time_us = time_us_old;

digitalWrite (DIR_PIN,LOW);

digitalWrite (STEP_PIN,HIGH);
delayMicroseconds(time_us);
digitalWrite (STEP_PIN,LOW);
delayMicroseconds(time_us);
count_s=count_s+1;
}

void down_speed_a()
{
float time_us_old;
float Cyc_new;
Cyc_new = Cyc -count_s*((speed_a/360)/200) ;   //计算出第二步相对于上一步的新转速
time_us_old = 1/(Cyc_new*Microstep)*1000000;   //time_us_old为每步的二分之一时间
int time_us = time_us_old;

digitalWrite (DIR_PIN,HIGH);

digitalWrite (STEP_PIN,HIGH);
delayMicroseconds(time_us);
digitalWrite (STEP_PIN,LOW);
delayMicroseconds(time_us);
count_s=count_s+1;
}

void down_speed_b()
{
float time_us_old;
float Cyc_new;
Cyc_new = Cyc -count_s*((speed_a/360)/200) ;   //计算出第二步相对于上一步的新转速
time_us_old = 1/(Cyc_new*Microstep)*1000000;   //time_us_old为每步的二分之一时间
int time_us = time_us_old;

digitalWrite (DIR_PIN,LOW);

digitalWrite (STEP_PIN,HIGH);
delayMicroseconds(time_us);
digitalWrite (STEP_PIN,LOW);
delayMicroseconds(time_us);
count_s=count_s+1;
}

void loop()
{
//   int number;
//   number=400;
   EN_PIN=0;
   if(Serial.available()>0)//如果串口有数据进入的话
     {
      var=Serial.read();//读字符,是ASCII码的
     }
     if (var=='1')
     {
      uniform_speed_a();
     }
     if (var=='2')
     {
      uniform_speed_b();
     }
      if (var=='3')
     {
      up_speed_a();
     }
     if (var=='4')
     {
      up_speed_b();
     }
     if (var=='5')
     {
      down_speed_a();
     }
     if (var=='6')
     {
      down_speed_b();
     }
}[/code]

上边的代码我大概解释下,因为我用的是混合式步进电机,所以采用了其自带的步进电机驱动,驱动器的信号输入STEP_PIN、DIR_PIN 、EN_PIN 分别为脉冲信号、方向信号和使能信号,也就是说我只要控制好STEP_PIN引脚高低电平的变化频率便可以控制步进电机的旋转速度了,那么只要我的delay(time)延时函数给定,那么这个步进电机就应该是匀速运动了。

电机驱动器可以设置步进电机的细分,我这里设置为200细分,也就是说STEP_PIN信号脚200个变化周期步进电机便旋转一圈,速度由我的delay延时函数控制。

我的步进电机后边是加装1000线的编码器的,为什么说步进电机不是匀速,便是由编码器返回的差分信号看出来的,我用示波器看到了差分信号并不是恒定周期的,而是大概若干个恒定周期之后,会出现一个周期略长的缓冲周期,然后如此往复循环。

这里我认为是每一段代码都是有机器周期的,比如匀速子函数:
void uniform_speed_a()
{
  float       time_us_old;
  time_us_old  = 1*100000/(2*Cyc*Microstep);

  int time     = time_us_old;
  
  digitalWrite (DIR_PIN,HIGH);

  digitalWrite (STEP_PIN,HIGH);
  delayMicroseconds(time_us_old);
  digitalWrite (STEP_PIN,LOW);
  delayMicroseconds(time_us_old);
}

中,
  digitalWrite (STEP_PIN,HIGH);
  delayMicroseconds(time_us_old);
  digitalWrite (STEP_PIN,LOW);
  delayMicroseconds(time_us_old);
为脉冲信号输出代码,但是该子程序中运行脉冲信号输出之前总要先运行
float       time_us_old;
  time_us_old  = 1*100000/(2*Cyc*Microstep);

  int time     = time_us_old;
这三行程序,这样,其实步进电机就无法做到真正的匀速运动了,它包含了三条代码的机器时间。


大虾们,关于这样的解释是否正确?我该如何让步进电机做到真正的匀速运动?后边我的程序还有加入编码器的闭环控制,但是关于步进加减速子函数还会有一些问题,以及编码器测速后的串口速度值输出显示也有一些问题,这个后续可以在讨论。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-17 00:39 , Processed in 0.063142 second(s), 17 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表