t r o n i x s t u f f

fun and learning with electronics

Tutorial – Parallax Ping))) Ultrasonic Sensor

Sense distance with ultrasonic sensors in chapter forty-five of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – a series of articles on the Arduino universe. The first chapter is here, the complete series is detailed here.

Updated 05/02/2013

Whilst being a passenger in a vehicle with a ‘reversing sensors’, I became somewhat curious as to how the sensors operated and how we can make use of them. So for this chapter we will investigate an ultrasonic sensor from Parallax called the Ping)))™ Ultrasonic Distance Sensor. It can measure distances between ~2cm and ~3m in length. Here is our example sensor:

(Memories of Number Five …)

Parallax have done a lot of work, the board contains not just the bare sensor hardware but controller circuitry as well:

Which is great as it leaves us with only three pins – 5V, GND and signal. More on those in a moment, but first…

How does it work?

Good question. The unit sends out an ultrasonic (a sound that has a frequency which is higher than can be heard by the human ear) burst of sound from one transducer (the round silver things) and waits for it bounce off an object and return – which is detected by the other transducer. The board will then return to us the period of time taken for this process to take, which we can interpret to determine the distance between the sensor and the object from which the ultrasonic sound bounced from.

The Ping))) only measures a distance when requested – to do this we send a very short HIGH pulse of five microseconds to the signal pin. After a brief moment a pulse will come from the board on the same signal pin. The period of this second pulse is the amount of time the sound took to travel out and back from the sensor – so we divide it by two to calculate the distance. Finally, as the the speed of sound is 340 metres per second, the Arduino sketch can calculate the distance to whatever units required.

It may sound complex, but it is not –  so let’s run through the theory of operation with an example. Using our digital storage oscillscope we have measured the waveforms on the signal pin during a typical measurement. Consider the following example of measuring a distance of 12cm (click image to enlarge):

You can see the 5uS pulse in the centre and the pulse returned from the sensor board on the right. Now to zoom in on the returned pulse (click image to enlarge):

Without being too picky the pulse is roughly 720uS (microseconds) long – the duration of ultrasonic sound’s return trip from the sensor board. So we divide this by two to find the time to travel the distance – 360uS. Recall the speed of sound is 340 metres per second – which converts to 29.412 uS per centimetre. So, 360uS divided by 29.412 uS gives 12.239902081… centimetres. Rounded that gives us 12 centimetres. Easy!

Finally, there are some limitations to using the Ping))) sensor. Download the data sheet (pdf) and read pages three to five for information on how to effectively mount the sensor and the sensitivity results from factory resting.

How do we use it with Arduino?

As described previously we first need to send a 5uS pulse, then listen for the return pulse. The following sketch does just that, then converts the data to centimetres and displays the result on the serial monitor. The code has been commented to explain each step.

Example 45.1 

// Example 45.1 - tronixstuff.wordpress.com - CC by-sa-nc
// Connect Ping))) signal pin to Arduino digital 8
int signal=8;
int distance;
unsigned long pulseduration=0;
void setup()
{
 pinMode(signal, OUTPUT);
 Serial.begin(9600);
}
void measureDistance()
{
 // set pin as output so we can send a pulse
 pinMode(signal, OUTPUT);
// set output to LOW
 digitalWrite(signal, LOW);
 delayMicroseconds(5);

 // now send the 5uS pulse out to activate Ping)))
 digitalWrite(signal, HIGH);
 delayMicroseconds(5);
 digitalWrite(signal, LOW);

 // now we need to change the digital pin
 // to input to read the incoming pulse
 pinMode(signal, INPUT);

 // finally, measure the length of the incoming pulse
 pulseduration=pulseIn(signal, HIGH);
}
void loop()
{
 // get the raw measurement data from Ping)))
 measureDistance();

 // divide the pulse length by half
 pulseduration=pulseduration/2; 

 // now convert to centimetres. We're metric here people...
 distance = int(pulseduration/29);

 // Display on serial monitor
 Serial.print("Distance - ");
 Serial.print(distance);
 Serial.println(" cm");
 delay(500);
}

And the results of some hand-waving in the serial monitor:

So there you have it – you can now measure distance with a degree of accuracy. However that image above isn’t very exciting – instead let’s use a 7-segment display shield to get things up in lights. The shield uses the NXP SAA1064 LED display driver IC (explained quite well here). You can download the demonstration sketch from here. And now for the video:

So there you have it – now the use of the sensor is up to your imagination. Stay tuned using the methods below to see what we get up to with this sensor in the future.

Have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column, or join our Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

