0

I am building a robot that is both obstacle-avoiding and remote-controlled. The robot uses an infrared remote. When the front button is pressed the robot moves front, when the right button is pressed the robot turns right, and so on...
When a certain button is pressed the robot switches to obstacle-avoiding mode and starts to drive around. When the ultrasonic sensor detects an object 15cm away the robot turns right, reverses, and then continues moving forward. the obstacle-avoiding code has a problem, though. Here is the code:

#include <EEPROM.h>
#include <IRLib.h>
#include <AFMotor.h>
int frontlights = A1;
int backlights = A2;
int buzzer = A3;
int pingPin = A4; //setup pingpin as A4  

//ir variables
int RECV_PIN = A0;
IRrecv My_Receiver(RECV_PIN);
IRdecode My_Decoder;
unsigned int Buffer[RAWBUF];  

void obstacle_avoiding(){
   while (My_Decoder.value==0xFF807F && My_Decoder.value!=0xFF0AF5){  // when the automatic mode button is pressed and the stop button is not pressed do...  

 motor4.setSpeed(230);
 motor3.setSpeed(230);
 motor2.setSpeed(230); 
 motor1.setSpeed(230);

    long duration, inches, cm;

  // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);

  // The same pin is used to read the signal from the PING))): a HIGH
  // pulse whose duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

  // convert the time into a distance
  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);

  Serial.print(inches);
  Serial.print("in, ");
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();
  delay(90);

      if(cm>15){          // if an object is greater than 10cm move forward
      motor_forward();
      Serial.println("forward");
      digitalWrite(backlights, LOW);

      }


     else if (cm<=15)     // if an object is less than or equal 10cm move backward then turn right 
     {
      motor_stop();
      digitalWrite(frontlights, HIGH);
      digitalWrite(backlights, HIGH);
      digitalWrite(buzzer, HIGH);
      delay(200);
      digitalWrite(buzzer, LOW);
      delay(2000);
      motor_backward();
      digitalWrite(backlights, HIGH);
      Serial.println("backward");
      delay(500);
      motor_stop();
      digitalWrite(backlights, HIGH);
      delay(900);
      motor_right();
      digitalWrite(backlights, LOW);
      Serial.println("right");
      digitalWrite(frontlights, LOW);
      delay(400);

   }
   if (My_Decoder.value==0xFF0AF5){   //the stop button is pressed break the "while" loop and stop the robot 
   break;
   motor_stop();
   }
 }
}  



void loop() {
   long duration, inches, cm;
    if (My_Receiver.GetResults(&My_Decoder)){
       //Restart the receiver so it can be capturing another code
       //while we are working on decoding this one.
       My_Receiver.resume(); 
       My_Decoder.decode();

    //automatic code here
            else if (My_Decoder.value==0xFF807F && My_Decoder.value!=0xFF0AF5){
              obstacle_avoiding();   

            } 

          }

        }  

The code is working however when the "while" statement becomes true it will loop infinitely not stopping even when the condition has become false. I thought while statements should loop until the condition becomes false. Am I misinformed?

  • 2
    side note: (My_Decoder.value==0xFF807F && My_Decoder.value!=0xFF0AF5) if My_Decoder.value is 0xFF807F then it's a fairly safe bet that it's not 0xFF0AF5 which means the condition can be simplified to (My_Decoder.value==0xFF807F) – Andrew Jul 11 '17 at 13:13
  • @Andrew I had been working previously with the simplified condition you offered but with no different results. – Matthew Amisi Jul 11 '17 at 15:06
  • Yes, the reason for the infinite loop is exactly what Look Alterno pointed out, the value of My_Decode.value never changes within the while loop so if the condition is true at the start then it'll remain to be true forever. You need to fix that by somehow including updating My_Decoder within the loop. You can do that by either adding code within the while or by changing the while into an if and relying on the loop() function to create your loop. This was just a minor tidy up to remove redundant logic. – Andrew Jul 11 '17 at 15:13
1

My_Decoder.value doesn't change inside obstacle_avoiding(). Hence, while is running infinitely.

I think you have to delete the while, and let loop() take care of controlling the execution.

Addendum

The intent of the loop() is to read some IR data in value. I under the impression that getResults() sometimes block, acording to this:

However the IRrecvLoop is not interrupt driven and so when you call GetResults it sits in a tight loop and does not release control back to you until the complete signal has been received.

I also want to check that value doesn't change if getResults() return nothing with this loop()

void loop() {
bool r = My_Receiver.GetResults(&My_Decoder)
Serial.print("getResults()=");
Serial.print(r);
Serial.print(" value=");
Serial.println(My_Decoder.value);

if (r) {
    //Restart the receiver so it can be capturing another code
    //while we are working on decoding this one.
    My_Receiver.resume();
    My_Decoder.decode();
} else {
    if (My_Decoder.value == 0xFF807F && My_Decoder.value != 0xFF0AF5) {
        obstacle_avoiding();
        }
    }
}

I hope this works!

  • When I delete the "while", and let "loop()" take care of controlling the execution, if I press the obstacle-avoiding button, the code only runs once. – Matthew Amisi Jul 11 '17 at 15:02
  • @Matthew. Read my answer new version. – user31481 Jul 11 '17 at 16:34
0

Copy/paste this part only:

void loop() {
   long duration, inches, cm;
    if (My_Receiver.GetResults(&My_Decoder)){
       //Restart the receiver so it can be capturing another code
       //while we are working on decoding this one.
       My_Receiver.resume(); 
       My_Decoder.decode();
        }
    //automatic code here
           if (My_Decoder.value==0xFF807F && My_Decoder.value!=0xFF0AF5){
              obstacle_avoiding();   

            } 

          }

        }
  • 1
    Please explain your solution and fix the code indentation. – gre_gor Jul 11 '17 at 13:58
  • I tried the above code and found that the "while" loop still runs infinitely. – Matthew Amisi Jul 11 '17 at 15:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.