JasmineL 发表于 2013-4-23 21:41:16

请问Arduino如何同时驱动两个步进电机,分别走不同步数?(使用TB6560驱动)

本帖最后由 JasmineL 于 2013-4-23 21:42 编辑

http://www.geek-workshop.com/forum.php?mod=viewthread&tid=3266
我使用了了大连好人写的库函数,链接在上面
现在的主要问题是两个步进电机可以以不同速度运行,但是是同时开始同时停。
时间以运行时间长的步进电机为主,另一个步进电机走的比输入进去的步数多。

目前我能想到的解决办法是:在相同时间内,两个步进电机以一定比例的速度运行,以期盼能得到成比例的步数。
但又发现一个问题,如果比例较大,例如步数比为8:1时,一个电机转8圈的时候,另一个电机会转的比1圈多大概30度。
也就是说,速度成比例的时候,步数不完全成这个比例,转的数量少的时候,不明显,多了就不行了.....

求问大家,怎样才能同时驱动两个步进电机,且让他们走不同的步数...

我的代码如下:

//1,2电机以不同速度转动相同步数

#include <EasyStepper.h>
#define STEP1_PIN 2
#define STEP2_PIN 4
#define DIR1_PIN 6
#define DIR2_PIN 8
#define EN1_PIN 12
#define EN2_PIN 13//两个EN端悬空
#define DIR1_PIN_INVERTED true
#define DIR2_PIN_INVERTED true
#define EN1_PIN_INVERTED true
#define EN2_PIN_INVERTED true
EasyStepper stepper1(STEP1_PIN, DIR1_PIN, EN1_PIN, DIR1_PIN_INVERTED, EN1_PIN_INVERTED);
EasyStepper stepper2(STEP2_PIN, DIR2_PIN, EN2_PIN, DIR2_PIN_INVERTED, EN2_PIN_INVERTED);
int times=0;
int stepps=0;
void setup()
{
Serial.begin(9600);
stepper1.debugMode(false);
stepper1.startup();
stepper2.debugMode(false);
stepper2.startup();
}
void loop(){
if (Serial.available() > 0)
{
      stepps=Serial.parseInt();
      Serial.println(stepps);
      stepper1.rotate(400.0,stepps/2);
      stepper2.rotate(50.0,-stepps/2);
}
    while(stepps!=0)
    {
   
      if (times < 2)
      {
      stepper1.run();
      if (stepper1.isDone())
      {      
      // go back
      stepper1.rotate(400.0,stepps/2);
      Serial.println("Iner1"+times);
         }
      stepper2.run();
      if (stepper2.isDone())
      {      
      // go back
      stepper2.rotate(50.0,-stepps/2);
      times++;
      Serial.println("Iner2"+times);
         }
         if(times==2)
          {
            stepps=0;
            times=0;
          }
       }
       Serial.println("Outer"+times);
}}

gjfhahaha 发表于 2013-4-23 23:27:36

