How to read a HC-SR04 sensor without a delay?

Hi everyone. I have been trying to read a HC-SR04 sensor with no delay in the program. I would like to be able to call the function ie void scan() for when I want to be updating the sensor.

The 1st thing I tryed was to put a delay loop, similar to the one in blink without delay. And this did work for pulling the trigPin high and low at the right points.

 if( 10 > (micros() - SonarLoopCapture) > 5) {
    digitalWrite(TrigPin, HIGH);
  }
  
  if(micros() - SonarLoopCapture > 10) {
    digitalWrite(TrigPin, LOW);
    SonarLoopCapture = micros();
  }

However, where it get's caught up is that I was using pulseIn to capture the legnth of the echo pin. The code waits for a response, thus adding a delay and ruining everything else.

I need a way of reading the legnth of the echoPin without using any delay. I have already used the interrupts.

Thanks, david.

1 Like

if you don't want a delay you must use interrupts and capture the micros() in the ISR()

you could use PinChangeINterrupts for that.

(not trivial but doable)

if( 10 > (micros() - SonarLoopCapture) > 5) {

So, if 10 is greater than the subtraction result, compare true to 5. Otherwise, compare false to 5.

Since neither true or false is greater than 5, the if statement will never evaluate to true.

Only Brian Kernighan and Dennis Ritchie are allowed to invent shortcuts. The rest of us have to do it the correct way.

Woops! My bad

  if((micros() - SonarLoopCapture) > 5) {
    digitalWrite(TrigPin, HIGH);
  }
  
  if((micros() - SonarLoopCapture) > 10) {
    digitalWrite(TrigPin, LOW);
    SonarLoopCapture = micros();
  }

robtillaart:
if you don't want a delay you must use interrupts and capture the micros() in the ISR()
you could use PinChangeINterrupts for that.
(not trivial but doable)

If you can use Pin 2 or Pin 3 you can use the external interrupt feature:

volatile unsigned long LastPulseTime;
void setup() {
attachInterrupt(0, EchoPinISR, CHANGE);  // Pin 2 interrupt on any change
}
.
.
.
void EchoPinISR() {
    static unsigned long startTime;
    if (digitalRead(2)) // Gone HIGH
        startTime = micros();
    else  // Gone LOW
        LastPulseTime = micros() - startTime;
}

Have you looked at the NewPing library?

Yep, sorry for being inactive. I have tried the NewPing library and it introduces a delay which is enough to screw with all the other stuff in my code. I am thinking that if I can change the interrupt pins while the chip in running I can do it. So I could have the interrupt active on pins 2 & 3 for a second or two, then I could change the interrupt pins to 7 or 8 to read the HS-SR04 for a little bit.

Is this doable?

Thanks.

So I could have the interrupt active on pins 2 & 3 for a second or two, then I could change the interrupt pins to 7 or 8 to read the HS-SR04 for a little bit.

Is this doable?

Are pins 7 and 8 external interrupt pins on your Arduino?