I have code for an ultrasonic sensor which I found from a site. Here is the code:

#define trigPin 12
#define echoPin 13

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

void loop() {
  int duration, distance;
  digitalWrite(trigPin, HIGH);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2) / 29.1;
  if (distance >= 200 || distance <= 0){
    Serial.println("Out of range");
  else {
    Serial.println(" cm");

However, I don't understand the work of pulseIn() function. I mean, I want to know when the time count starts and when it ends. For example, in this code, does the time start at digitalWrite(trigPin, HIGH); or does the time start at the pulseIn() function?

If it's the second one, when it stops, then how does the time give us the distance of an obstacle when I am already delaying 1000 microseconds after I send a ping in air?

  • The 100us delay for the trigger pin seems a bit long to me. It depends on the brand of your sensor, but a typical value (I use it with HC-SR04) is around 10us.
    – jfpoilpret
    Jun 9, 2014 at 7:31
  • How can i do this code in assembly languaje???? Please help.
    – user6603
    Jan 8, 2015 at 19:03
  • 1
    How can i do this code in assembly languaje - what does that have to do with this question?
    – Nick Gammon
    Jan 25, 2016 at 5:31

4 Answers 4


From the docs:

Reads a pulse (either HIGH or LOW) on a pin. For example, if value is HIGH, pulseIn() waits for the pin to go HIGH, starts timing, then waits for the pin to go LOW and stops timing. Returns the length of the pulse in microseconds. pulsein

So, in this case, pulseIn(echoPin, HIGH) starts counting the number of microseconds until echoPin goes HIGH and stores that in duration.

It starts and ends on that line, it's what is known as a blocking function. It will really sit there until echoPin goes high and tells you how long it took (unless you specify a timeout).

That also means that any delays you have before or after the pulseIn call don't affect it in any way.

The way you get distance from this time is by the following equation:

distance = (duration/2) / 29.1;

You divide by two because it goes out and back so the time would be double that of a one-way travel. The 29.1 is the speed of sound (which is 343.5 m/s => 1 / 0.03435 = 29.1). So note the result is in CM's, not inches. You could probably figure it out by looking at the data sheet of the sensor or just get a lot of samples relating duration to distance (you would measure the distance manually) and get an equation that is very similar.

  • 1
    I've been Skeeted! Actually, the 29.1 is the speed of sound. Also, just a quick addition: IIRC the reason that there's a pulse to read is the ultrasonic module produces a HIGH signal until the sound makes its way back to the module. Jun 8, 2014 at 18:16
  • 1
    I didn't understand the fourth paragraph. Because if I send a sound pulse in air and wait 2 second it will travel a lot distance. So when I start counting I will be 2 seconds late. So why there isn't any problem if I give delays before pulseIn? @ sachleen. And thanks Annonomus Penguin and sachlee
    – shajib0o
    Jun 9, 2014 at 15:16
  • @shajib0o "pulseIn() waits for the pin to go HIGH, starts timing, then waits for the pin to go LOW and stops timing."
    – sachleen
    Jun 9, 2014 at 15:28
  • 3
    @shajib0o As far as I can tell, it's that the ultrasonic sensor makes the pin go HIGH when the signal is sent and then LOW when the signal comes back. Jun 9, 2014 at 21:33
  • 1
    Actually, this is wrong. pulseIn(echoPin, HIGH) measures the time until the ECHO pin goes LOW. Feb 6, 2018 at 22:33

Indeed it would be a problem if you started to measure the pulse length 1000 microseconds after it starts. However, this is not how the HC-SR04 sensor works:

enter image description here

  • the sensor is triggered by the falling edge of TRIG, at digitalWrite(trigPin, LOW);

  • the ECHO pulse starts about 0.3 ms after the trigger

That's why a delay of 1 ms doesn't affect the measurement result. pulseIn(echoPin, HIGH) will actually wait for the ECHO pin go HIGH, then start measuring the pulse length until it goes LOW again. As such, the duration of the TRIG pulse can be reduced to 10 microseconds (minimum TRIG duration for HC-SR04), to make the measurements faster.


It is important to know that you do not measure the time from trigger start - by setting the Trigger pin HIGH - up to the Echo signal.

The Sensor HC-SR04 starts the measurement by receiving a HIGH on the Trigger input and then sends, a short time later, the time coded as the length of the HIGH level on the Echo pin.

If you use pulseIn() 2 ms, i.e. 2000μs, after triggering, it should work fine.

  • 1
    I'm not sure how much this adds to, or differs from, the accepted answer. Jan 24, 2016 at 19:46

Don't get confused, as the ultrasonic module has a particular way of working. First you set a pulse in the trigpin. When it ends, the module sends 8 bursts of 40 kHz pulses (and thats actually what is used to measure distance, not your pulse in the trigpin, which goes nowhere). At exactly the moment the first burst is sent, the echo pin sets itself in HIGH. When this is happening, the program is in the line of pulseIn, and since echopin is in HIGH it starts timing (because pulseIN(echopin,HIGH) waits for echopin to be HIGH for start timing). When the first pulse of the 40 kHz bounces in the object and gets back to the receiver, the echopin sets itself in LOW. Then the pulseIn function stops the time and returns it. Then the program continues running. This module is a little bit tricky in order to learn the way of working of pulseIn.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.