Arduino:void loop()给出了意想不到的结果

时间:2013-09-10 11:40:15

标签: arduino robot

我正在开发一种简单的机器人(带有4轮基座),它向前移动并通过距离传感器探测物体,用手臂捡起它。物体是一个从向上方向具有某种把手的盒子,因此臂被放置在所谓的物体把手下方并向上提升它。我想要实现的任务是机器人应该向前移动并将对象放置在放置在某个指定位置的容器(它也是物理对象)中。

机器人通过底座轮子中的4个直流电机移动,机械臂由单独的直流电机控制。

我想要的是:

机器人应向前移动,直到检测到物体为止。
当检测到物体时,它应该停止车轮并启动臂以向上提升物体。
然后它应向前移动,直到它检测到第二个对象即容器。
当检测到第二个物体(容器)时,应停止车轮并启动机械臂以将物体放入容器中。

为此,我写了以下代码

#define mp1 3
#define mp2 4
#define m2p1 5
#define m2p2 6

#define echoPin 7 // Echo Pin
#define trigPin 8 // Trigger Pin
#define LEDPin 13 // Onboard LED

#define armPin1 9  // Pin 1 of arm
#define armPin2 10  // Pin 2 of arm

int maximumRange = 200; // Maximum range needed
int minimumRange = 18; // Minimum range needed
long duration, distance; // Duration used to calculate distance

int first = 0;

void setup()
{
  Serial.begin(9600);

 //Setting the pins of motors
 pinMode(mp1, OUTPUT);
 pinMode(mp2, OUTPUT);
 pinMode(m2p1, OUTPUT);
 pinMode(m2p2, OUTPUT);

 //Setting the pins of distance sensor
 pinMode(trigPin, OUTPUT);
 pinMode(echoPin, INPUT);

 pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)

 pinMode(armPin1, OUTPUT);
 pinMode(armPin2, OUTPUT);
}// end setup method

long calculateDistance(){
  //Code of distance sensor
  digitalWrite(trigPin, LOW); 
  delayMicroseconds(2); 

  digitalWrite(trigPin, HIGH);
  delayMicroseconds(20); 

  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);

 //Calculate the distance (in cm) based on the speed of sound.
 return duration/58.2;
}

void loop()
{
  distance = calculateDistance();

  while(distance > minimumRange) {
    forward();
    distance = calculateDistance();
  }

  while(distance <= minimumRange && first == 0){
    stopMotors();

    pickObject();

    distance = calculateDistance();
  }

  while(distance > minimumRange) {
    forward();
    distance = calculateDistance();
  }

  while(distance <= minimumRange && first == 1){
    stopMotors();

    putObject();

    distance = calculateDistance();
  }// end second while copied 

  first = 1;

}// end loop function

void pickObject(){
  digitalWrite(armPin1, LOW);
  digitalWrite(armPin2, HIGH);
}

void putObject(){
  digitalWrite(armPin1, HIGH);
  digitalWrite(armPin2, LOW);
}

void stopMotors(){
  digitalWrite(mp1, LOW);
  digitalWrite(mp2, LOW);
  digitalWrite(m2p1, LOW);
  digitalWrite(m2p2, LOW);
}

void forward(){
  digitalWrite(mp1, LOW);
  digitalWrite(mp2, HIGH);
  digitalWrite(m2p1, HIGH);
  digitalWrite(m2p2, LOW);
}

但是代码不能像我希望的那样工作。它实际上是向下移动手臂。可能是因为我还没有理解loop()函数的流程。

任何人都可以告诉我代码中的问题是什么,我的代码应该是什么才能获得所需的结果?

4 个答案:

答案 0 :(得分:2)

我的原始答案与@Bmoore在诊断中的答案一致,但我现在相信loop()中的算法基本上正确。这是发生的事情:

  1. 我们正处于第一次迭代中,first==0。您输入while(distance > minimumRange),直到条件中断为止。 distance现在是<= minimumRangefirst == 0
  2. 您输入while(distance <= minimumRange && first == 0)。你留在那里,不断停止驱动引擎并进行测量,直到物体与超声波传感器有间隙。 distance现在是> minimumRangefirst == 0
  3. 您输入while(distance > minimumRange)。你会留在它,直到情况破裂。 distance现在是<= minimumRangefirst == 0
  4. 输入while(distance <= minimumRange && first == 1),因为first == 0
  5. 您设置first = 1并结束迭代。
  6. 您现在正处于第二次迭代中。同样,distance现在是<= minimumRangefirst == 1。 您因此而输入前三个while
  7. 您输入while(distance <= minimumRange && first == 1)并留在while,直到宇宙热死(或直到您的Arduino电量耗尽,以先到者为准)。
  8. 所以,算法很扎实。因此,其他地方肯定有问题。以下是我看到的可疑内容:

    • pickObject()putObject()相反。你留在第二个while。这可能与无效的起始位置相结合:如果您的机器人可以从起始状态向上移动其手臂,那么您的假设可能会出现问题。
    • 无论出于何种原因,distance遇到第一个对象后始终<<>> <(1>)(传感器故障,等待时间短在三角脉冲和回波之间等)。然后,您将在第二次minimumRange中继续进行第一次迭代。请注意,这要求先前的错误条件与观察一致。

    在您的代码中还有一些不完全正确的事情:

    • while锁存,即如果您在引脚上设置digitalWrite()LOW,则值将保持设置,直到您更改它为止。你一直在不必要地写这些值。
    • 正如其他答案所指出的那样,HIGH是一个......循环。它重复了一遍。您应该将loop()重写为while s(更新当然条件)。
    • 您还要使算法依赖busy-waiting方法,不断测量距离,直到手臂移动,一遍又一遍地发送脉冲。电能不是免费的,尤其是在嵌入式平台上。在这些情况下,您应该添加delay()

    也可能还有其他故障(我当然希望你不会拖延你的手臂驱动引擎,因为你从未真正停止它!)。

    因此,一般来说,你应该解决这样的问题:

    1. Serial.Write()语句添加到您的代码中,使其具有信息性,描述已发生的步骤以及关键参数的值。
    2. 通过USB将Arduino连接到IDE,或使用例如可与SD卡配合使用的日志屏蔽。
    3. 根据这些日志,确定算法中的故障位置。
    4. 以这种方式使用日志将为您节省许多麻烦。

答案 1 :(得分:1)

这是你的问题:

循环功能不断运行,每次结束时都会立即启动。您首先将其设置为1,但是您永远不会将其设置为0,因此它首先经历的每个循环都是1.

while(distance <= minimumRange && first == 1){
    stopMotors();

    putObject();

    distance = calculateDistance();
  }// end second while copied 

  first = 1;

答案 2 :(得分:1)

loop方法一次又一次地打开,一遍又一遍,直到电量耗尽或机器人关机。

我没有你的机器人因此很难测试你的代码,但也许,在充分尊重的情况下,你的方法并不完全正确。

对于我的机器人,我去了behavior-based。每个循环(每秒数百次)机器人会询问有关环境及其内部状态的问题。使用答案,它会选择正确的行为。

您正在使用的方法是基于行为的机器人的良好开端。以下是一些解释所有这些内容的幻灯片:behavior-based robotic

希望它有所帮助!

答案 3 :(得分:0)

循环功能不断运行,每次结束时都会立即启动。您首先将其设置为1,但是您永远不会将其设置为0,因此它首先经历的每个循环都是1.

while(distance <= minimumRange && first == 1){
    stopMotors();

    putObject();

    distance = calculateDistance();
}// end second while copied 

first = 1;