HC-SR04 Ultrasonic sensors incorrect readings when at an angle

Hello,

I am currently making a autonomous car that is able to go through a maze on its own. It has 3 ultrasonic sensors; one in the middle, one on the right and one on the left. These sensors are places 90 degrees from each other (right is 90 degrees from middle sensor, left is 90 degrees from middle sensor. I hope this makes sense!).

In order to make sure that the robot does not crash into the wall, it will automatically adjust itself if it is too close to the right side of the wall or left side. This is done by first checking the left and right sensors; if they are within 2cm of each other, it will move straight and will not adjust itself. However, if they are not within 2cm of each other, it will make adjustments where necessary (too close to the left wall --> shift to the right. and vice versa).

The issue is, however, when it is adjusting itself. If the left or right sensors are at an angle with respect to the wall it is near, the sensors become wonky and read extremely large values (~2300 cm!). This is of course wrong, because if you position the robot manually to be 90 degrees with respect to the wall, the real readings are ~10-~15cm. Could anyone provide me with any guidance? I have tried the newPing library but it doesn't solve my issue. Am i doing something wrong somewhere?

For reference, the width of our maze from wall to wall is 1 foot. Also I apologize if something doesn't make sense; I'm extremely exhausted working on this, lol. Thank you!!

Most likely, the problem is in your code, which you forgot to post. This post explains how to do that properly.

Ultrasonic sensors are slow and prone to interference from multiple reflections and from each other. You are better off using something like these LIDAR TOF distance sensors for running mazes.

jremington:
Most likely, the problem is in your code, which you forgot to post. This post explains how to do that properly.

Ultrasonic sensors are slow and prone to interference from multiple reflections and from each other. You are better off using something like these LIDAR TOF distance sensors for running mazes.

Hi,

Sorry for not posting code. Here is my code for adjustments and moving straight:

 if ((forward >= 23 && forward < 1000 && forward > 0 ) )

A bit of explanation: I do adjustments( if right & left < 40 )because if there is an opening (at an intersection), rather than adjusting, it should make the turn. I hope this makes sense!

Also, regarding ultrasonic, our group is looking to only utilize ultrasonic sensors. Else, it can be easy (i.e we can do a line follower robot with a black line underneath, but project would be too easy). I hope this is ok!

If you want informed help, post ALL the code. Snippets are generally useless.

jremington:
If you want informed help, post ALL the code. Snippets are generally useless.

Sure.

#include <NewPing.h>

#include <Servo.h>


#include <AFMotor.h>

When an ultrasonic wave hit an object at a low angle, it sometime travel a longer distance before it rebound back. The result is a wrong or maximum reading. It happen occasionally with my robot.

If it is possible, maybe you should put your side sonars at an angle, say something like 30 or 45 degre. The distance will be greter but maybe the sound should be closer to 90° with respect to the wall.

Aside from the fact that the if statements are largely incomprehensible, there is nothing obviously wrong with the code.

That leaves the physics of reflection. If you shine a flashlight beam at an angle into a mirror, the reflected beam does not return to the flashlight. Same thing for a sound wave striking flat walls.

The rule is "angle of incidence = angle of reflection" as described in the link. Result: pulsein doesn't return the correct answer, possibly because of multiple reflections.

A much more elegant way to solve a problem like this is to use proportional steering. Measure the distance to the right and left walls and take the difference. Steer as follows:

Steering_angle = K*(R-L); // if the result is positive, steer right, if negative steer left (proportionally).

Adjust K for best results.

duino_nano:
When an ultrasonic wave hit an object at a low angle, it sometime travel a longer distance before it rebound back. The result is a wrong or maximum reading. It happen occasionally with my robot.

If it is possible, maybe you should put your side sonars at an angle, say something like 30 or 45 degre. The distance will be greter but maybe the sound should be closer to 90° with respect to the wall.

Hi, thx for your suggestion. Unfortunately, we have tried to put the sensors at all different angles - it still gives us errors.

jremington:
Aside from the fact that the if statements are largely incomprehensible, there is nothing obviously wrong with the code.

That leaves the physics of reflection. If you shine a flashlight beam at an angle into a mirror, the reflected beam does not return to the flashlight. Same thing for a sound wave striking flat walls.

The rule is "angle of incidence = angle of reflection" as described in the link. Result: pulsein doesn't return the correct answer, possibly because of multiple reflections.

