【问题标题】:How to move forward and backward with the Arduino Stepper motor?如何使用 Arduino 步进电机前后移动?
【发布时间】:2021-10-23 07:17:41
【问题描述】:

我想为具有三个按钮和一个步进电机的系统创建一个 Arduino 程序。如果按下按钮 1,步进器应该向前移动 50 步。如果按下按钮 2,步进器应后退 50 步。如果按下按钮 3,则步进器应在向后 50 步后向前移动 50 步。

我使用了 Arduino 的步进器库并编写了以下代码。函数Forward()Backward()Continuous() 实现每个按钮要执行的操作。每个函数逐步移动电机并将动作记录在串行输出上。

但我无法达到我想要的结果:步进器不会后退而只会前进。更准确地说:

  • Forward() 按预期工作
  • Backward() 产生预期的日志输出(最多计算步数 50),但电机只向前移动而不是向后移动。
  • Continuous() 函数也不起作用:在前进 50 步后(移动并记录步数),它会继续前进,只为计数器记录 1。

我需要你的帮助。如何使电机在Backward() 中后退?以及如何纠正Continuous()实现前进后退,并产生正确的后退步数?

这是我的代码:

#include <Stepper.h>

int forward_button = 2;
int backward_button = 3;
int cont_button = 4;

int button_cond1;
int button_cond2;
int button_cond3;

int del = 50;

const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
// for your motor

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);
int stepCount = 0;         // number of steps the motor has taken
int steps;

void Forward() { // should go forward by 50 steps
  int stepCount = 0; 
  while (stepCount < 50) {
    steps = 1;
    myStepper.step(steps);
    stepCount++;
    delay(del);
    Serial.print("Forward steps :");
    Serial.println(stepCount);
  }
}

void Backward() { // should go backward by 50 steps
   int stepCount = 0;
   while (stepCount < 50) {
    steps = 1;
    myStepper.step(steps);
    stepCount++;
    delay(del);
    Serial.print("Backward steps :");
    Serial.println(stepCount);
  }
}

void Continuous() {  // should go forward by 50 steps, then backwards
  int stepCount = 0; 
  while (stepCount < 50) {
    steps = 1;
    myStepper.step(steps);
    stepCount++;
    delay(del);
    Serial.print("Continuous steps :");
    Serial.println(stepCount);
  }
  while (50 < stepCount <= 200) {
    int stepCount = 0;
    steps = 1;
    myStepper.step(steps);
    stepCount++;
    delay(del);
    Serial.print("Continuous steps :");
    Serial.println(stepCount);
  }
}

void setup() {
  // initialize the serial port:
  Serial.begin(9600);

  pinMode(forward_button, INPUT_PULLUP);
  pinMode(backward_button, INPUT_PULLUP);
  pinMode(cont_button, INPUT_PULLUP);

  //myStepper.setSpeed(60);
}

void loop() {
  // step one step:

  button_cond1 = digitalRead(forward_button);
  button_cond2 = digitalRead(backward_button);
  button_cond3 = digitalRead(cont_button);

  if ((button_cond1 == LOW) && (button_cond2 == HIGH) && (button_cond3 == HIGH))  {
    Forward();
  }
  else if ((button_cond1 == HIGH) && (button_cond2 == LOW) && (button_cond3 == HIGH))  {
    Backward();
  }
  else if ((button_cond1 == HIGH) && (button_cond2 == HIGH) && (button_cond3 == LOW))  {
    Continuous();
  } 
}

