Is pulseIn() still buggy?

I am attempting to do object detection using an ultrasonic sensor. I am running stepper motors, so I am using *pingDelay to adjust the delay times between phase steps in order to run them at a constant rate.

When I run the code below, things work perfectly when the object in question has a ping delay less than my timeout of 1000uSec. However, once the object moves beyond that the motors slow to a crawl. I removed the timout parameter and found that it behaved exactly the same, except the return value was the ping delay for the far wall of the room instead of zero. So bascially, the only difference with the timout parameter is returns a zero, while still waiting for the ping to return. Unless I am missing something obvious the timeout for pingIn isn't working properly.

This is the code I am using with it, in case I really did miss something obvious.

boolean getObj(int *pingDelay) {
    digitalWrite(Trig, LOW);
    delayMicroseconds(3);
    digitalWrite(Trig, HIGH);
    delayMicroseconds(10);
    digitalWrite(Trig, LOW);
    int duration = pulseIn(Echo, HIGH, 1000);
    if (duration == 0){
      *pingDelay = 1000;
      return false;
    }
    else if (duration < 500){
      *pingDelay = duration;
      return true;
    }
    else {
      *pingDelay = duration;
      return false;
    }     
}

Any ideas?

You don't show the part of the code where the results of that function are used. I suspect an error in that code. Perhaps you should post a working sketch that demonstrates the problem.

That is a good point. In the test code I wrote motor1.go() moves the motor through a half step. The way I have it set up, it should run at a constant rate until getObj() returns false, and then it will pause for two seconds. The driver board I am using has an led for each phase, and the flashing is quite apparent, so it should be possible to replicate with just an led (assuming the ultrasonic sensor has enough delay on the input), or perhaps even with Serial output and timer.

delayMicroseconds(1000 - pingDelay);
motor1.go();
if (getObj(&pingDelay)) {delay(2000);}

I don't understand what your Title has to do with your problem?
What bug are you referring to in pulseIn() ?

Imagining there is a problem in the Arduino code can easily distract one from the errors in one's own code.

Where does pingDelay get its value?

...R

Imagining there is a problem in the Arduino code can easily distract one from the errors in one's own code.

So true. I think the search results I found when trying to grasp why the timeout wasn't working as expected spooked me.

I have actually fixed the problem, and it is unrelated to the timeout, which you all were likely suspicious of already. :wink: It seems that passing a zero value to delayMicroseconds() is the fault. Instead of effectively ignoring the command as I assumed, it seems to overflow and create a very long delay.

Here is a working sketch that demonstrates the behavior I mentioned before, but using the pin 13 led instead of a motor.

#define Trig 3
#define Echo 2
#define LED 13

boolean getObj(int *pingDelay) {
    digitalWrite(Trig, LOW);
    delayMicroseconds(3);
    digitalWrite(Trig, HIGH);
    delayMicroseconds(10);
    digitalWrite(Trig, LOW);
    int duration = pulseIn(Echo, HIGH, 1000);
    if (duration == 0){
      *pingDelay = 1000;//-----------Make this 999 to fix
      return false;
    }
    else if (duration < 500){
      *pingDelay = duration;
      return true;
    }
    else {
      *pingDelay = duration;
      return false;
    }     
}

int pingDelay = 0; 
unsigned int counter = 0;


void setup() {
  pinMode(Trig, OUTPUT);
  pinMode(Echo, INPUT);
  pinMode(LED, OUTPUT);
}

void loop() {
    delayMicroseconds(1000 - pingDelay);//------This is where it breaks
    //The sole purpose of counter is to slow down the flashing
    //so timing changes are more aparent.
    counter++;
    if (counter % 15 == 0){
     if(digitalRead(LED) == LOW){digitalWrite(LED, HIGH);}
     else {digitalWrite(LED, LOW);}
    }
    if (getObj(&pingDelay)) {delay(2000);}

}

The intended behavior of this is the led should flash at a constant rate (rapid) until and object is within a few cm of the ultrasonic sensor (<500uSec ping delay time), and then it should pause for two seconds either on or off.

In the observed behavior, the led pauses with ping delay time < 500uSec (as intended), runs at a constant rapid rate with 500uSec <= ping delay time < 1000uSec (as intended), and then runs at something like a couple orders of magniude slower at ping delay time > 1000 (unintended).