A much more elegant way to solve a problem like this is to use proportional steering. Measure the distance to the right and left walls and take the difference. Steer as follows:

Steering_angle = K*(R-L); // if the result is positive, steer right, if negative steer left (proportionally).

Adjust K for best results.

Apologies for the ugly code. This is a bit frustrating and relieving - frustrating because I have spent many many hours on this and relieving to know that it may just boil down to the sensors. Genuinely unsure on what to do next. Thanks for your help, it has been greatly appreciated .

Hi,

To find the distance with my robot, I use the following codes:

digitalWrite(HCtrig, HIGH);
delayMicroseconds(10);
digitalWrite(HCtrig, LOW);

duration = pulseIn(HCecho, HIGH);
distance = (duration / 58.2);

Maybe the "microdelay" you are using (80) is too long!

it may just boil down to the sensors. Genuinely unsure on what to do next

For sound, the wall is very smooth and acts like a mirror.

That is not necessarily so for light, so the VL53L0X time of flight sensors might work for you. Buy one and try it out.

jremington:
For sound, the wall is very smooth and acts like a mirror.

That is not necessarily so for light, so the VL53L0X time of flight sensors might work for you. Buy one and try it out.

OK, since I think we have exhausted all options - I will try this sensor out. Question, since we need 3 sensors (one for left, right,middle), is it possible to use these 3 sensors with the 1 SDA and SCL pin with the arduino? If we can, how to differentiate the sensors from each other? I hope this makes sense! Thanks for your help again!

duino_nano:
Hi,

To find the distance with my robot, I use the following codes:

digitalWrite(HCtrig, HIGH);
delayMicroseconds(10);
digitalWrite(HCtrig, LOW);

duration = pulseIn(HCecho, HIGH);
distance = (duration / 58.2);

Maybe the "microdelay" you are using (80) is too long!

Thanks for your suggestion, I have tried this but I still get similar results.

is it possible to use these 3 sensors with the 1 SDA and SCL pin with the arduino? If we can, how to differentiate the sensors from each other?

Yes, but it is not as easy as it should be. You can change the I2C address of a VL53L0X sensor during initialization, which requires an extra I/O pin to control the XSHUT input.

But, the sensor forgets the I2C address on power down, so that has to happen every time you power up the robot.

I'm sure that will be remedied in some future edition, but for now you need an I/O pin for each sensor, in addition to the two I2C pins. So, four I/O pins for 3 sensors, if one takes the default address.

See the details on the Pololu web page.

Maybe the "microdelay" you are using (80) is too long!

That won't make a significant difference. Sound travels less than 3 cm in 80 us.

There is another point to consider. I think that the VL53L0X takes at least 20ms to obtain a reading (with high accuracy mode, it is 200 ms). If speed of acquisition of de data is important in regard of speed of the robot (so it react fast), the VL53L0X might not be the best sensor for the job.

Maybe worth looking at the POLOLU 2467 also. Slightly faster (16ms), no need for I2C, no lost of adress and only 3 I/O pin needed.

Oups...

3 analogues pin

Taking one of the ultrasonic sensors, place that sensor at 90 to the wall and measure/watch/analyze its readings. Then offset the ultrasonic sensor by + or - 10 degrees, measure/watch/analyze the sensors readings. From my previous use of the SRC04 a distinct set of characteristics will emerge that will demonstrate an ability to detect when the sensor is at 90 degrees to its target. This gathered data can be used to torque a servo that the SR04 is mounted to and gives the ability to keep the left/right sensors 90 degrees to the target.

You will find that the SR04 and the like have a 15 degree cone of output. I switched to TFMini's which has a 2 degree cone of output, the TFMini, a serial device, also returns signal strength. TFMini signal strength and distance have a distinct relationship, that I use to determine accuracy of the readings. A single TFMini can be mounted on a servo and used to scan a range. Using single ping gives you, the programmer, control as to when the TFMini measures distance, such as after the servo has reached position. Oh, reminds me, the SR04's accuracy drops way down when the SR04 is moving. The TFMini is not much use closer than 4cm, light is fast. For close in distance, I'd use SR04's. There a mods that can be done with an SR04 to upgrade it but, after its all said and done, a TFMini is still the better option; as the primary distance measuring device, over an SR04.