【问题讨论】:

  • stepsPerRevolution 在 Backward() 中更改但未使用。它不会改变步进器发生的情况。
  • 为什么要更改stepsPerRevolution,尤其是在 Stepper 对象被初始化之后?你试过myStepper.step(-1) 吗?你定义了一个Forward() 和一个Backward()函数,为什么不在Continuous() 中使用它们呢?
  • 其实我忘了删除它们。我只尝试了 .step(1) 和 .step(-1) 而不是它们,但结果是一样的
  • 我现在要编辑问题中的代码
  • while (50 &lt; stepCount &lt;= 200) { 看起来不对..

标签: c++ arduino stepper


【解决方案1】:

步进器方向问题:

根据文档,myStepper.step() 转动电机:

以最近一次调用 setSpeed() 确定的速度将电机转动特定的步数。

更重要的是,为了双向移动,它使用带符号的参数:

转动电机的步数 - 转动一个方向, 转动另一个方向(int)

在您的代码中,Backward()Forward() 之间没有区别:您在两种情况下都提供了正值。所以我建议把Backwards()改成负数:

myStepper.step(-steps); 

Continuous()的逻辑问题

还需要在您的 Continuous() 函数的第二个循环中更正方向,您想要向后移动。
但首先,您需要纠正此循环的条件:

while (50 < stepCount <= 200) {  //OUCH compares a boolean and an integer

C++ 并没有像您想象的那样链接比较运算符。因此,将其分解为两个不同的比较,并用逻辑 分组:

while (50 < stepCount && stepCount <= 200) { 

不幸的是,在第一个循环结束时,stepCount 正好是 50。并且 50 并不严格小于 (&lt;) 小于 50。您可以改用 小于或等于 (&lt;=),但由于循环不会减少计数器,您可以将条件简化为:

while (stepCount <= 200) { // we know that it will stay 50 or above

您还需要删除此循环块中stepCount 的重新定义,因为它会创建一个隐藏初始定义的新局部变量(即一个名称,两个变量,这非常混乱)。

如果还是不行

在长期交换 cmets 之后,这里有一些建议(以粗体表示解决问题的建议):

  • 确保最新版本的代码在 arduino 上运行并且没有编译错误或警告。
  • 确保不同的按钮执行预期的功能。
  • 如果电机运动不如预期,请确保您的 Stepper 对象配置了与电机兼容的每转步数。
  • 如果移动不稳定,或者如果正负步骤之间没有区别(根据文档,这应该朝相反的方向移动),然后交叉检查Stepper 的构造函数获取按正确顺序排列的引脚编号:这很重要,因为Stepper 将按给定顺序向不同引脚发送一系列信号以实现正确的运动。

如果仍然无法正常工作,则可能是硬件问题,或者与库不兼容(参见例如here,作者通过提供另一个信号序列解决了该问题,这不是最简单的方法)。

【讨论】:

  • 你好@Christophe。首先感谢您的详细解答。我将您的建议应用于我的代码,但现在,只有按钮 1 正在工作,这使得步进器前进。用于向后()和连续()功能的按钮目前不起作用
  • 让我们一次一个: 1)向后,“根本不工作”看起来如何:根本没有运动?几个动作?软件错误消息?你在串行上得到什么输出? 2)如果连续,你会在第二个循环中转发,它会工作吗,有两个转发序列?如果不是,它是如何准确反应的?
  • 1) 在 backward() 中,它以确定的步骤前进。串行端口提供了我预期的步骤 1 到 50。 2) 在 Continuous() 中,第一个 while 循环从 1-50 步开始,但是在第二个 while 循环中,stepCount 在串行端口中变为 1,步进器继续向前运动。但是,在第二个循环中,它需要返回并向后移动
  • 好的。所以我知道按钮控件似乎有效?但是,如果电机在负步骤的情况下无法倒退,则可能存在排序问题(例如,构造函数中的引脚顺序可能应该不同,例如最后两个倒置?)。还要检查构造函数中的步数是否与电机的步数相匹配,以消除与那里的差异相关的任何问题。最后,步数为 1 的事实意味着您没有应用我回答的最后一句话:请删除 while 循环内的`int stepCount = 0;`。
  • 嘿@Christophe,我解决了这个问题。我刚刚通过更改位置编写了 Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11)。感谢您的帮助,我会更加小心地写别针
猜你喜欢
  • 2014-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-15
  • 1970-01-01
相关资源
最近更新 更多