Simple Arduino HC-SR04 (HCSR04) Distance Detection Using ...
Maybe your like
Instantly share code, notes, and snippets.
- Download ZIP
- Star (3) You must be signed in to star a gist
- Fork (3) You must be signed in to fork a gist
- Embed Select an option
- Embed Embed this gist in your website.
- Share Copy sharable link for this gist.
- Clone via HTTPS Clone using the web URL.
No results found
Learn more about clone URLs Clone this repository at <script src="https://gist.github.com/wolph/0094b278a54f8f472c76b7eb0d0a8f89.js"></script> - Save wolph/0094b278a54f8f472c76b7eb0d0a8f89 to your computer and use it in GitHub Desktop.
- Embed Embed this gist in your website.
- Share Copy sharable link for this gist.
- Clone via HTTPS Clone using the web URL.
No results found
Learn more about clone URLs Clone this repository at <script src="https://gist.github.com/wolph/0094b278a54f8f472c76b7eb0d0a8f89.js"></script> Save wolph/0094b278a54f8f472c76b7eb0d0a8f89 to your computer and use it in GitHub Desktop. Download ZIP Simple arduino HC-SR04 (HCSR04) distance detection using interrupts for low latency measurements Raw hcsr04.ino This file contains hidden or 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 Show hidden characters| #include <Arduino.h> |
| // Uses https://github.com/PaulStoffregen/TimerOne for sending on a regular interval |
| #include <TimerOne.h> |
| // ECHO pin, needs to be a pin that supports interrupts! |
| #define ULTRASONIC_PIN_INPUT 2 |
| // TRIG pin, can be any output pin |
| #define ULTRASONIC_PIN_OUTPUT 3 |
| // update interval, make sure to keep it above 20ms |
| #define ULTRASONIC_TIMER_US 50000 |
| // the time the pulse was sent |
| volatile long ultrasonic_echo_start = 0; |
| // the distance once it's been measured |
| volatile long ultrasonic_distance = 0; |
| void ultrasonicPulse(){ |
| // Sets the trigger on HIGH state for 10 micro seconds to send a series of pulses |
| digitalWrite(ULTRASONIC_PIN_OUTPUT, HIGH); |
| // blocks 10 microseconds from the interrupt, I think we'll live :) |
| delayMicroseconds(10); |
| // disable the sending again so we can wait for a response |
| digitalWrite(ULTRASONIC_PIN_OUTPUT, LOW); |
| // record the send time |
| ultrasonic_echo_start = micros(); |
| } |
| void ultrasonicEcho(){ |
| // don't do anything if no pulse has been sent |
| if(ultrasonic_echo_start != 0){ |
| // calculate the distance by measuring how long it took to return the sound |
| // The speed of sound is 343 m/s and we need half the time it took (since |
| // the sound has to travel towards the object _AND_ back). So a single echo does |
| // 1/(343/2) = 0.005831 seconds per meter |
| ultrasonic_distance = (micros() - ultrasonic_echo_start) / 58; |
| ultrasonic_echo_start = 0; |
| } |
| } |
| void setup(){ |
| Serial.begin(115200); |
| // set the echo pin to receive interrupts, on an arduino uno only pin 2 and 3 can link to interrupts |
| pinMode(ULTRASONIC_PIN_INPUT, INPUT_PULLUP); |
| pinMode(ULTRASONIC_PIN_OUTPUT, OUTPUT); |
| // set the update interval for sending the trigger |
| Timer1.initialize(ULTRASONIC_TIMER_US); |
| // link the trigger function to the timer |
| Timer1.attachInterrupt(ultrasonicPulse); |
| // link the echo function to the echo pin |
| attachInterrupt(digitalPinToInterrupt(ULTRASONIC_PIN_INPUT), ultrasonicEcho, RISING); |
| } |
| void loop() { |
| Serial.print("Distance: "); |
| Serial.println(ultrasonic_distance); |
| delay(ULTRASONIC_TIMER_US / 1000); |
| } |
huyvo2020 commented Nov 30, 2020
Have you test the code and on which HW? Normally, HCR04 send back the pulse with on Echo pin, but what you coded is the delay time between Trigger rising and Echo rising.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
wolph commented Nov 30, 2020
I've tried it with this thing and it seemed to work fine: https://wiki.keyestudio.com/Ks0192_keyestudio_4WD_Bluetooth_Multi-functional_Car
I'm not ruling out that there are bugs though... but it seemed to work perfect for a distance range between ~20cm and 1.5m if I remember correctly.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
dcmid commented Dec 3, 2020
Strangely, I get a constant 8cm distance when using this code. I ended up on this page because I had written my own version and was getting the 8cm issue. Our programs are nearly identical, so I copied yours to see if it worked better. Everything works perfectly fine if I don't use the pin interrupt and instead just use pulseIn during the timer interrupt, but of course that needlessly ties things up. I'll do some more digging tomorrow. Just figured I would mention it in case anybody has a similar problem in the future.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
greenonline commented Sep 9, 2021
For good practice, add these three lines to the start of ultrasonicPulse() to clear the trigger pin.
// Clears the trigger Pin digitalWrite(ULTRASONIC_PIN_OUTPUT, LOW); delayMicroseconds(2);like so
void ultrasonicPulse(){ // Clears the trigger Pin digitalWrite(ULTRASONIC_PIN_OUTPUT, LOW); delayMicroseconds(2); // Sets the trigger on HIGH state for 10 micro seconds to send a series of pulses digitalWrite(ULTRASONIC_PIN_OUTPUT, HIGH); // blocks 10 microseconds from the interrupt, I think we'll live :) delayMicroseconds(10); // disable the sending again so we can wait for a response digitalWrite(ULTRASONIC_PIN_OUTPUT, LOW); // record the send time ultrasonic_echo_start = micros(); }Also, the echo is a falling edge (usually), unless the signal has been inverted, so
attachInterrupt(digitalPinToInterrupt(ULTRASONIC_PIN_INPUT), ultrasonicEcho, RISING);should be
attachInterrupt(digitalPinToInterrupt(ULTRASONIC_PIN_INPUT), ultrasonicEcho, FALLING);One other thing is that there is an assumption made in your code that the echo pin has risen HIGH, when you execute this line:
ultrasonic_echo_start = micros();Logically, it should have but it might not be the case.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
ingtommi commented Nov 16, 2023
Aiming to code the same functionality I found this conversation and I thank you for the examples.
I'd like to share my version of the code, where I don't use a timer for the trigger (maybe should be a good pratice...) but I try to improve the accuracy considering only the time between the two echo edges (anyway, the same goal could have been reached by compensating the offset).
#include <TimerInterrupt_Generic.h> const int trigPin = 4; const int echoPin = 3; //3x 3.3kOhm used to divide voltage volatile bool echoFallen = false; volatile unsigned long echoStart, echoEnd; unsigned long duration; unsigned int distance; void setup(){ Serial.begin(9600); pinMode(echoPin, INPUT); pinMode(trigPin, OUTPUT); attachInterrupt(digitalPinToInterrupt(echoPin), ultrasonicEcho, CHANGE); } void loop() { //send trigger ultrasonicTrig(); //wait for falling edge if(echoFallen){ duration = echoEnd - echoStart; //s = v*t, sound speed is 343 m/s, wave reaches object and comes back distance = .0343*(duration/2); //unset falling edge flag echoFallen = false; } //output Serial.print("Distance (cm): "); Serial.println(distance); delay(1000); } //trigger void ultrasonicTrig(){ //clear pin digitalWrite(trigPin, LOW); delayMicroseconds(2); //send pulse digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); } //ISR void ultrasonicEcho(){ switch(digitalRead(echoPin)){ case HIGH: echoStart = micros(); break; case LOW: echoEnd = micros(); //set falling edge flag echoFallen = true; } }Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment You can’t perform that action at this time.Tag » Arduino Hc-sr04 Interrupt
-
Generating An Interrupt From HC-SR04 Ultrasonic Sensor
-
Reading The HC-SR04 With Timer1 And No Interrupts - Arduino Forum
-
Arduino Programming The HC-SR04 With Interrupts
-
Arduino Interrupt For Ultrasonic Sensor - YouTube
-
Arduino Programming The HC-SR04 With Interrupts - YouTube
-
Non-blocking Ultrasonic Sensor For Arduino : 3 Steps - Instructables
-
Interrupt Arduino When A Particular Value Is Read By A Ultrasonic ...
-
How To Measure Distance Using Ultrasonic Sensor
-
Arduino Multi-tasking - The Online Shed
-
HC-SR04 Sensor Timer Interrupt Issues - AVR Freaks
-
Arduino Interrupt Tutorial
-
Trying To Use Ultrasonic Sensor With Interrupts - ESP32 Forum
-
Arduino - En Utilisant Les Interruptions De Gels De Traitement Et De ...
-
Interrupt | Cộng đồng Arduino Việt Nam