pulseIn() gives different values if I use delay()

Hello,

I am trying to use a Pololu POL4079 sensor to measure distances.
I use pulseIn() to read the width of the pulse given by the sensor, and transform it into a distance, following the formula given by Pololu.

void setup()
{
  pinMode(sensorPin,INPUT);
  Serial.begin(115200);
}
void loop()
{
          t = pulseIn(sensorPin, HIGH, 1850000);
          d = (t - 1000)*4;
          Serial.println(d);
}

But I found that, when I use delay() between two measurements (in the loop(), after Serial.println), I get very different figures. I tried with delay(1000), delay(100), delay(10)...
I must add that no measure seems to be correct: the distance value doesn't make sense and it fluctuates a lot.

How can a delay() change the value of the pulseIn() ?

Thanks in advance!

The posted code is incomplete.

Please post the code that gives the inconstant values and a sample of the output.

What is the sensor?

Why the ridiculously long pulseIn() timeout?

Does it still happen with millis() timing?

void loop()
{
   static unsigned long timer = 0;
   unsigned long interval = 1000;
   if (millis() - timer >= interval)
   {
      timer = millis();
      t = pulseIn(sensorPin, HIGH, 1850000);
      d = (t - 1000) * 4;
      Serial.println(d);
   }
}

Non-blocking timing tutorials:
Blink without delay().
Blink without delay detailed explanation
Beginner's guide to millis().
Several things at a time.

Thanks for using putting the code in a code block in your first post. Most new members do not bother to read the guidelines. Good job.

How about using the demo-code that is provided by the manufacturer itself?
found here

// Example Arduino program for reading the Pololu Distance Sensor with Pulse Width Output, 300cm Max
 
// Change this to match the Arduino pin connected to the sensor's OUT pin.
const uint8_t sensorPin = 2;
 
void setup()
{
  Serial.begin(115200);
}
 
void loop()
{
  int16_t t = pulseIn(sensorPin, HIGH);
 
  if (t == 0)
  {
    // pulseIn() did not detect the start of a pulse within 1 second.
    Serial.println("timeout");
  }
  else if (t > 1850)
  {
    // No detection.
    Serial.println(-1);
  }
  else
  {
    // Valid pulse width reading. Convert pulse width in microseconds to distance in millimeters.
    int16_t d = (t - 1000) * 4;
 
    // Limit minimum distance to 0.
    if (d < 0) { d = 0; } 
  
    Serial.print(d);
    Serial.println(" mm");
  }
}

best regards Stefan

Thank you for your answers.
The initial code is:

const uint8_t sensorPin = 5;
unsigned long t;
int d;

void setup()
{
  pinMode(sensorPin,INPUT);
  Serial.begin(115200);
}
void loop()
{
          t = pulseIn(sensorPin, HIGH, 1850000);
          d = (t - 1000)*4;
          Serial.println(d);
          //delay(1000);
}

It returns values like:

3440
2412
3432
3424
2476
3052
3412
3332
3396
2264
3404

When I uncomment "delay(1000)" (or put some other delay time), I receive for instance (having not change the sensor position):

1464
1476
1440
1396
1436
1472
1448
1432
1160
1172
1344
1484
1572
1332
1300

Shouldn't I receive the same measure?
My code is based on the one written by Pololu.

Thanks in advance!

I don't understand how the delay() can have an effect on the pulse measurement. Isn't the pulseIn() just measuring the first pulse width it finds when it is called ? How can it impact the next loop iteration? There must be something I'm missing!

Change "D" to an unsigned long and see if the value changes.

Try this loop:

  while (digitalRead(sensorPin) == HIGH) { };
  t = pulseIn(sensorPin, HIGH);
  d = (t - 1000)*4;
  Serial.println(d);
  delay(1000);

Hi geneha4
In the past, I had the same issue.
After various tests, I had solved it by stopping the interrupts before the pulse-in and reactivating them immediately after.

so try this code:

  while (digitalRead(sensorPin) == HIGH) { };
  noInterrupts();
  t = pulseIn(sensorPin, HIGH);
  interrupts();
  d = (t - 1000)*4;
  Serial.println(d);
  delay(1000);

Let me know if it works for you.

Steve

As the signal-train of this distancesensor is very similar to the signal-train of an RC-receiver

RC-receiver frequency 50 Hz puslwidth 1,0 µsec to 2,0 µsec
Distancemeasuring-sensor frequency 30 Hz. Pulsewidth 1,0 µsec to 1m75 µsec

it should work to use a RC-receiver-library

best regards Stefan

I don't see any reason for this, except when one or more ISRs are active. If the sketch doesn't use any ISR, I can't get why pulseIn should be messed by interrupts. If there's something I don't know, I'm open to enhance my knowledge :wink:

Hi docdoc,
You are right, I too.
But in the end, this was the solution.

If you can, try it yourself and let us know."

Do you mean you have interrupts in your sketch or it's a "plain" one?

It's pretty hard to recreate it at the moment, I need an input with a pulse frequency high enough to make any difference.

In my case the input of signal was a channel from a Radiocontrol.

S.

As pulseIn() is a blocking function, in your case I suspect one (or more) of included libraries has active hardware interrupts, making pulseIn() to fail its timings. This means your workaround could be the solution, if you are sure it can't make problems to a loaded library.

That is not what I saw when I looked at the code. It waits for the input to be LOW, then HIGH, then LOW again.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.