Ultrasonic Sensor Help

I'm starting to learn about ultrasonic sensors. I've connected 3 together and am printing the distance they record onto the Serial Monitor, code is shown below.

The problem is I'm getting large values from time to time. For example, the readings from one sensor will be: 35, 36, ,35, 2995, 35, 36, etc. even though I placed a large piece of cardboard in front of them and shook it.

Is this because they're sensing the objects behind me, or is it a problem with the sensors?

Also, how would you optimize my code?

#define trigPin1 2
#define echoPin1 3
#define trigPin2 4
#define echoPin2 5
#define trigPin3 6
#define echoPin3 7
#define vibrator1 8
#define vibrator2 9
#define vibrator3 10

long duration, distance, Sensor1,Sensor2,Sensor3;

void setup()
{
Serial.begin (9600);
pinMode(trigPin1, OUTPUT);
pinMode(echoPin1, INPUT);
pinMode(trigPin2, OUTPUT);
pinMode(echoPin2, INPUT);
pinMode(trigPin3, OUTPUT);
pinMode(echoPin3, INPUT);
}

void loop() {
SonarSensor(trigPin1, echoPin1);
Sensor1 = distance;


SonarSensor(trigPin2, echoPin2);
Sensor2 = distance;



SonarSensor(trigPin3, echoPin3);
Sensor3 = distance;


Serial.print(Sensor1);
Serial.print(" ");
Serial.print(Sensor2);
Serial.print(" ");
Serial.println(Sensor3);
}

void SonarSensor(int trigPin,int echoPin)
{
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 29.1;
delay(250);
}

Hi,
Have you tried using the NewPing library?

Tom... :slight_smile:

PulseIn() returns 0 if it times out, that is, if the sensor doesn't see a reflection for whatever reason. It may be that the sensor times out sooner and that's what generates the 2995 value. This would make sense if the bogus values you see are relatively consistent. One way to address this is to pass a shorter timeout argument to PulseIn() which is using one second as the default. Thus something like "duration = pulseIn(echoPin, HIGH, 30000); " would timeout after 30,000 uS which is about 5 meters range (10 m round trip). If pulseIn() times out it will return 0 and you'll have to handle that.

On your code style, it would be more clear if you returned distance from the function SonarSensor rather than passing back through global variables.

With the above, something like this (compiled but not tested):

#define trigPin1 2
#define echoPin1 3
#define trigPin2 4
#define echoPin2 5
#define trigPin3 6
#define echoPin3 7

long Sensor1, Sensor2, Sensor3;

void setup()
{
  Serial.begin (9600);
  pinMode(trigPin1, OUTPUT);
  pinMode(echoPin1, INPUT);
  pinMode(trigPin2, OUTPUT);
  pinMode(echoPin2, INPUT);
  pinMode(trigPin3, OUTPUT);
  pinMode(echoPin3, INPUT);
}

void loop() {
  Sensor1 = SonarSensor(trigPin1, echoPin1);
  delay(250) ;
  Sensor2 = SonarSensor(trigPin2, echoPin2);
  delay(250) ;
  Sensor3 = SonarSensor(trigPin3, echoPin3);
  delay(250) ;
  
  Serial.print(Sensor1);
  Serial.print(" ");
  Serial.print(Sensor2);
  Serial.print(" ");
  Serial.println(Sensor3);
}

long int SonarSensor(int trigPin, int echoPin)
{
  #define Timeout 30000    // PulseIn timeout 30000 uS (about 5 meters range)
  long int duration, distance ;
  
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH, Timeout);
  distance = (duration / 2) / 29.1;
  return distance ;
}

I prefer the solution of TomGeorge. Use the NewPing library. It works perfectly.

If you want to use the Tone() function in your code please also download the documentation from GitHub. By setting one value in the library you will regain the Tone() function.