HC-SR04 Anomoly

I have plagiarized code to run the HC-SR04 Acoustic Distance Sensor. The code runs just fine in a stand alone test program, but the same code is returning huge numbers for the Duration and Distance calculations. I am trying to determine what would cause the code to fail so consistently:
NOTE: I am running this on a Mega board; hence the high pin numbers.

#define DETECTOR_TRIGGER_PIN	   21
#define DETECTOR_ECHO_PIN	   20
#define DETECTOR_PULSEIN_TIMEOUT   100	// Microseconds to wait before timing out

long duration, distance;

bool measureDistance () {
		distance = duration = 0;
	digitalWrite ( DETECTOR_TRIGGER_PIN, LOW );
	delayMicroseconds ( 2 );
	digitalWrite ( DETECTOR_TRIGGER_PIN, HIGH );
	delayMicroseconds ( 10 );
	digitalWrite ( DETECTOR_TRIGGER_PIN, LOW );
	duration = pulseIn ( DETECTOR_ECHO_PIN, HIGH, DETECTOR_PULSEIN_TIMEOUT );
		distance = (long) (float) ( ( duration / 2 ) / 29.1 );


		Serial.print ( F ( "Duration:" ) );
	Serial.print ( duration );
	if (distance <= 0) {
		Serial.print ( ", Unable to measure distance" );
	} else {
		Serial.print ( F ( ", Distance:" ) );
		Serial.print ( distance );
	}
	Serial.println ();
		delay ( 100 );
	return ( distance > 0 );
}


long getDistance () {
	return distance;
}


long getDuration () {
	return duration;
}

Here is what comes back:
Duration:15256781, Distance:729344
Duration:15256781, Distance:729344
Duration:15256781, Distance:729344
Duration:15256781, Distance:729344
Duration:15256781, Distance:729344
Duration:15256781, Distance:729344
Duration:15256781, Distance:729344
Duration:15256781, Distance:729344
Duration:15256781, Distance:729344
Duration:15256781, Distance:729344

Please post the full sketch that produces the bad numbers.

Why do you need functions that do nothing but return global variables?

The code you provided looks like it should work even though you are using 'long' where you should be using 'unsigned long'. There is almost certainly a bug in the rest of the code that is causing your problem.

To Pert: My code consists of over 40 classes, so it is not practical to post all of it. The problem occurs and is displayed with a single method:

	//	Simple distance check - calculates distance in CM
	unsigned long duration, distance;


	bool measureDistance () {
		distance = duration = 0;
		digitalWrite ( DETECTOR_TRIGGER_PIN, LOW );
		delayMicroseconds ( DETECTOR_LOW_MICROS );
		digitalWrite ( DETECTOR_TRIGGER_PIN, HIGH );
		delayMicroseconds ( DETECTOR_HIGH_MICROS );
		digitalWrite ( DETECTOR_TRIGGER_PIN, LOW );
//		duration = pulseIn ( DETECTOR_ECHO_PIN, HIGH, DETECTOR_PULSEIN_TIMEOUT );
		duration = pulseIn ( DETECTOR_ECHO_PIN, HIGH );
		distance = (unsigned long) (float) ( duration / 2.0 / 29.1);
		delay ( 100 );

		Serial.print ( F ( "Duration:" ) );
		Serial.print ( duration );
		Serial.print ( F ( ", Distance:" ) );
		Serial.print ( distance );

		return ( distance > 0 );
	}

The problem occurs and is displayed with a single method:

Would that be the problem that caused you to say

The code runs just fine in a stand alone test program

?

If so, then, clearly the problem is with the code you don't feel willing to share.

rhj4:
To Pert: My code consists of over 40 classes, so it is not practical to post all of it.

That's fine. Then simply provide a MCVE that demonstrates the problem.

Even if you were doing something flakey with Timer0 so that pulseIn() accidentally returned a pulse length of 15.256781 seconds, the distance should be 262144 cm (2.621 km), not 729344 cm (7.293 km). This means that not only is your duration being clobbered, the calculated distance doesn't match the clobbered duration!

I have produced a MCVE that has pinned the problem to hardware. The code works fine in two different hardware configurations but not the third. So that's where I will focus my efforts.

rhj4:
I have produced a MCVE that has pinned the problem to hardware. The code works fine in two different hardware configurations but not the third. So that's where I will focus my efforts.

Excellent. Thanks for letting us know.

Does the hardware problem indicate a pin conflict?

I found that when writing MCVE for the purpose of requesting support or submitting a bug report, it often showed me what the exact problem was. That made me realize what a valuable troubleshooting technique this can be. I now do it regularly when I'm having problems, simply for my own benefit.

I agree that creating an MCVE (A new FLA for me) is very useful. I actually take it one step further and produce a full diagnostic tool. Right now I have such tools to test H-Bridges (L298N and L9110), WiFi and Bluetooth communications and a bunch of others. My intention is to put them all on GitHub and give them away, but that may take awhile.

I've found the SR04 sensors to be very fussy about other hardware. If for instance I hook up an IR sensor to the analog line, it causes a large increase in errors with the SR04. Same code, unplug the IR sensor, and the erratic readings go away. Very annoying. Just like running ping library causes servo jitter. All sorts of wonderful bugs in Arduino.