Raspberry pi, an Ultrasonic Sensor and Node.js – Measure Distances

This post is part 8 of 9 in the series Raspberry Pi
Tweet about this on TwitterShare on LinkedIn0Share on Google+0Share on Reddit0Buffer this pageFlattr the authorEmail this to someonePrint this page

In this post, we will interface an Ultrasonic sensor – HC-SR04 and Raspberry Pi B+. And then we will write a Node.js program to detect the distances between an object and the Ultrasonic sensor. We will be using an awesome Node.js module named r-pi-usonic to interact with the Ultrasonic sensor from our Pi.

We will be implementing 2 variations of measuring distances using the Ultrasonic sensor. One variation is to get the distance on demand. And the second one is to continuously measure the distance.

Below is a quick demo on

Measuring on-demand

A continuous measurement of distance

You can find the completed code here.

So, let us get started.

Prerequisites

If you are new to Raspberry pi and have not yet installed Node.js on it, I would recommend going through Getting Started with Raspberry pi and Node.js.

If you are new to electronics devices and circuits, I would recommend going through the video lectures from All About Circuits.

Components needed

  1. 1 – Raspberry pi B+
  2. 1 – Breadboard
  3. 1 – 1K Ohm resistor
  4. 1 – HC-SR04 Ultrasonic sensor
  5. 4 – Jumper wires

If you are new to Raspberry Pi GPIO, please refer this.

Understanding HC-SR04 Ultrasonic Sensor

HC-SR04 sensor works with a power of 5v. It has a range of approximately 2cm to 4m. It outputs a frequency of 40khz, twice the human ear can hear. (more info on the sensor here)

As you can see from the above diagram, the HC-SR04 sensor has 4 pins.

  1. VCC  : +5v power supply
  2. Trigger : A high input to this pin for a duration of 10 micro seconds, activates the sensor
  3. Echo : This pin returns the time taken for the transmitted signal to come back after hitting an object.
  4. Ground : Connected to the ground

So, this is how the sensor works. First, we send a high signal to the trigger pin for a duration of 10 micro seconds. This dispatches a sound wave of 40khz frequency via the the Transmitter (speaker on the left hand side of the sensor) and when the sound wave hits an object, it will return an “echo” to the Receiver (mic on the right hand side of the sensor).

When the echo comes back, the echo pin will output a high signal for a duration that is equal to the time taken for the soundwave to originate and echo back. So, the duration of the high signal is directly proportional to twice the distance of the obstacle from the sensor.

Now, we will monitor the duration of the high signal on the echo pin and using this value, we will calculate the distance.

We know that

speed = (distance travelled) / (time taken)

Here the distance will be equal to twice the distance between the obstacle and the sensor. Because, the time we are using is equal to the time taken for the signal to originate and echo back.

We also know that speed of sound is 340 m/s. So, the above equation will become

340 = 2d / time

or

d = 170 * time

So, if we plug in the time from the echo pin, we can calculate the distance between the obstacle and the sensor.

Simple and Easy right!!

Setup HC-SR04 Ultrasonic Sensor

Screen Shot 2014-11-21 at 7.31.26 pm

As you can see from the above diagram, we will connect the VCC pin of the sensor to +5v and GND to GND. We will connect the Trigger pin to GPIO pin 17 and finally we will connect a 1K Ohm resistor between the Echo pin and GPIO pin 18.

The Echo pin outputs a 5V output, which will damage the GPIO pin, if interfaced directly. This is why we connect a 1K Ohm resistor between the Echo and GPIO pin 18.

Node.js Program

Now that we have connected the hardware, we will write a program to measure the distance. We will measure the distance on demand first.

Login to your pi via ssh – terminal/putty. As soon as you ssh into pi, you will be landing inside the /home/pi folder. We will create a new folder here named node_programs. And inside this folder, we will be maintaining all our programs. Run

mkdir node_programs

To step inside that folder, run

cd node_programs

For this post, we will create a new folder named ultraSonicSensor and will step inside this folder. Run

