Go Down

Topic: [solved] Stop the robot with Ultrasound sensors (Read 980 times) previous topic - next topic

Sentrinity

Sep 11, 2018, 02:54 pm Last Edit: Sep 14, 2018, 11:19 am by Sentrinity
Hi guys

I want to do an obstacle avoiding robot with multiple ultrasound sensors, so before that, to test that my code works I tried to let the robot stop after any of the sensors is less than 30 cm away from an obstacle.
But it doesn't work because everytime the robot stops after a while he starts driving again eventhough the obstacle is right infront of him.I know that with this code the does cycle through the sensors but still how can do it that he stops right away. I use the new ping library. It could be this question is for programming question section but I am not sure. So how can I fix that problem? I marked the serial stuff as comments because it isn't important for my problem.
Code: [Select]

// ---------------------------------------------------------------------------
// Example NewPing library sketch that pings 3 sensors 20 times a second.
// ---------------------------------------------------------------------------

#include <ArloRobot.h>
#include <NewPing.h>

#define SONAR_NUM 4      // Number of sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.

ArloRobot Arlo;                               // Arlo object
SoftwareSerial ArloSerial(12, 13);            // Serial in I/O 12, out I/O 13

int countsLeft, countsRight;

NewPing sonar[SONAR_NUM] = {   // Sensor object array.
  NewPing(11, 11, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
  NewPing(10, 10, MAX_DISTANCE),
  NewPing(9, 9, MAX_DISTANCE),
  NewPing(8, 8, MAX_DISTANCE)
};

void setup() {
  Serial.begin(9600); // Open serial monitor at 9600 baud to see ping results.
  ArloSerial.begin(19200);                    // Start DHB-10 serial com
  Arlo.begin(ArloSerial);                     // Pass to Arlo object

  Arlo.clearCounts();                         // Clear encoder counts
}

void loop() {
  for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through each sensor and display results.
    if (sonar[i].ping_cm() >= 30)
    {
      Arlo.writeSpeeds(72, 72);                 // Go forward 72 counts/sec
    }
    else
    {
      Arlo.writeSpeeds(0, 0);                  //Stop
      delay(500);
    }

    delay(29); // Wait 100ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.

    /*    Serial.print(i);
        Serial.print("=");
        Serial.print(sonar[i].ping_cm());
        Serial.print("cm "); */
  }
  //Serial.println();
}

wildbill

Your problem is that if any of your sensors have more than 30cm clear in front of them, you turn the motors on. If your requirement is that any detected obstacle stops the robot, you will need to check that no sensor sees a blockage before you turn the motors on. You likely want an immediate stop though if any sensor is blocked.

AWOL

Code: [Select]
delay(29); // Wait 100ms between pings ( :o

Sentrinity

Code: [Select]
delay(29); // Wait 100ms between pings ( :o
29ms should be the shortest delay between pings. Thats the comment of the author of the new ping library I just forgot to change the comment I meant to put 29 there.

Sentrinity

Your problem is that if any of your sensors have more than 30cm clear in front of them, you turn the motors on. If your requirement is that any detected obstacle stops the robot, you will need to check that no sensor sees a blockage before you turn the motors on. You likely want an immediate stop though if any sensor is blocked.

And how can I put that in my code, sry I am not so experience in coding. Should I just do a while loop?

wildbill

One way to do it is to use a boolean flag. Call it OkToRunMotors or some such. Set it true before your for loop. In the loop, check whether each sensor is detecting a range of less than 30. If it does, stop the motors and set the flag false.

After the for loop, if OkToRunMotors is still true, run the motors.

n.b. don't run the motors from the for loop itself as you are currently doing - per your requirement, you need to have established that all sensors show the way clear before you can do that.

Sentrinity

I tried to do what you said is this right?
Code: [Select]

#include <ArloRobot.h>
#include <NewPing.h>
//#include <Servo.h>


#define SONAR_NUM 4      // Number of sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.

ArloRobot Arlo;                               // Arlo object
SoftwareSerial ArloSerial(12, 13);            // Serial in I/O 12, out I/O 13

int countsLeft, countsRight;
//bool OkToRunMotors = true;

