Wednesday, 17 June 2015

Connecting and programming a HC-SR04 ultrasonic sensor for Arduino

I wanted to make a simple Arduino controlled robot so I ordered a few parts from AliExpress. One of these parts was a HC-SR04 ultrasonic sensor. It is a cheap (a few dollars including delivery) ultrasonic sensor which has sufficient range and accuracy for my needs.

Figure 1: HC-SR04 ultrasonic sensor
The basic details of the HC-SR04 sensor are listed below:
  • Voltage: 5V DC
  • Current: 15mA
  • Minimum range: 2cm
  • Max range: 4m
  • Working frequency: 40Hz
  • Measuring angle: 15 degrees

More details can be found in the data sheet here

The sensor has 4 pins being Vcc, Trig, Echo and GND.

Connecting it to the Arduino is simple. As it has very low power requirements (15mA) the Vcc and GND pins can be directly connected to the 5V and GND pins on the Arduino. The Trig and Echo pins can be connected to any digital IO pins on the Arduino.

A diagram and photo showing how I connected the sensor and Arduino together are shown in Figures 2 and 3 below.
Figure 2: Wiring diagram for Arduino and HC-SR04

Figure 3: Photo of actual Arduino and HC-SR04 setup
Programming the Arduino to work with the sensor is simple but it requires an understanding of how the sensor operates.

The sensor sends out an ultrasonic ping and then measures the time taken for the signal to bounce off the nearest surface and return. It works on all surfaces including glass but can have problems with acoustically soft surfaces like curtains. A diagram illustrating how an ultrasonic sensor works is shown below in Figure 4.

Figure 4: How an ultrasonic sensor works
The ping is initiated when the Trig pin is set high for 10 micro seconds. When the ping returns the Echo pin is held high for the amount of time that the ping took to return.

To convert the ping return time into a distance we need to do some math. The measured time is the round trip time so it includes the time taken for the ping to travel back from the object to the sensor. We only want the distance to the object so we can halve the time.

Now that we know how long sound takes to reach the object we can calculate how far away it is. The speed of sound is approximately 340m/s. There are 100 centimetres in a metre and 1,000,000 microseconds in a second. Therefore it takes sound 1,000,000 / (340 * 100) = 29 microseconds (approximately) to travel 1 centimetre.

So the calculation looks like this:
Distance (cm) = Measured time / 2 / 29

To make the code neater and more reusable I created a function which sends out a ping, measures the return time and returns the result of the calculation (Figure 5 below).
//Returns the distance in centimetres measured by the ultrasonic sensor
int measureDistance()
{
  //Send an ultrasonic ping
  digitalWrite(SR04TrigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(SR04TrigPin, LOW);
  
  //Determine the ping time
  long pingTime = pulseIn(SR04EchoPin, HIGH);
  
  //Calculate the distance
  //Distance to object is only half ping time
  //Takes 29 microseconds to travel 1 cm so divide by 29
  int distance_cm = pingTime / 2 / 29;

  return distance_cm;  
}
Figure 5: Function which return distance in centimetres

To test the code all that's left is to setup the input and output pins and find a way to display the measured value. I configured pin 3 to be the Trig pin and pin 2 for the echo pin. As for the display I decided to print the result to the serial port as it can be easily viewed in Serial Monitor.

The full code for the project is shown below in Figure 6 and an example output from Serial Monitor is shown in in Figure 7. 


//HC-SR04 ultrasonic sensor test sketch
//Created by Blax
//www.blaxlab.com

#define SR04TrigPin 3
#define SR04EchoPin 2

void setup() {  
  //Setup HC-SR04 ultrasonic sensor
  pinMode(SR04TrigPin, OUTPUT);
  pinMode(SR04EchoPin, INPUT);
  
  //Initialize serial communication at 9600bps
  Serial.begin(9600);
}

void loop() {
  //Get the distance to nearest object
  int distance_cm = measureDistance();
  
   //Print the distance
   Serial.println(distance_cm);
  
  //Wait a half second before measuring again
  delay(500);
}

//Returns the distance in centimetres measured by the ultrasonic sensor
int measureDistance()
{
  //Send an ultrasonic ping
  digitalWrite(SR04TrigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(SR04TrigPin, LOW);
  
  //Determine the ping time
  long pingTime = pulseIn(SR04EchoPin, HIGH);
  
  //Calculate the distance
  //Distance to object is only half ping time
  //Takes 29 microseconds to travel 1 cm so divide by 29
  int distance_cm = pingTime / 2 / 29;

  return distance_cm;  
}
Figure 6: HC-SR04 ultrasonic sensor test code
Figure 7: Sample code output in Serial Monitor

No comments:

Post a Comment