It’s fun to switch to floats for the computations, I tried it, but it didn’t increase accuracy too much. Consider how C++ evaluates expressions. As I understand it, C++ groups equivalent operators associatively from right to left: For example, the expression a / b / c is parsed as a/ (b / c), and not as (a / b) / c.
So, the calculation “inches = duration / 74 / 2” becomes “inches = duration / 37”. Then, “duration / 37” rounds the result down to the nearest integer, the remainder is discarded. So you lose at most an inch accuracy.
The inexpensive 2-transducer sensors don’t seem to be that accurate, and will give fairly erratic readings if they are on a moving platform. (No problem, there are $50 ultrasonic sensors you can buy.) What I did was take a weighted exponential moving average of the sensor output:
int range, rangeavg, duration;
....
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
delayMicroseconds(50);
digitalWrite(pin, HIGH);
delayMicroseconds(5);
digitalWrite(pin,LOW);
pinMode(pin,INPUT);
duration = pulseIn(pin,HIGH);
delay(60); // it's important to wait at least 50 msec between pings
range = duration/74/2;
if (range > 0) { // sometimes the sensor returns 0, discard reading
rangeavg = (rangeavg + range + range + range) / 4;
}
This weights the most recent reading by 3X, you could use 2X or 10X or whatever works best for your project. This filters out the effect of glitches in the ping, since the ping doesn’t always return the distance to the “desired target”. I have a floor-wandering robot that uses these sensors to decide whether to turn L, R, or go straight; the smoothed values make the robot go on a smoother path.