Ultrasonic sensor not measuring distance

Hi I'm new here,

In my project my ultrasonic sensor is acting strange. I ran an ultrasonic sensor test code. When I bring the object closer to the sensor, it's measured distance increases and when I bring the object further away, it's measured distance decreases, as if it's inverted. It's measurements are also invalid: whenever I hold the object a foot away, it detects it as one meter.

#define trigPin A0
#define echoPin A1

void setup() {
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  Serial.begin(9600);
}

void loop() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  long duration = pulseIn(echoPin, HIGH, 30000);
  Serial.print("Raw duration: ");
  Serial.println(duration);

  if (duration == 0) {
    Serial.println("No echo detected.");
  } else {
    int distance = duration * 0.034 / 2;
    Serial.print("Distance: ");
    Serial.print(distance);
    Serial.println(" cm");
  }
  delay(500);
}

Does anyone know what could be a possible problem? Thanks!

float distance = duration * 0.034 / 2.0;

Please post a link to the product page for the ultrasonic sensor you are using, and post a wiring diagram (hand drawn is fine).

    Ultrasonic Sensor (HC-SR04)
    ----------------------------
    |  VCC  | ---- (5V) ---- Arduino 5V  
    |  GND  | ---- (GND) ---- Arduino GND  
    |  TRIG | ---- (A0)  ---- Arduino A0  
    |  ECHO | ---- (A1)  ---- Arduino A1  
    ----------------------------

    L298N Motor Driver #1 (Left Motors)
    ------------------------------------
    | 12V   | ---- (Battery +)  
    | GND   | ---- (Battery - & Arduino GND)  
    | 5V    | ---- (Enable jumper ON)  
    | ENA   | ---- (PWM Pin 9) (Arduino PWM Output)  
    | IN1   | ---- (Pin 7) (Motor direction)  
    | IN2   | ---- (Pin 8) (Motor direction)  
    | OUT1  | ---- (Left Motor +)  
    | OUT2  | ---- (Left Motor -)  
    ------------------------------------

    L298N Motor Driver #2 (Right Motors)
    ------------------------------------
    | 12V   | ---- (Battery +)  
    | GND   | ---- (Battery - & Arduino GND)  
    | 5V    | ---- (Enable jumper ON)  
    | ENB   | ---- (PWM Pin 10) (Arduino PWM Output)  
    | IN3   | ---- (Pin 5) (Motor direction)  
    | IN4   | ---- (Pin 6) (Motor direction)  
    | OUT3  | ---- (Right Motor +)  
    | OUT4  | ---- (Right Motor -)  
    ------------------------------------

    Arduino Uno Connections
    ------------------------------------
    | A0   | ---- Trigger (Ultrasonic)  
    | A1   | ---- Echo (Ultrasonic)  
    |  7   | ---- IN1 (L298N Left)  
    |  8   | ---- IN2 (L298N Left)  
    |  5   | ---- IN3 (L298N Right)  
    |  6   | ---- IN4 (L298N Right)  
    |  9   | ---- ENA (L298N Left - PWM)  
    | 10   | ---- ENB (L298N Right - PWM)  
    | GND  | ---- Common Ground with Motor Driver & Battery  
    ------------------------------------

One thing at a time!

Remove all connections to the motor driver and other extraneous devices, until you get the ultrasonic sensor working.

The code looks OK, except that these two lines do nothing useful and can be removed.

  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

I think that you should check the duration's of your pings that farther range reports as taking longer. This is the most important part of this post. The rest is nit-picking except for temperature and mach speed in hot or cold conditions.

Try using all type long variables and to avoid using floats...

1 meter at 340m/s = 1m / 340m/s = 0.002941...secs
= 2941 microsecs per meter one-way just to check values.
A 1 meter = 100 cm ping would take 5882 microsecs.
With this, calculating with all type long variables in 20C air should work well and be faster than using floats. Using .034 forces the whole calculation to be done with floats.

If we multiply duration by 100 and divide by 5882 we get cm's more precisely than cm = duration / 58.

It should get close to or the same as duration * .034 / 2, only a good bit faster on most Arduinos.

But be aware that the speed of sound is dependent on the temperature of the air. In cold air the speed is slower and in hot air it is faster. The difference is very small per degree. Humidity is a much smaller factor.

The Ping tutorial example says
// 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:

Since the pin is already LOW from the last pass of loop(), the recommended "short LOW pulse" does nothing.

I don't recommend to take those tutorials very seriously.

Right you are. The pinMode OUTPUT defaults to LOW so even the first action should begin LOW.

The pulseInLong() doc in the Arduino Reference Page mentions interrupt affected scenarios. Maybe the motor code does that?

Depends on the Arduino you are using.
So which Arduino?

Thanks for all your help so far! I'm using an Arduino Uno.

Here's my old circuit do you think it would be better than my current one?

+-----------------------+           +-----------------------+
|    6xAA Battery Pack  |           |  4xAA Battery Pack   |
|   +V            GND   |           |   +V            GND  |
+-----------------------+           +-----------------------+
        |                                |       |
        |                                |       |
        V                                V       |
+--------------------------------------+ |       |
|          Arduino Motor Shield        | |       |
|                                      | |       |
|  VIN <-------------------------------+ |       |
|  GND <--------------------------------+-------+|
|                                      |         |
|  M1 ---> DC Motor 1                  |         |
|  M2 ---> DC Motor 2                  |         |
|  M3 ---> DC Motor 3                  |         |
|  M4 ---> DC Motor 4                  |         |
|                                      |         |
|  Pin 9 ---> Servo Signal             |         |
|                                      |         |
|  Pin 6 ---> Ultrasonic Sensor TRIG   |         |
|  Pin 7 ---> Ultrasonic Sensor ECHO   |         |
|  Pin A2 --> IR Sensor                |         |
+--------------------------------------+         |
         |   |                                    |
         |   |                                    |
         V   V                                    |
+-------------------------+                       |
|       Breadboard        |                       |
|                         |                       |
|    +V Rail --> Sensors  |                       |
|    GND Rail --> Sensors |                       |
+-------------------------+                       |
         |   |                                    |
         V   V                                    |
+-------------------------+                       |
|       Servo Motor       |                       |
|   +V  <-----------------+                       |
|   GND <-----------------+                       |
|   Signal <--------------+ Pin 9 on Motor Shield |
+-------------------------+                       |

What is this "object"
Those sensors work well with plain flat surfaces that are perpendicular to the sensor beam. Fuzzy and soft objects don't work so well, Objects at an angle don't work well either.

I just use anything like books, phone cases, boxes, whatever is beside me that has a flat surface.

The problem is with the motor shield A0 and A1 are used by the motor shield.
Try using A4 and A5

Thanks, I'll do that! Why is that the problem, though?

I changed it to A4 and A5 (so now the Trig is A4 and Echo is A5) and now it only works when I put the object very close to the ultrasonic sensor. What could this mean?

I don't understand your schematic.
Where does the Uno get it's power from?

The Arduino Uno gets its power from the 5v terminal from one of the l298n motor drivers.