mkdir ultraSonicSensor && cd ultraSonicSensor

Note : You can run multiple commands separated by a &&.

First we will initialize a new node project here. Run

npm init

Fill it up as applicable.

Now we will install a node module named r-pi-usonic to interact with the Ultrasonic sensor. Run

npm install r-pi-usonic --save

Next, we will create a new file named sense.js. And we will open the same in the nano editor. Run

nano sense.js

Paste the below code into the nano editor

Yup, 3 instructions to get the distance.

Line 1 : We require the module

Line 2 : We initiate the module passing in the Trigger GPIO pin number, Echo GPIO pin number and a timeout.

Line 3 : We wait for 60 milliseconds and then print the distance

Let us save the file and run the program. To save the program, press (ctrl+x). This will ask you to save the file. Press Y and press enter key to complete the operation.

To run the program, execute

sudo node sense.js

Now, the distance will be measured from the first object it encounters. If you want you can explicitly place an object for the sensor to detect as show below

Sweet right!

Now, let us say that you are building a robot and you would like to utilize the Ultrasonic sensor to detect obstacles in your path. This way, if the path is clear, you can move your robot ahead. Else, you can look other way and then see if you can proceed in that direction.

The setup we have now is pretty perfect for that scenario. So, instead of measuring the distance on demand, we will be continuously measuring the distance between the first obstacle and our sensor. And below is how we do it.

I have borrowed this code from here and made some changes to it.

Create a new file

nano surveyor.js

And paste the below code into the editor

Things to notice

Line 1,2 : We require the dependencies

Line 4 : Init function that takes

  • Echo pin connected GPIO pin number
  • Trigger pin connected GPIO pin number
  • Timeout
  • Delay
  • Rate

Line 5 :  We initialize the sensor

Line 9 : IIFE – Immediately Invoked Function Expression, that iterates every 60ms (delay) and takes 5 samples (rate) and stores them inside the  distances variables. Finally when 5 samples are completed, we print the median of the distances.

Line 26 : Takes in the 5 samples and prints the median of the distances.

Line 39 :  We invoke the init function.

Save the file and run

sudo node surveyor.js

And you should see

A powerful way to utilize the Ultrasonic sensor.

Hope this post gave you an idea how to work with a Ultrasonic sensor and Raspberry PI B+.


Thanks for reading! Do comment.
@arvindr21