找出问题了

      if (times < 2)
      {
      stepper1.run();
      if (stepper1.isDone())
      {      
      // go back
      stepper1.rotate(400.0,stepps/2);
      Serial.println("Iner1"+times);
         }
      stepper2.run();
      if (stepper2.isDone())
      {      
      // go back
      stepper2.rotate(50.0,-stepps/2);
      times++;
      Serial.println("Iner2"+times);
         }
         if(times==2)
          {
            stepps=0;
            times=0;
          }

看黑体代码部分,函数 .run是走一小步的意思, 每次step1走一小步,然后判断走完没有,然后step2再走一小步,然后再判断step2走完没有.

如果step1走完, 就继续走stepps/2步(对time和step2都没有影响), 只有等step2走完,time才加1.
只有time加到2, 才跳出函数,大家同时不走了.

所以导致的结果是,无论step1速度是多少,要走多少步,可是两个马达运行的时间都是以step2的设置为主

现在你知道应该怎么改你的程序了吧


JasmineL 发表于 2013-4-24 01:04:05

gjfhahaha 发表于 2013-4-23 23:27 static/image/common/back.gif
找出问题了

      if (times < 2)


谢谢高手~明白错在哪了,可还是不知道能怎么改....

因为run需要一个循环才能一直执行,两个步进电机如果想同时动,应该是要写在同一个循环里面的吧?

那循环的跳出方式用什么呢?

JasmineL 发表于 2013-4-24 01:42:52

gjfhahaha 发表于 2013-4-23 23:27 static/image/common/back.gif
找出问题了

      if (times < 2)


我是这么改的,还没经过测试,不知道对不对?
//1,2电机以不同速度转动相同步数

#include <EasyStepper.h>
#define STEP1_PIN 2
#define STEP2_PIN 4
#define DIR1_PIN 6
#define DIR2_PIN 8
#define EN1_PIN 12
#define EN2_PIN 13//两个EN端悬空
#define DIR1_PIN_INVERTED true
#define DIR2_PIN_INVERTED true
#define EN1_PIN_INVERTED true
#define EN2_PIN_INVERTED true
EasyStepper stepper1(STEP1_PIN, DIR1_PIN, EN1_PIN, DIR1_PIN_INVERTED, EN1_PIN_INVERTED);
EasyStepper stepper2(STEP2_PIN, DIR2_PIN, EN2_PIN, DIR2_PIN_INVERTED, EN2_PIN_INVERTED);
int times=0;
int stepps=0;
void setup()
{
Serial.begin(9600);
stepper1.debugMode(false);
stepper1.startup();
stepper2.debugMode(false);
stepper2.startup();
}
void loop(){
if (Serial.available() > 0)
{
      stepps=Serial.parseInt();
      Serial.println(stepps);
      stepper1.rotate(400.0,stepps);
      stepper2.rotate(400.0,-stepps);
}
    while(stepps!=0)
    {
   
      if (times < 1)
      {
      if (stepper1.isDone()==false)
      {      
            stepper1.run();
      }
      if (stepper2.isDone()==false)
      {      
            stepper2.run();
      }
      if(stepper1.isDone()&&stepper2.isDone())
      {
          times=1   
          stepps=0;
          times=0;
         
         }
      }
    }
}

xmdesign 发表于 2013-4-24 07:26:00

直线插补,我发过个帖CNC用的GCode_Interpreter,参考里面的插补方式

gjfhahaha 发表于 2013-4-24 16:12:28

JasmineL 发表于 2013-4-24 01:42 static/image/common/back.gif
我是这么改的,还没经过测试,不知道对不对?

times 这个变量貌似没用了吧

JasmineL 发表于 2013-4-24 18:52:15

gjfhahaha 发表于 2013-4-24 16:12 static/image/common/back.gif
times 这个变量貌似没用了吧

是这样的,我实际用的时候,是没有while(stepp!=0)这一个循环的,因为两个电机走的步数是经过计算后得出的,不是这个测试程序这么简单,写的时候疏忽了~~现在程序已改正了

JasmineL 发表于 2013-4-24 18:58:49

贴上个主程序里试验成功的函数吧,竖直平面内从现有位置移动到另一位置void xyMove(float dest_x,float dest_y)
{
init_a=float(sqrt(pow(init_x,2)+pow(init_y,2)));
init_b=float(sqrt(pow(D-init_x,2)+pow(init_y,2)));
dest_a=float(sqrt(pow(dest_x,2)+pow(dest_y,2)));
dest_b=float(sqrt(pow(D-dest_x,2)+pow(dest_y,2)));

da=dest_a-init_a;
db=dest_b-init_b;
//a,b电极旋转的正方向不同,去了再看,某个的da需要*-1
//记得试一试两电机同转,但符号不同的时候,是否方向相反
   
step_a=fabs(da*step_per_cm+0.5);
   step_b=fabs(db*step_per_cm+0.5);//四舍五入
   times=0;//电极需要初始化,以保证连续运动
    if(step_a>=step_b)
   {
       speed_a=spd;
       speed_b=(step_b*1.0/step_a)*spd;
   }
   else
   {
   speed_b=spd;
   speed_a=(step_a*1.0/step_b)*spd;
   }
   if(da<0)
   step_a=step_a*(-1);
   if(db<0)
   step_b=step_b*(-1);
   
   stepper1.rotate(speed_a,-step_a);
   stepper2.rotate(speed_b,step_b);
   
   times=0;
   while (times < 1)
   {
      if (stepper1.isDone()==false)
      {      
            stepper1.run();
      }
      if (stepper2.isDone()==false)
      {      
            stepper2.run();
      }
      if(stepper1.isDone()&&stepper2.isDone())
      {
          times=1;
      }
    }
   
   init_x=dest_x;
   init_y=dest_y;

}

rick_hou 发表于 2013-4-24 23:40:04

xmdesign 发表于 2013-4-24 07:26 static/image/common/back.gif
直线插补,我发过个帖CNC用的GCode_Interpreter,参考里面的插补方式

您发的那个Gcode的程序我想知道怎么用,很感兴趣。

xmdesign 发表于 2013-4-25 07:18:08

串口(Serial.begin(19200);)键入G代码
1:G90 绝对坐标方式(G91为增量坐标方式)
2:G1 F3000 运行速度(F1~X)
3:X10 Y20 Z50移动目标坐标
4: M代码你发现其实可以你自己定义,比如打开或者关闭某个端口等
等等 G代码

rick_hou 发表于 2013-4-25 11:48:29

xmdesign 发表于 2013-4-25 07:18 static/image/common/back.gif
串口(Serial.begin(19200);)键入G代码
1:G90 绝对坐标方式(G91为增量坐标方式)
2:G1 F3000 运行速度 ...

嗯,我正在改造我的小铣床,现在是做了个手动/自动走刀,控制xy两轴,z轴改动量比较大我就没改,我想实现雕刻或者铣平面的的工作,一直在找gcode的解释程序,您给的那个程序我下来看了下,觉得不错。就是不太清楚怎么写程序。

阴霾の微笑 发表于 2014-8-6 13:37:57

回复做个笔记,有空研究下,谢谢楼主

sjiliang 发表于 2016-3-1 11:06:51

英文不好,打开相应链接就糊涂了。库文件下载,安装以及历程理解一直困扰。请不吝赐教;详尽些更好。

csmingbaby 发表于 2018-8-20 13:39:23

楼主可以发份源码吗!对我来说很有参考价值!([email protected]

:lol顺便问一下arduino最多可以实现同时控制多少个步进马达??
页: [1]
查看完整版本: 请问Arduino如何同时驱动两个步进电机,分别走不同步数?(使用TB6560驱动)