NewPing sonar[SONAR_NUM] = {   // Sensor object array.
  NewPing(11, 11, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
  NewPing(10, 10, MAX_DISTANCE),
  NewPing(9, 9, MAX_DISTANCE),
  NewPing(8, 8, MAX_DISTANCE)
};

void setup() {
  Serial.begin(9600); // Open serial monitor at 9600 baud to see ping results.
  ArloSerial.begin(19200);                    // Start DHB-10 serial com
  Arlo.begin(ArloSerial);                     // Pass to Arlo object
  Arlo.clearCounts();                         // Clear encoder counts
}

void loop() {
  bool OkToRunMotors = true ;
  for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through each sensor and display results.
    if (sonar[i].ping_cm() <= 30)
    {
      Arlo.writeSpeeds(0, 0); // Go forward 72 counts/sec
      OkToRunMotors = false;
      delay(500);
    }

    delay(100); // Wait 100ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  }
  if (OkToRunMotors = true)
  {
    Arlo.writeSpeeds(72, 72);                 
    //delay(500);
  }

  /*    Serial.print(i);
      Serial.print("=");
      Serial.print(sonar[i].ping_cm());
      Serial.print("cm "); */
}
//Serial.println();


So I tested this code and now stoping when an obstacle is in the way works with the ultrasound sensor on pin 11 on the other ones it is like before the robot stops for a while but and then the wheels turn a little bit like 1/5 so why does it only work on one of these pins?

AWOL


Sentrinity

#8
Sep 13, 2018, 10:32 am Last Edit: Sep 13, 2018, 10:33 am by Sentrinity
Code: [Select]
  if (OkToRunMotors = true)oops
What's wrong with that I don't get it. :/
Isn't that what wildbill said?

AWOL

You're assigning the value true to the variable OkToRunMotors, and then evaluating the outcome, which is, of course, always true.

You should be comparing true to OkToRunMotors

Sentrinity

You're assigning the value true to the variable OkToRunMotors, and then evaluating the outcome, which is, of course, always true.

You should be comparing true to OkToRunMotors
Oh yeah that was the mistake so I changed it to this:

Code: [Select]
if (true == OkToRunMotors)

And know it does work ty very much guys.

Sentrinity

I have a new problem now, the code does work and the robot drives until it sees an obstacle but this only works permanently if I put the robot on a box or such. Then the wheels turn until it sees my hand or another obstacle.
But if I put the robot on the ground it works sometimes or it doesn't work. Even when it starts on an elaveted space then I move the robot to the ground. It does scan because the led of the ultrasound do blink. So where could the problem be? I just put the code again if I made a mistake somehow.
Code: [Select]
// ---------------------------------------------------------------------------
// Example NewPing library sketch that pings 3 sensors 20 times a second.
// ---------------------------------------------------------------------------

#include <ArloRobot.h>
#include <NewPing.h>

#define SONAR_NUM 4      // Number of sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.

ArloRobot Arlo;                               // Arlo object
SoftwareSerial ArloSerial(12, 13);            // Serial in I/O 12, out I/O 13

int countsLeft, countsRight;

NewPing sonar[SONAR_NUM] = {   // Sensor object array.
  NewPing(11, 11, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
  NewPing(10, 10, MAX_DISTANCE),
  NewPing(9, 9, MAX_DISTANCE),
  NewPing(8, 8, MAX_DISTANCE)
};

void setup() {
  Serial.begin(9600); // Open serial monitor at 9600 baud to see ping results.
  ArloSerial.begin(19200);                    // Start DHB-10 serial com
  Arlo.begin(ArloSerial);                     // Pass to Arlo object
  Arlo.clearCounts();                         // Clear encoder counts
}

void loop() {
  bool OkToRunMotors = true ;
  for (uint8_t i = 0; i < SONAR_NUM; i++) // Loop through each sensor and display results.
  {
    if (sonar[i].ping_cm() <= 20)
    {
      Arlo.writeSpeeds(0, 0); // Stop
      OkToRunMotors = false;
    }
    delay(100); // Wait 100ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
    /*    Serial.print(i);
        Serial.print("=");
        Serial.print(sonar[i].ping_cm());
        Serial.print("cm ");
        Serial.println();
    */
  }
  if (true == OkToRunMotors)
  {
    Arlo.writeSpeeds(72, 72);         //Move Forward with 72 counts/s
  }
}

Sentrinity

I am an idiot I just had to increase the max distance  ::) so now everything is fine.

Go Up