NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.7

robtillaart:

	// Ping started, wait for the ping echo to return.
while (*_echoInput & _echoBit)
	if (maxLoops2-- == 0) return NOECHO;

// Calculate ping time, 16 = clock cycles of routine overhead.
return clockCyclesToMicroseconds(numloops * CLOCK_CYCLES + 16);


Comparing against 0 is faster and makes code a few bytes smaller

This is with the loop counting ping method, which I don't suggest using, and is mostly pulseIn with slight changes to work correctly with ultrasonic sensors.

Also, your code doesn't quite work, as it must count the loops to figure out the distance in the final loop. Also, numloops is not defined. I tried to implement the corrected version of your code suggestion, but it was actually 2 bytes longer, so one would expect a little slower as well.

I was, however, able to optimize the loop counting ping method to save around 44 bytes. See below:

// Alternate timer, uses loop counting to time the ping echo.
unsigned int NewPing::ping() {
	unsigned long numloops = 0;
	unsigned long cpu_speed = microsecondsToClockCycles(10);
	unsigned long maxLoops = (_maxEchoTime + MAX_SENSOR_DELAY) * cpu_speed / CLOCK_CYCLES / 10;
	unsigned long maxLoops2 = _maxEchoTime * cpu_speed / CLOCK_CYCLES / 10;
	*_triggerOutput &= ~_triggerBit;
	delayMicroseconds(2);
	*_triggerOutput |= _triggerBit;
	delayMicroseconds(10);
	*_triggerOutput &= ~_triggerBit;
	while (*_echoInput & _echoBit)
		if (numloops++ == maxLoops) return NO_ECHO;
	while (!(*_echoInput & _echoBit))
		if (numloops++ == maxLoops) return NO_ECHO;
	numloops = 1;
	while (*_echoInput & _echoBit)
		if (numloops++ == maxLoops2) return NO_ECHO;
	return clockCyclesToMicroseconds(numloops * CLOCK_CYCLES);
}

robtillaart:
Still don't like this one...

#define NewPingConvert(echoTime, conversionFactor) (max(echoTime / conversionFactor, (echoTime ? 1 : 0)))

can be improved by (1) adding rounding and (2) working in millimeters as proposed before.

The granularity of measurement = 4 micros(), in 4 micros sound travels approx 1.35 millimeter, or about 1/7 of a centimeter. that's almost 3 bits of precision, assuming the last 2 are noise your lib should be able to measure 0.5cm == 5mm steps (1/10th inch) without problems.

If you'd like to suggest an alternative, please provide specific code as I can't read your mind and won't try to guess either.

Also, keep in mind that mm conversion is worthless as the sensor is not accurate enough to measure down to the mm (only accurate to 6-7mm). Further, doing the math down to the mm level would not be more accurate because temperature is not being considered and the effect of temperature can be a few cm. In other words, a more complex formula will not yield more accurate results, simply take more program space with no benefit.

Not sure why you're not happy with just changing US_ROUNDTRIP_CM to a fraction or get the microsecond result from ping() and use your own magic conversion code. Am I missing something? Using the sensors in the real world I can't get 1/10th inch results, how exactly are you doing this? Or, is it just a theory you have?

Tim