Skip to content

Instantly share code, notes, and snippets.

@mikedotalmond
Last active July 6, 2017 14:01
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mikedotalmond/6044960 to your computer and use it in GitHub Desktop.
Save mikedotalmond/6044960 to your computer and use it in GitHub Desktop.
Example sketch for working with the HC-SR04 Ultrasound distance sensor. Uses https://github.com/mikedotalmond/arduino-pulseInWithoutDelay
/**
* @author Mike Almond - @mikedotalmond
*
* Example sketch for working with the HC-SR04 Ultrasound distance sensor
* http://users.ece.utexas.edu/~valvano/Datasheets/HCSR04b.pdf
*
* Uses a hardware interrupt to monitor the echo pin and measure the pulse length (without pausing code execution like you would when using Arduino::pulseIn())
* https://github.com/mikedotalmond/arduino-pulseInWithoutDelay
* PulseInZero uses interrupt 0 ( pin 2 on arduino uno)
* PulseInOne uses interrupt 1 ( pin 3 on an arduino uno)
*
* See http://arduino.cc/en/Reference/AttachInterrupt for more on the Arduino hardware interrupts
*
**/
#include <PulseInZero.h> //
//#include <PulseInOne.h> //
const float SpeedOfSound = 343.2; // ~speed of sound (m/s) in air, at 20°C
const float MicrosecondsPerMillimetre = 1000.0 / SpeedOfSound; // microseconds per millimetre - sound travels 1 mm in ~2.9us
const float MicrosecondsToMillimetres = (1.0 / MicrosecondsPerMillimetre);
const float MicrosecondsToMillimetres2 = MicrosecondsToMillimetres / 2.0; // beam travels the distance twice... so halve the time.
const int SIGNAL_PIN = 12; // digital pin connected to the trigger port on the module
// connect the echo port to the pin for interrupt 0 (pin 2 on Uno)
//
unsigned long lastTime = 0;
int pingTimer = 0;
int pingDelay = 500; // milliseconds between ping pulses
float millimetres = 0.0;
void setup() {
Serial.begin(9600);
pinMode(SIGNAL_PIN, OUTPUT);
digitalWrite(SIGNAL_PIN, LOW);
// set up PulseInZero (pulseIn alternative using interrupt 0 - pin2 on an Arduino Uno)
// use PulseInZero::begin() in place of pulseIn() and pulseComplete will fire when a pulse completes
PulseInZero::setup(pingPulseComplete);
}
void loop() {
unsigned long time = millis();
unsigned long dt = time - lastTime;
lastTime = time;
pingTimer += dt;
if(pingTimer > pingDelay){
pingTimer = 0;
ping();
}
// do stuff...
}
/**
* Trigger the outward ping pulse(s)
*/
void ping(){
// Serial.println("ping out");
digitalWrite(SIGNAL_PIN, HIGH);
delayMicroseconds(10); // I think I can cope with blocking for a whole 10us here...
digitalWrite(SIGNAL_PIN, LOW);
// start listening out for the echo pulse on interrupt 0
PulseInZero::begin();
}
/**
* Pulse complete callback hanlder for PulseInZero
* @param duration - pulse length in microseconds
*/
void pingPulseComplete(unsigned long duration) {
millimetres = MicrosecondsToMillimetres2 * duration;
if(millimetres > 4000){
Serial.println("out of range");
// out of range (http://users.ece.utexas.edu/~valvano/Datasheets/HCSR04b.pdf)
millimetres = 4000;
} else {
Serial.print("duration: ");
Serial.print(duration);
Serial.print(" us, distance: ");
Serial.print(millimetres);
Serial.println(" mm");
}
}
@raiyaan-abdullah
Copy link

Thanks bhai!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment