11.6. ReadSonar Arduino Sketch

This sketch is used by Exercise: Read Ultrasonic Ranger.

11.6.1. Full Source Code

The full code is all in one file ReadSonar.ino.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
// ReadSonar - measure distance using a HC-SR04 or compatible ultrasonic ranger
//
// Copyright (c) 2016, Garth Zeglin.  All rights reserved. Licensed under the
// terms of the BSD 3-clause license as included in LICENSE.
//
// This program assumes that:
//
//  1. A SR04 sonar is connected: as follows: pin 8 is TRIG, pin 7 is ECHO.
//     Note: this sensor has +5V digital outputs can connect directly to the
//     digital input pins on the Arduino UNO.
//
//  2. The serial console on the Arduino IDE is set to 9600 baud communications speed.
//
// Note: this works, but could still use refinement.  The actual module echo
// waveform doesn't quite match the description, there appears to be an initial
// HIGH pulse prior to the LOW during propagation time.  A better solution may
// be to use the NewPing library.

// ================================================================================
// Define constant values.

// The wiring assignment.
const int TRIG_PIN = 8;
const int ECHO_PIN = 7;

// The rated distance limit of the sensor, in cm.
const int MAX_DISTANCE = 450;

// A typical speed of sound, specified in cm/sec.
const long SOUND_SPEED = 34000;

// Determine the maximum time to wait for an echo. The maximum rated distance is
// 4.5 meters; if no echo is received within the duration representing this
// round-trip distance, stop measuring.  The timeout is specified in
// microseconds.
const long TIMEOUT = (2 * MAX_DISTANCE * 1000000)/SOUND_SPEED;

// ================================================================================
// Configure the hardware once after booting up.  This runs once after pressing
// reset or powering up the board.

void setup()
{
  // Initialize the serial UART at 9600 bits per second.
  Serial.begin(9600);

  // Initialize the trigger pin for output.
  pinMode(TRIG_PIN, OUTPUT);
  digitalWrite(TRIG_PIN, LOW);
  
  // Initialize the echo pin for input.
  pinMode(ECHO_PIN, INPUT);
}
// ================================================================================
// Run one iteration of the main event loop.  The Arduino system will call this
// function over and over forever.
void loop()
{
  // Read the distance as an uncalibrated timing value in microseconds.
  long duration = ping_sonar(); // function is defined below

  // If valid, scale into real-world units.
  if (duration > 0) {

    // Convert to a distance.  Note that the speed of sound is specified in
    // cm/sec, so the duration is scaled from microsecondst o seconds.  The
    // factor of 2 accounts for the round-trip doubling the time.
    float distance = (duration * 1e-6 * SOUND_SPEED) / 2;

    Serial.print("Ping: ");
    Serial.print(duration);
    Serial.print(" usec   Distance: ");
    Serial.print(distance);
    Serial.println(" cm");

  } else {
    // if no pulse detected
    Serial.println("No ping.");
  }

  // Allow a little extra time for the sonar to recover.
  delay(30);
}

// ================================================================================
// Ping function to run one measurement cycle using the sonar.  Returns a ping
// travel duration in microseconds, or 0 if no echo was observed.

long ping_sonar(void)
{
  // Generate a short trigger pulse.
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  // Measure the pulse length
  return pulseIn(ECHO_PIN, HIGH, TIMEOUT);
}

// ================================================================================