Thursday, February 12, 2015

HC-SR04 : using an ultrasonic module as a motion detector




Abstract

This week we are going to use our preferred ultrasonic sensor as a motion detection module. This is an alternative to the classical PIR sensors (see here) with its pros and contras that we will try to illustrate.

The idea

We are going to use the HC-SR04 to measure some default distance (background distance) B. At regular time frames we are going to measure a new distance, say D. If D is different from A, then this means that there is an obstacle between the sonar and B.

Computing the background distance

We assume that the sensor has been fixed on some support and that for a certain interval of time there are no objects that enter in the scene. From this post, the safe interval of times between two distinct distance measurements is 26ms. Therefore we are going to perform SAMPLESIZE measurements and take the average distance (rounded up) as background distance.


uint16_t SetupDefaultDistance() {
  
  uint64_t averageMillis;
  uint32_t i;

  for(i=0, averageMillis=0; i<SAMPLESIZE; i++) {
    averageMillis += readoutSensor();
    delay(INITDELAYMS);
  }
 
  // return the mean (rounded up)
  return (uint16_t)(averageMillis/SAMPLESIZE); 
}

Configuring the sketch

Using a different ultrasonic module. To configure the sketch for a different ultrasonic module, the just change the definition of INITDELAYMS which is the minimal time between two valid distance measurements. The duration of the trigger signal is configured by changing TRIGLENUS (expressed in microseconds).

Choosing sample size. The duration and precision of the computation of the calibration phase is regulated by the macro SAMPLESIZE which accounts for the number of measurements over which take the mean distance (ie the background distance). Of course, the larger this number the more precise will be the value of the background distance. However, remark that larger sample sizes require greater times to be computed. We think that setting it to 100 is a good trade-off.

Sensibility. As it is well-known, the measurements of our sensor are not perfect. Therefore, if we don't want to trigger alarm just because a measuring error, it is better to setup some tolerance for measurement errors. Tolerance is controlled by the macro TOLERANCE which contains a float number between 0 and 1 which stands for the percentage of errors that we accept. Of course, it is not wise to setup a tolerance which is lower than your sensor precision ;-)

The pinout. The sketch uses digital pins 2 (ECHO signal) and 4 (TRIGGER signal). If one needs to change them, just change the corresponding macro definitions TRIGPIN and ECHOPIN.

The complete sketch


/**
 * \file MotionDetection.ino
 * \brief Motion detection using an HC-SR04
 * \author Enrico Formenti
 * \date 9 february 2015
 * \version 1.0
 * \copyright BSD license, check the License page on the blog for more information. All this text must be
 *  included in any redistribution.
 *  <br><br>
 *  See macduino.blogspot.com for more details.
 */

// the include below is for old versions of the IDE
// #include <Serial.h>

#define SAMPLESIZE 100
#define TOLERANCE .01
#define INITDELAYMS 26
#define TRIGLENUS 10

// trigger pin of HC-SR04
#define TRIGPIN 4 
// echo pin of HC-SR04
#define ECHOPIN 2

uint16_t defaultMS;
uint16_t curMillis;
uint16_t millisTolerance;

uint16_t readoutSensor() {
  // The sensor is triggered by a HIGH pulse of 10us or more.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  digitalWrite(TRIGPIN, LOW);
  delayMicroseconds(3);

  // Start trigger signal

  digitalWrite(TRIGPIN, HIGH);
  delayMicroseconds(TRIGLENUS);
  digitalWrite(TRIGPIN, LOW);
 
  // Read the signal from the sensor: a HIGH pulse whose
  // duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
 
  return pulseIn(ECHOPIN, HIGH);
}

uint16_t SetupDefaultDistance() {
  
  uint64_t averageMillis;
  uint32_t i;

  for(i=0, averageMillis = 0; i<SAMPLESIZE; i++) {
    averageMillis += readoutSensor();
    delay(INITDELAYMS);
  }
 
  // return the mean (rounded up)
  return (uint16_t)(averageMillis/SAMPLESIZE); 
}



void setup() {

  // setup pins
  pinMode(TRIGPIN, OUTPUT);
  pinMode(ECHOPIN, INPUT);

  // init serial communication
  Serial.begin(9600);

  // compute background distance
  Serial.print("Computing defaults...");

  defaultMS = SetupDefaultDistance();
  millisTolerance = (uint16_t)(defaultMS * TOLERANCE);
  
  Serial.println("Done."); 
}

void loop() {
  uint16_t val;
  
  curMillis = readoutSensor();

  if ( curMillis>defaultMS) 
    val = curMillis-defaultMS;
  else
    val = defaultMS - curMillis;
        
  if( val > millisTolerance)
    Serial.println("Motion detected!");
 
  delay(INITDELAYMS);
}

Remark that in the sketch all the distances etc. are expressend in milliseconds since there is no point to transform them into real distance. Indeed, we just want to measure differences!

Detection failures

If an object runs through the sensing cone of the HC-SR04 fast enough, then the sensor may fail to detect it. Indeed, assume that the sensing cone is 30 degrees wide (horizontally) and that an object traverses the cone at some distance d in a direction which is parallel to the sensor as illustrated in Figure 1. The HC-SR04 is positioned at the bottom of the triangle.
Fig. 1. Example of detection failure.
Then, with simple trigonometric calculations we may find that the speed v is given by the formula given in Figure 1, where td is the time that takes the sound wave emitted by the HC-SR04 to travel the distance d. For example, if d=4m then v is about 91 m/s.

HC-SR04 vs. PIR sensor

Each of these two modules has its own precise purpose which is distance measuring for HC-SR04 and motion detection for a PIR sensor. It is pretty clear that a PIR sensor cannot be used for distance measuring; however, an HC-SR04 can be used as a motion detector as it is proved by our previous sketch. Let us try to list advantages and disadvantages.

Advantages
  • Multipurpose: the HC-SR04 can be reverted for measuring distances; then back to motion detection and so on.
  • Configuration: the HC-SR04 can be quickly reconfigured completely via software; while, in general, PIR sensors need manual hardware configuration.
  • Initialization: can be pretty fast on the HC-SR04 (2-3 seconds); while it is a least 10 seconds on most PIR sensors.
Disadvantages
  • Sensing cone: PIR sensors have large sensing cones while the cone of HC-SR04 is very few degrees wide vertically and less than 30 degrees horizontally.
  • Speed: of course, light speed (PIR sensor) is incomparably higher than sound speed (HC-SR04).
  • CPU usage: the HC-SR04 needs to send signals periodically in order to detect motion and this uses CPU of course. On the other hand, PIR sensors are passive sensors, so they need CPU only when a motion is detected (if they are attached to an interrupt).
  • Detection failures: because of its low speed, the HC-SR04 may fail to detect a fast enough moving object (see the dedicated section); while this is nearly impossible for PIR sensors.

See also

HC-SR04: avoiding oversampling errors
HC-SR04: what is the distribution law for the frequencies of values? (Part 2)
HC-SR04: what is the distribution law for the frequencies of values? (Part 1)
HC-SR04 : using multiple ultrasonic modules
Introduction to HC-SR04

Conclusions

Each module is designed for its own purpose. However, turning an HC-SR04 into a motion detector can be useful in some situations.

Enjoy!

No comments :

Post a Comment