Arduino HC-SR04 Distance Sensor Driver Implementation

HC-SR04 Ultrasonic Sensor and Arduino

The HC-SR04 Ultrasonic Sensor is a very affordable proximity/distance sensor that has been used mainly for object avoidance in various Arduino robotics projects.  It provides 2cm to 400cm of non-contact measurement functionality with a ranging accuracy that can reach up to 3mm. Each HC-SR04 module includes an ultrasonic transmitter, a receiver and a control circuit.

In case we want to change our sensor in the future for a different one we will use programming interfaces.  The interface is a description of the actions that an object can do… for example when you flip a light switch, the light goes on, you don’t care how, just that it does. In Object Oriented Programming, an Interface is a description of all functions that an object must have in order to be an “X”. Again, as an example, anything that “ACTS LIKE” a light, should have a turn_on() method and a turn_off() method. The purpose of interfaces is to allow the computer to enforce these properties and to know that an object of TYPE T (whatever the interface is ) must have functions called X,Y,Z, etc.

How to connect Distance Sensor to Arduino Uno?

Interface

/**
 * Distance Sensor Driver Interface
 *
 * @file distance_sensor_driver.h
 * @brief Distance Sensor Driver Interface
 * @author Robert Meisner <robert@catchit.pl>
 * @version 1.0 2016-12-22
 */


namespace CatchIT
{
     class DistanceSensorDriver
    {
    public:
		virtual void init() = 0;
        /**
          * @brief Class constructor.
          */
        DistanceSensorDriver(unsigned int distance) : maxDistance(distance) {}
        
        /**
         * @brief Return the distance to the nearest obstacle in centimeters.
         * @return the distance to the closest object in centimeters 
         *   or maxDistance if no object was detected
         */
        virtual unsigned long getDistance() = 0;
        
    protected:
        unsigned int maxDistance;
    };
};

Arduino – HC-SR04 Implementation

/**
 * HC-SR04 Distance Sensor Driver Implementation
 *
 * @file hc_sr04_distance_sensor_driver.h
 * @brief HC-SR04 Distance Sensor Driver Implementation
 * @author Robert Meisner <robert@catchit.pl>
 * @version 1.0 2016-12-22
 */


#include "distance_sensor_driver.h"

#define MEASURE_SAMPLE_DELAY 5
#define MEASURE_SAMPLES 25
namespace CatchIT
{
class HC04DistanceSensorDriver : public DistanceSensorDriver
{
  public:
    HC04DistanceSensorDriver(int triggerPin, int echoPin, int maxDistance)
        : DistanceSensorDriver(maxDistance),
          triggerPin(triggerPin), echoPin(echoPin)
    {
    }
    void init()
    {
        Serial.print("Initiating Distance Sensor on :");
        Serial.println(echoPin);
        pinMode(echoPin, INPUT);
        pinMode(triggerPin, OUTPUT);
    }
    virtual unsigned long getDistance()
    {
        long dist = measure();
        //Serial.println(dist);
        return dist;
    }

  private:
    int triggerPin;
    int echoPin;
    const float usonicDiv = 58.0;

    long measure()
    {
        long measureSum = 0;
        for (int i = 0; i < MEASURE_SAMPLES; i++)
        {
            delay(MEASURE_SAMPLE_DELAY);
            measureSum += singleMeasurement();
        }
        return measureSum / MEASURE_SAMPLES;
    }
    long singleMeasurement()
    {
        long duration = 0;
        // Measure: Put up Trigger...
        digitalWrite(triggerPin, LOW);
        delayMicroseconds(2);
        digitalWrite(triggerPin, HIGH);
        delayMicroseconds(10);
        digitalWrite(triggerPin, LOW);
        duration = pulseIn(echoPin, HIGH);
        return (long)(((float)duration / usonicDiv) * 10.0);
    }
};
};

Example Arduino code

/*
 Distance
 Reads a distance, prints the result to the serial monitor
*/

#include "hc_sr04_distance_sensor_driver.h"
int trigPin = 2;
int echoPin = 4;
UsefulDrivers::HC04DistanceSensorDriver *driver = new UsefulDrivers::HC04DistanceSensorDriver(trigPin, echoPin, 3000);
// the setup function runs once when you press reset or power the board
void setup()
{
    // initialize serial communication at 9600 bits per second:
    Serial.begin(9600);
    // put your setup code here, to run once:
    driver->init();
}
// the loop function runs over and over again forever
void loop()
{
    // put your main code here, to run repeatedly:
    unsigned long distance = driver->getDistance();
    Serial.print("Distance is: ");
    Serial.print(distance);
    Serial.println("mm");

    // wait for 30 milliseconds
    delay(30);
}

 

You can find source files and examples in this Github repo:

https://github.com/robertmeisner/useful-drivers