Last active
July 6, 2017 14:01
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @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"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks bhai!