【问题标题】:Stepper motor control via RC receiver通过 RC 接收器控制步进电机
【发布时间】:2017-06-29 04:40:38
【问题描述】:

我是 Arduino 编程新手,花了几天时间才走到这一步,但似乎无法弄清楚为什么这段代码不起作用。

我正在尝试使用业余级遥控器 RX/TX 来控制步进电机。

我有一个 RC 接收器向我的 Arduino 发送一个从 1000 到 2000 的模拟值。如果该信号是 1000,我想在步进器上设置 1000 = -360 度,在步进器上设置 2000 = +360 度。

我从接收器接收到正确的信号并将它们打印到串行监视器,但我似乎无法用这个值控制步进电机。这个电机只是卡在第一个 while 循环中并继续向一个方向旋转。

int ch1 = 0;                                // RC Reciever Channel Value
int ch1previous = 0;                        // RC Receiver Channel Previous Value
int PUL=7;                                  //define Pulse pin of stepper driver
int DIR=6;                                  //define Direction pin of stepper driver
int ENA=5;                                  //define Enable Pin of stepper driver

void setup() {
  pinMode (PUL, OUTPUT);                    // Stepper Driver Pulse Pin
  pinMode (DIR, OUTPUT);                    // Stepper Driver Direction Pin
  pinMode (ENA, OUTPUT);                    // Stepper Driver Enable Pin
  pinMode(3, INPUT);                        // RC Reciever Pin Input
  Serial.begin(9600);                       

}

void loop() {

  ch1 = pulseIn(3, HIGH, 50000);                    // Read RC Reciever Channel Value

while ( ch1 > ch1previous) {                        // If CH1 is greater than CH1Previous run the differance
      for ( int i = ch1; i < ch1previous; i++);{    // in steps to maintain the setpoint value in forwared position
      digitalWrite(DIR,HIGH);
      digitalWrite(ENA,HIGH);                       // pulsing stepper motor in forward motion
      digitalWrite(PUL,HIGH);
      delayMicroseconds(50);
      digitalWrite(PUL,LOW);
      delayMicroseconds(50);
}
  }

 while ( ch1 < ch1previous) {                      // if CH1 is less than CH1Previous run the differance
      for ( int i = ch1; i<ch1previous; i--);{      // in steps to maintain the setpoint value in reverse motion
      digitalWrite(DIR,LOW);
      digitalWrite(ENA,HIGH);                       // pulsing stepper motor in reverse motion
      digitalWrite(PUL,HIGH);
      delayMicroseconds(50);
      digitalWrite(PUL,LOW);
      delayMicroseconds(50);
    }
  }


  Serial.print ("Channel 1: ");             // print text to the serial monitor
  Serial.println(ch1);                      // print ch1 value to the serial monitor and end line
  Serial.print("CH1 Previous: ");           // print text to the serial monitor 
  Serial.println(ch1previous);              // print ch1previous value to the serial monitor and end line
  ch1previous = ch1;                        // remember the previous value from ch1

  delay(500);                               // just to clean up the serial monitor
}

【问题讨论】:

  • 两个while条件即使启动一次也会无限执行。正如您在 cmets If CH1 is greater than CH1Previous run the difference 中输入的那样,这些 while 条件必须由 if statements 替换。也就是说,将它们设为if(ch1 &gt; ch1previous)else if(ch1 &lt; ch1previous)
  • for 循环后; 的意义何在?那些 for 循环什么都不做。
  • 您似乎预计脉冲可达 50000 微秒。但是您将其存储到 int 中,该 int 最多只能存储 32767。将 unsigned long 用于 ch1ch1previous
  • @Sma 您应该将其发布为答案。
  • @gre_gor 好的,我会这样做的。

标签: while-loop arduino stepper


【解决方案1】:

可以 ch1 = pulseIn(3, HIGH, 50000) 曾经是负值吗?如果不是,那么当您考虑以下陈述时,这可以解释这种行为:

 while ( ch1 > ch1previous) { 

并且ch1previous 被初始化为零。

【讨论】:

  • pulseIn 返回一个unsigned long
【解决方案2】:

这两个while 条件即使启动一次也会无限继续。正如您在 cmets If CH1 is greater than CH1Previous run the difference 中输入的那样,这些 while 条件必须替换为 if statements。也就是说,将它们设为if(ch1 &gt; ch1previous)else if(ch1 &lt; ch1previous)。并且 for 循环的条件也应该颠倒,根据 if 条件限制它们。

这些改动后,你的代码会变成这样

void loop() {
    ch1 = pulseIn(3, HIGH, 50000);

    if ( ch1 > ch1previous) {
        for ( int i = ch1; i > ch1previous; i--){
            //code
        }
    }

    else if ( ch1 < ch1previous) {
        for ( int i = ch1; i<ch1previous; i++){
            //code
        }
    }

    ...
}

【讨论】:

  • 谢谢!这现在的行为更像我希望的那样,但是我现在在步进电机上出现漂移,即使我的设定点值没有改变,它也会非常缓慢地沿 CW 方向移动,有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-12
  • 1970-01-01
  • 1970-01-01
  • 2011-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多