在具有独立分配提示的两个步进器之间过渡



我将使用两个步进电机,两个简易驱动器,一个arduino uno。每个步进电机都有前后旋转的齿轮。首先,我想为每个步进器分配多个旋转提示。如

int step1cue1 = 329
int step1cue2 = 582
int step1cue3 = 1038
int step1 cue4 = 1790
...
int step2cue1 = 568
int step2cue2 = 1004
int step2cue3 = 1928
int step2cue4 = 3592
...
and each stepper needs minimum 0 and maximum value, such as,
int step1maxcue = 8372
int step2maxcue = 8421

each rotation speed and acceleration need to be set and controllable as well.
I would like to use rotation speed = 0 to make the stepper stopped at the cue.

**操作

两个步进器都从 0 开始,首先,stepper1 从其 step1cues 中旋转到随机选择的提示,当它几乎到达所选提示时,stepper2 开始旋转到从 step2cues 中随机选择的提示。(步进器1在提示处停止,速度=0),当步骤2几乎到达其提示时,步进器1开始旋转到另一个随机选择的步骤1cue(不是当前提示)。(步进器2停止,速度=0)。并在两个步进器之间重复此转换。

你能帮我写这段代码吗?

我想使用下面的代码,

#include <AccelStepper.h>
// Define two steppers and the pins they will use
AccelStepper stepper1(1, 9, 8);
AccelStepper stepper2(1, 7, 6);
int pos1 = 3600;
int pos2 = 5678;
void setup()
{  
  stepper1.setMaxSpeed(3000);
  stepper1.setAcceleration(1000);
  stepper2.setMaxSpeed(2000);
  stepper2.setAcceleration(800);
}
void loop()
{
  if (stepper1.distanceToGo() == 0)
  {
        pos1 = -pos1;
    stepper1.moveTo(pos1);
  }
  if (stepper2.distanceToGo() == 0)
  {
    pos2 = -pos2;
    stepper2.moveTo(pos2);
  }
  stepper1.run();
  stepper2.run();
}
我不知道

AccelStepper 库,所以我可能是错的,但这应该按照您的要求:

#include <AccelStepper.h>
// With matrices it's easier
const int step1cues[] = { 329,  582, 1038, 1790 ...};
const int step2cues[] = { 568, 1004, 1928, 3592 ...};
// Define two steppers and the pins they will use
AccelStepper stepper1(1, 9, 8);
AccelStepper stepper2(1, 7, 6);
byte movingStepper;
// Distance from position when the motor should start
#define THRESHOLD 20
void setup()
{
    // A0 should be disconnected. If it is used
    // change this to an unused analog pin
    randomSeed(analogRead(0));
    stepper1.setMaxSpeed(3000);
    stepper1.setAcceleration(1000);
    stepper2.setMaxSpeed(3000);
    stepper2.setAcceleration(1000);
    // Make sure that steppers are at zero
    stepper1.setCurrentPosition(0);
    stepper2.setCurrentPosition(0);
    // Pretend that we were moving motor 2
    // It is already at position, so first
    // loop will move motor 1 to a new position
    movingStepper = 2;
}

void loop()
{
    if (movingStepper == 1)
    {
        if (abs(stepper1.distanceToGo()) < THRESHOLD)
        {
            int nextpos;
            do
            {
                nextpos = step2cues[random(sizeof(step2cues)/sizeof(int))];
            } while (abs(nextpos - stepper2.targetPosition()) < THRESHOLD);
            stepper2.moveTo(nextpos);
            movingStepper = 2;
        }
    }
    else
    {
        if (abs(stepper2.distanceToGo()) < THRESHOLD)
        {
            int nextpos;
            do
            {
                nextpos = step1cues[random(sizeof(step1cues)/sizeof(int))];
            } while (abs(nextpos - stepper1.targetPosition()) < THRESHOLD);
            stepper1.moveTo(nextpos);
            movingStepper = 1;
        }
    }
    stepper1.run();
    stepper2.run();
}

THRESHOLD是句子中的"几乎":当它接近此值时,它将开始移动另一个电机。注意:提示应该是模式距离另一个的两倍,而不是阈值的两倍,这样您就不会有混合条件(我的意思是,在这个阈值下,一个提示和任何其他提示的最小距离应该是 40)。

顺便说一下,您无需将速度设置为 0:当步进器到达该位置时,它将自行停止。

编辑:

OP 还要求另外三个功能(选择时打印下一个提示,串行打印当前位置,在电机到达提示时设置开关),所以它们就在这里。

首先,为了

清楚起见,我将第二个和第三个功能与以前的代码分开。我选择仅在位置更改时才运行该代码,但这可以很容易地更改为

    仅在
  1. 固定数量的更改后打印该代码(例如,仅在更改 50 或更多之后)
  2. 在固定时间(例如 0.5 秒)打印该代码

无论如何,这是代码:

int currentPos1 = -1;
int currentPos2 = -1;
void loop()
{
    if (movingStepper == 1)
    {
        if (abs(stepper1.distanceToGo()) < THRESHOLD)
        {
            int nextpos;
            do
            {
                nextpos = step2cues[random(sizeof(step2cues)/sizeof(int))];
            } while (abs(nextpos - stepper2.targetPosition()) < THRESHOLD);
            stepper2.moveTo(nextpos);
            Serial.print("Next cue for motor 2: ");
            Serial.println(nextpos);
            movingStepper = 2;
        }
    }
    else
    {
        if (abs(stepper2.distanceToGo()) < THRESHOLD)
        {
            int nextpos;
            do
            {
                nextpos = step1cues[random(sizeof(step1cues)/sizeof(int))];
            } while (abs(nextpos - stepper1.targetPosition()) < THRESHOLD);
            stepper1.moveTo(nextpos);
            Serial.print("Next cue for motor 1: ");
            Serial.println(nextpos);
            movingStepper = 1;
        }
    }
    if (currentPos1 != stepper1.currentPosition())
    {   // Stepper 1 has moved
        currentPos1 = stepper1.currentPosition()
        if (stepper1.distanceToGo() == 0)
        { // Stepper 1 has reached the final position
            digitalWrite(switch1, HIGH);
        }
        else
        {
            digitalWrite(switch1, LOW);
        }
        Serial.print("Motor 1 pos: ");
        Serial.println(currentPos1);
    }
    if (currentPos2 != stepper2.currentPosition())
    {   // Stepper 2 has moved
        currentPos2 = stepper2.currentPosition()
        if (stepper2.distanceToGo() == 0)
        { // Stepper 2 has reached the final position
            digitalWrite(switch2, HIGH);
        }
        else
        {
            digitalWrite(switch2, LOW);
        }
        Serial.print("Motor 2 pos: ");
        Serial.println(currentPos2);
    }
    stepper1.run();
    stepper2.run();
}

如果您选择修改它以不接收频繁的电机更新(例如,每半秒显示一次消息),则应将Stepper X has reached the final position块移到控件之外,以便每次迭代都可以执行它:

