1

I want to connect multiple Ultrasonic sensors to my Arduino board. For that, I need multiple pulseIn() functions to work at the same time. How can I do that?

  • PulseIn() is an Arduino-specific thing. Like much of the Arduino software, it's a user-friendly thing, but it's far from optimal. If you want Arduino-specific help, you might be better asking on the Arduino stack exchange. On the other hand, if you want help to do this directly with the timers on the Atmel chip, this site is the right place. In that case, you'll need to edit your question to say which microprocessor your Arduino uses. – Jack B Oct 1 '16 at 16:30
  • As it stands, the question could be migrated to the Arduino stackexchange. – gbulmer Oct 1 '16 at 16:38
2

You can't use pulseIn() if you want to use both ultrasonic sensors at the same time.

So either:

  • don't use pulseIn, and instead do that part yourself using eg. digitalRead,
  • use the ultrasonic sensors sequentially, one then the other, or
  • use pin-change interrupts to sense the signal pulse return.

The easiest approach is to use the ultrasonic sensors sequentially. In that case use the form pulseIn(PIN, value, timeout);, where timeout, in microseconds sets the maximum time to wait for a pulse.

This is practical if you know the realistic range is within a couple of metres. The speed of sound is 343.2 metres per second, or 0.3432 metres per millisecond. So if timeout is set to 3000 microseconds (3 milliseconds), then it will wait for an echo up to (roughly) 0.5 metres away.

Edit: The distance to the object, measured by timing the delay, is half the total distance travelled because the sound travels to the object, then bounces back to the sensor.
Ie. distance to object = total distance travelled by sound / 2

An alternative is to do what pulseIn does, but for more than one pin. This is simpler than the real pulseIn code, but illustrates the idea:

int inPin1 = ...;
int inPin2 = ...;

void setup() {
  // ... other stuff, then set up the pins
  pinMode(inPin1, INPUT);
  pinMode(inPin2, INPUT);
}

void loop() {
  // start ultrasound 1
  // start ultrasound 2
  // wait for ultrasound 1 to send pulse
  // wait for ultrasound 1 to send pulse
  long startTime = micros();
  while (digitalRead(inPin1)==LOW && digitalRead(inPin1)==LOW) {
    ; // do nothing
  }

  long stop1st = micros();
  int firstBack = -1;
  while (digitalRead(inPin2)==LOW) { // wait for the other if it was 1 first
    firstBack = inPin1; // remember pin 1 returned first
  }
  while (digitalRead(inPin1)==LOW) { // wait for the other if it was 2 first
    firstBack = inPin2; // remember pin 2 returned first
  }
  long stop2nd = micros();

  // now have the two return times, and the pin which returned first
}

You could read the source of pulseIn() and write better code than this.

The third option, to use external or pin-change interrupts, depends on which Arduino you are using. A normal ATmega328 has a couple of pins, 2 and 3, which have their own 'external' interrupt service routines (ie. each pin has a 'function' which is called when the hardware detects a signal change on a pin). To see how to attach them, see attachInterrupt.

Other pins can also be used with a 'pin change' interrupt, but each interrupt has to figure out which of a port (up to 8 pins) has triggered it, so it isn't as quick and simple.

The idea here is to start the ultrasonic sensors exactly as before, save the time they are started, exactly as before, but let a short interrupt routine capture the time that the returning echo pulse triggers the pin.

There is a little bit of care in making sure the times are captured and the main loop signalled.

You might choose to dedicate a timer to measuring the ultrasounds round trip, if you want higher resolution and lower jitter than the normal 4 microsecond timer. A microsecond is about 0.34mm, so 4 microsecond is about 1.3mm error.

  • "So if timeout is set to 3000 microseconds (3 milliseconds), then it will wait for an echo up to (roughly) 0.5 metres away." It should be close to ~1.02 meters away. Am I right? – Mat_python Oct 1 '16 at 17:29
  • @Mat_python - sound travels 0.3432m/millisecond, so in 3 milliseconds it will travel about 1 metre. An ultrasound sensor works by bouncing sound, so sound has to travel to the object, and then return. So you are measuring round-trip time, hence the distance to the object is total distance/2. – gbulmer Oct 2 '16 at 8:15
  • Thank you. I thought so. I am trying to detect a moving object. i.e, a soccer ball. I am working on building a goal counter. The problem with an ultrasonic sensor is it misses the ball sometimes. I used two ultrasonic sensors to detect a soccer ball, which could be moving really fast, but it detected 8 times out of 10. what could be the problem? Is there any other sensors I can use to detect the soccer ball passing between 0-1.5 meters of distance from the sensor. I also tried PIR sensor, but it does not work well for non-living objects. – Mat_python Oct 2 '16 at 15:51
  • @Mat_python - if all you want to make is a soccer ball counter, would detecting something crossing a line do? That could be easy to make. Or do you mean drive around a field counting balls? You'll need to be clear about the problem, and it may be worth writing a new question. – gbulmer Oct 2 '16 at 17:35
  • Yes. I want to make a soccer ball counter, and detecting something crossing a line will work. I tried using ultrasonic sensor. But, it misses if the ball is too fast. what are other alternatives? I also wrote new question thread on this here : arduino.stackexchange.com/questions/29748 – Mat_python Oct 2 '16 at 19:12

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.