Series Navigation<< Raspberry Pi, 16×2 LCD and Node.js – Print stuffRaspberry Pi, Node.js and Twilio – Is It Raining Arvind? #IoT >>
Tweet about this on TwitterShare on LinkedIn0Share on Google+0Share on Reddit0Buffer this pageFlattr the authorEmail this to someonePrint this page
  • Sandeep Gadhiya

    hiii i have to send this distance mesure to web page or android app what i have to do is ??????????

  • Surampalli Rajesh

    Hello Sir,
    I just followed all the steps mentioned in this blog bit in distance(ultrasonic sensor) is not measuring.
    It shows -1 as output in console
    Could you please help me what should I do to resolve this ??

  • AdamGoodApp

    The ultrasonic module has been updated. The code above will not work.

    You need usonic.createSensor() to be inside the unsonic.init function:

    usonic.init(function (error) {
    if (error) {
    } else {
    var sensor = usonic.createSensor(24, 23, 450);
    }
    });

    I have updated both scripts above, which can be viewed here:

    https://github.com/AdamGoodApp/ultrasonic-distance-sensor

    • Dipto Pratyaksa

      Problem with nested functions is mainly: how do you access the distance values and pass it to the user. Return value cannot be accessed from outside the function.
      We want to use it so it can be compared:

      if distance >100
      do this,
      else
      do something else

      sensor() is is not recognised if used outside the init function.

      Help?

  • ForrestErickson

    The command “sudo npm install r-pi-usonic –save” did not work on my RPi. model B.

    Looks like permission problem but it is beyond me.


    npm WARN package.json [email protected] No repository field.

    npm WARN package.json [email protected] No README data

    > [email protected] install
    /home/pi/node/ultraSonicSensor/node_modules/r-pi-usonic/node_modules/r-pi-gpio

    > node-gyp configure build

    gyp WARN EACCES user "root" does not have permission to access the dev
    dir "/root/.node-gyp/0.12.6"

    gyp WARN EACCES attempting to reinstall using temporary dev dir
    "/home/pi/node/ultraSonicSensor/node_modules/r-pi-usonic/node_modules/r-pi-gpio/.node-gyp"

    gyp ERR! UNCAUGHT EXCEPTION

    gyp ERR! stack Error: spawn ENOMEM

    gyp ERR! stack at exports._errnoException (util.js:746:11)

    gyp ERR! stack at ChildProcess.spawn (child_process.js:1162:11)

    .........
    .....

  • Aniebiet Willie

    I extended it to use two ultrasonic sensors. :-)
    Just the introduction I needed

  • alexdanemarca

    Instead of
    var sensor = usonic.sensor(18, 17, 1000);
    you should have written:
    var sensor = usonic.createSensor(18, 17, 1000);

    and
    var sensor = usonic.sensor(config.echoPin, config.triggerPin, config.timeout);
    should be
    var sensor = usonic.createSensor(config.echoPin, config.triggerPin, config.timeout);

    Thats works for me.
    Your version gives me #Object has no method ‘sensor’

    Otherwise very good code.
    Regards,

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Thanks for sharing alexdanemarca!

      • alexdanemarca

        Why people publish wrong codes and others should debug them? This is not the only case… A tiny detail goes wrong the wholy code.
        Regards,
        alexdanemarca

        • http://thejackalofjavascript.com/ Arvind Ravulavaru

          Are you using Raspberry Pi B+ or any other model?

          • http://thejackalofjavascript.com/ Arvind Ravulavaru

            Also, what is the version of r-pi-usonic module you are using?

          • alexdanemarca
          • http://thejackalofjavascript.com/ Arvind Ravulavaru

            This update happened after I have written the example & I did not check after that. Take a look at this commit. https://github.com/clebert/r-pi-usonic/commit/228dcf769604fdb44ee8540e364d5d1344f96315#diff-04c6e90faac2675aa89e2176d2eec7d8L31

            Also, I do not have any intention to publish wrong code! Nor waste your time!

            Thanks,
            Arvind.

          • alexdanemarca

            Thanks, everything is ok. Be safe….

            With consideration and best wishes,
            alexdanemarca

          • alexdanemarca

            Yes, is B+, not B2 released in february 2015. I don’t think the model matters. The code It is in node.js code under Linux. I have node version 0.10.34
            Regards,

  • YesPapa

    Hi,

    You suggest to use GPIO pins. But in your example, the 17 pin is a power pin on a Pi B+/Pi 2 board. Is it normal?

    I try to redo your example but it doesn’t work.

    Thank you.

    • YesPapa

      Ok. I find my mistake for the pin.

      But it doesn’t work …

      • YesPapa

        Ok. I have a result. But I have only -1cm as a result.

        Have you got an idea for this issue?

        When I run the “surveyor.js” script, I have a timeout error.

        Thank you.

        • YesPapa

          This script is compatible with the raspberry pi 2?

          • YesPapa

            Not seems to be compatible? Do you know why? An update is planned?

            Thank you.

          • http://thejackalofjavascript.com/ Arvind Ravulavaru

            Hey YesPapa, MoD86, The above post is targeted at Raspberry Pi B+. I have not tried it on Raspberry PI 2 yet. I will probably make another series of post with Pi2. Thanks for you interest.

          • Surampalli Rajesh

            I tried this code in Pi B+, but I didn’t get output. I got result as -1 only. Could you please tell me what should I do now??

        • MoD86

          Hello,
          i have the same problem.

  • santhosh

    u specified speed of light is 340 m/s.. infact it’s the speed of sound..

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Thanks! Fixed it.