unsigned long lastShownMessages = 0;
void loop()
{
    if (movingStepper == 1)
    {
        if (abs(stepper1.distanceToGo()) < THRESHOLD)
        {
            int nextpos;
            do
            {
                nextpos = step2cues[random(sizeof(step2cues)/sizeof(int))];
            } while (abs(nextpos - stepper2.targetPosition()) < THRESHOLD);
            stepper2.moveTo(nextpos);
            Serial.print("Next cue for motor 2: ");
            Serial.println(nextpos);
            movingStepper = 2;
        }
    }
    else
    {
        if (abs(stepper2.distanceToGo()) < THRESHOLD)
        {
            int nextpos;
            do
            {
                nextpos = step1cues[random(sizeof(step1cues)/sizeof(int))];
            } while (abs(nextpos - stepper1.targetPosition()) < THRESHOLD);
            stepper1.moveTo(nextpos);
            Serial.print("Next cue for motor 1: ");
            Serial.println(nextpos);
            movingStepper = 1;
        }
    }
    if ((millis() - lastShownMessages) > 500)
    { // More than 500 ms passed since last update:
        Serial.print("Motor 1 pos: ");
        Serial.println(stepper1.currentPosition());
        Serial.print("Motor 2 pos: ");
        Serial.println(stepper2.currentPosition());
        lastShownMessages += 500;
    }
    if (stepper1.distanceToGo() == 0)
    { // Stepper 1 has reached the final position
        digitalWrite(switch1, HIGH);
    }
    else
    {
        digitalWrite(switch1, LOW);
    }
    if (stepper2.distanceToGo() == 0)
    { // Stepper 2 has reached the final position
        digitalWrite(switch2, HIGH);
    }
    else
    {
        digitalWrite(switch2, LOW);
    }
    stepper1.run();
    stepper2.run();
}

另外,出于校准目的,我可以在服务器监视器上看到步进器的旋转值(增量)吗?我可以将速度设置得很低并让它滚动,然后我可以知道我需要设置的阶梯的提示值。

#include <AccelStepper.h>
// With matrices it's easier
const int step1cues[] = {10000 , 20000, 30000 , 40000 , 50000, 60000, 70000, 80000};
const int step2cues[] = {10000 , 20000, 30000 , 40000 , 50000, 60000, 70000, 80000};
// Define two steppers and the pins they will use
AccelStepper stepper1(1, 4, 3);
AccelStepper stepper2(1, 7, 6);
int switch1 = 12;
int switch2 = 13;
byte movingStepper;
// Distance from position when the motor should start
#define THRESHOLD 20
void setup()
{
    Serial.begin(9600);
    pinMode(switch1, OUTPUT);
    pinMode(switch2, OUTPUT);
    // A0 should be disconnected. If it is used
    // change this to an unused analog pin
    randomSeed(analogRead(0));
    stepper1.setMaxSpeed(3000);
    stepper1.setAcceleration(1000);
    stepper2.setMaxSpeed(3000);
    stepper2.setAcceleration(1000);
    // Make sure that steppers are at zero
    stepper1.setCurrentPosition(0);
    stepper2.setCurrentPosition(0);
    // Pretend that we were moving motor 2
    // It is already at position, so first
    // loop will move motor 1 to a new position
    movingStepper = 2;
}

void loop()
{
    if (movingStepper == 1)
    {
        if (abs(stepper1.distanceToGo()) < THRESHOLD)
        {
            int nextpos;
            do
            {
                nextpos = step2cues[random(sizeof(step2cues)/sizeof(int))];
            } while (abs(nextpos - stepper2.targetPosition()) < THRESHOLD);
            stepper2.moveTo(nextpos);
            Serial.println("2");
            Serial.println(nextpos);
            movingStepper = 2;
            if ( nextpos = stepper2.targetPosition() ){
              digitalWrite(switch1, HIGH); 
            }
              else {
                digitalWrite(switch1, LOW);
                }
            }

    }
    else
    {
        if (abs(stepper2.distanceToGo()) < THRESHOLD)
        {
            int nextpos;
            do
            {
                nextpos = step1cues[random(sizeof(step1cues)/sizeof(int))];
            } while (abs(nextpos - stepper1.targetPosition()) < THRESHOLD);
            stepper1.moveTo(nextpos);
            Serial.println("1");
            Serial.println(nextpos);
            movingStepper = 1;
            if ( nextpos = stepper1.targetPosition() ){
              digitalWrite(switch2, HIGH); 
            }
              else {
                digitalWrite(switch2, LOW);
                }
            }
    }
    stepper1.run();
    stepper2.run();
}

最新更新