我有一个代码,其中我有一个来回运行的电动机,并且按钮连接到扫描仪,当我按下按钮时,它将导致电动机停止运转并超过它。我希望它们彼此平行运行,以使代码不会互相干扰。

这是我的代码

#include <AccelStepper.h>

// Define some steppers and the pins they will use

AccelStepper stepper1(AccelStepper::FULL2WIRE, 2, 3);

const int buttonPin = 4;
const int button2Pin = 14;
const int pulseopto1 = 9;
const int startScan = 11;

int buttonState = 0;
long previousMillis = 0;
long interval = 5;

void setup()
{
    pinMode(buttonPin, INPUT);
    pinMode(button2Pin, INPUT);
    pinMode(pulseopto1, OUTPUT);
    pinMode(startScan, OUTPUT); 
    stepper1.setMaxSpeed(40000.0);
    stepper1.setAcceleration(100000.0);
    stepper1.moveTo(25000);
}

void loop()
{
    buttonState = digitalRead(buttonPin);

    if (buttonState == LOW)
    {
        digitalWrite(startScan, HIGH);
    }
    else (buttonState == HIGH);
    {
        digitalWrite(startScan, LOW);
    }

    {
        buttonState = digitalRead(button2Pin);

        if (buttonState == LOW)
        {
            // turn LED on:
            digitalWrite(pulseopto1, HIGH);
            delay(5);
            digitalWrite(pulseopto1, LOW);
            delay(5);
        }
        else
        {
            // turn LED off:
            digitalWrite(pulseopto1, LOW);
        }
    }

    // Change direction at the limits
    if (stepper1.distanceToGo() == 0)
    {
        stepper1.moveTo(-stepper1.currentPosition());
    }

    stepper1.run();
}


评论

延迟的粒度是多少?可能是您的延迟导致电机停止了吗?

我认为延迟会影响电动机的运行,因为当我按下按钮时电动机会停止,但我不知道如何解决。

您将需要一个计时器来跟踪时间(或者也许已经有一些函数可以在Arduino中提供“当前时间”?)和一个状态机来跟踪状态。因此,发生的事情是在循环中,按下按钮后,您转到了WAIT_STATE_1并将开始时间设置为当前时间,在循环中的下一次,您检查是否经过了足够的时间。如果是这样,则进入下一个状态,该状态写入tp pulseopto1并进入WAIT_STATE_2,例如,再次将开始时间设置为当前时间。稍后再次在循环功能中,检查是否已经过足够的时间进入下一个状态(END_STATE)

Arduino“一次做两件事”的经典方法被描述为“无延迟闪烁”。

#1 楼

简短的答案是肯定的,但是长的答案是,您以错误的方式接近代码,将需要重新编写一些内容。

您似乎正在尝试读取按钮并让它的某些LED闪烁,同时使步进器来回移动。问题出在您的delay(5);命令,这些命令暂停了代码的执行。相反,您必须使用millis();函数来读取循环中每次迭代的当前时间。步进运动和LED闪烁都是时间的函数,因此只需编写这些函数并在每次迭代中进行设置。

long stepperPosition(long t)
{
    // YOUR CODE GOES HERE, like a sine or triangular waveform
    // it might also depend on stepper1.distanceToGo() == 0
    return sine(t * TIME_SCALE_FACTOR) * MAGNITUDE;
}

bool ledState(long t)
{
    // return HIGH if we're in the first "interval" millis after pressing
    // after that, return LOW to turn off the LED
    return (t < buttonPressTime + interval) ? HIGH : LOW;
}

void loop()
{
    long now = millis();

    // set the LED directly from the button state
    digitalWrite(startScan, LOW == digitalRead(buttonPin));

    // record the time of the button press for use in our function
    if (digitalRead(button2Pin) == LOW) {
        buttonPressTime = now;
    }

    // set LED based on time function
    digitalWrite(pulseopto1, ledState(now));

    // set stepper based on time function
    stepper1.moveTo(stepperPosition(now));
    stepper1.run();
}


在此代码中,LED和步进器被“并行”控制-它们都在每次迭代期间设置,没有条件延迟。

#2 楼

我认为您应该研究Arduino的attachInterrupt函数。您可以将按钮连接到Arduino上的特定中断引脚,然后编写一个小的简单中断处理程序,在触发该中断时将调用该处理程序。您可以将中断配置为在低电平,上升沿,下降沿或更改中断引脚时触发。这样,您不必轮询按钮,这将使您的主循环更干净/更容易编写。

这是arduino网页上的attachInterrupt():http://arduino.cc/ zh_cn / Reference / attachInterrupt

编辑:您还应该注释您的代码,以便我们知道您要执行的操作,并可能向我们提供您的硬件设置的描述(Arduino的实际连接引脚是什么) )。

鉴于TheRussian指出的语法错误,我不理解此代码的编译方式。

#3 楼

看起来电动机停止的原因(之一)是由于以下代码引起的:-

if (buttonState == LOW)
    {
        digitalWrite(startScan, HIGH);
    }
    else (buttonState == HIGH); --> this is a statement due to the semicolon.
    {
        digitalWrite(startScan, LOW); --> this statement will get executed even when buttonState is LOW.
    }


将其更改为以下内容并进行检查。

if (buttonState == LOW)
    {
        digitalWrite(startScan, HIGH);
    }
    else if (buttonState == HIGH)
    {
        digitalWrite(startScan, LOW);
    }


尝试使用任务计划程序拆分这两个活动。
我的$ 0.02。

#4 楼

覆写是什么意思?电动机会停止还是开始向错误的方向旋转?

loop()函数中的括号发生了奇怪的事情

if (buttonState == LOW)
{
    digitalWrite(startScan, HIGH);
}
else (buttonState == HIGH);  //This shouldn't be here. Just use else
{
    digitalWrite(startScan, LOW); 
}


我不确定,但是我认为您不需要在循环函数中调用stepper1.run()。尝试将其放在setup()函数的末尾。

评论


$ \ begingroup $
当我按下闪烁功能的按钮时,电机停止。
$ \ endgroup $
–荷兰人
2013年11月6日15:05

#5 楼

我一直在寻找相同的东西,我在IDLE中弄乱了,发现您是否在第一个代码或您要执行两个操作的代码旁边放置一个空格并键入代码。

示例:

Void loop 
{
  Serial.print("Hello"); 
  Serial.print("World"); 
}


并将分号放在我放置在代码上的位置。