November 28, 2011 - Posted by | arduino, distance, learning electronics, microcontrollers, parallax, sensor, tutorial, ultrasonic, Uncategorized | , , , , , , , , , , , ,

15 Comments »

  1. Does this unit only work on solid surfaces, or would it be ok for measuring water level in a tank ?

    Comment by steve56 | April 1, 2013 | Reply

    • Yes, you can measure water tank levels, as long as the water surface is still – good for farm tanks, not for things in motion.

      Comment by John Boxall | April 1, 2013 | Reply

      • Hi John,

        If max7219CNG or BCD4511 use what will section of the code look like and does #include “Wire.h” library includes the MAX7219CNG and BCD4511??

        #include “Wire.h”
        byte saa1064 = 0×70 >> 1; // define the I2C bus address for our SAA1064

        void setup()
        {
        Wire.begin(); // start up I2C bus
        pinMode(signal, OUTPUT);
        initDisplay();
        }

        void initDisplay()
        // turns on dynamic mode and adjusts segment current to 12mA
        {
        Wire.beginTransmission(saa1064);
        Wire.write(B00000000); // this is the instruction byte. Zero means the next byte is the control byte
        Wire.write(B01000111); // control byte (dynamic mode on, digits 1+3 on, digits 2+4 on, 12mA segment current
        Wire.endTransmission();
        }

        Comment by Jim | April 9, 2013

      • ? MAX7219 uses SPI bus (not I2C). Also 4511 nothing to do with I2C.

        Comment by John Boxall | April 9, 2013

  2. Hi John,

    I built a remote tank water level sensor using the Ping and an xBee radio to transmit the data back to my PC.

    I powered it with a 9V battery which lasted about 8 hours. Not very satisfactory. The unit logged and radioed data every 15 minutes.

    Can you give any tips on battery powered applications with a view to extending battery life, to maybe a few months ?

    regards
    Steve56

    Comment by Steve56 | May 14, 2013 | Reply

    • Well done Steve. If you don’t have 240V then consider solar-charged lead-acid batteries. Have a poke around Altronics or Jaycar to get an idea.

      Comment by John Boxall | May 14, 2013 | Reply

      • Hi John,

        Following your advice I bought a 12V sealed lead acid battery and solar charger. Given the increased capacity of the battery I’m just checking that I can plug it straight into the Arduino with out blowing the Arduino up.

        thanks
        Steve56

        Comment by Steve56 | May 15, 2013

      • Ah no. You’ll want to drop whatever comes out of the charge system you have using a linear voltage regulator, a simple LM7805-based circuit would do.

        Comment by John Boxall | May 15, 2013

      • John,

        If I connect the 12V battery to Vin on the Freetronics 11, will its on board regulator take care of that , or do I need another regulator besides ?

        Steve56

        Comment by Steve56 | May 15, 2013

      • It’s time you started doing your own homework :)
        Visit Eleven webpage – http://www.freetronics.com/collections/arduino/products/eleven
        Down the bottom are the design files – http://www.github.com/freetronics/Eleven
        See the schematic .pdf file is there – https://github.com/freetronics/Eleven/blob/master/Eleven.pdf
        So open that up. The voltage regulator after the DC socket is a MC33269. Google gets you the data sheet, max input voltage is 20V. However you’d want to keep it lower than that, say 15V max.
        Have a look at your system and find out what the maximum possible voltage output is and go from there.

        Comment by John Boxall | May 16, 2013

    • Dropping the MCU into low power mode between measurements/transmits would probably help a lot. You could use a RTC IC to wake it up – each time the MCU is done with measurement, it would set an alarm on the RTC and go to sleep. When the RTC alarm triggers, the alarm pin, hooked up to the right interrupt pin on the MCU would wake it up, starting another measurement cycle.

      Of course, all this is assuming you’re rolling your own Arduino, as most off the shelf boards (not all) have other components (namely voltage regulators) that tend to draw quite a bit of current, even when the MCU is asleep.

      Comment by Ante Vukorepa | May 14, 2013 | Reply

      • Hi Ante,

        Thanks for your reply. I’m using a Freetronics Eleven, Uno compatible board. The program on the data logger listens to the serial port via the xBee, waiting for an instruction from the controlling PC to send the data, so I’m not sure how I can put it to sleep while it listens.

        Comment by Steve56 | May 15, 2013

  3. Vreau si eu un program pentru masurarea nivelului de lichid dintr-un vas va rog.Folosesc un senzor PING si o placa ARDUINO UNO

    Comment by ANDREEA | May 15, 2013 | Reply


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 3,837 other followers

%d bloggers like this: