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

True, but the logic is not with the ping echo, it's with the conversion to inches and cm. And this is where it can be zero as the sensor can read something closer than an inch, which yields a zero. Technically, it should never happen with cm. But, I'd rather go the safe route.

thats why you should include rounding in the conversion functions (or do mililmeters, or 1/16th)

I had a closer look at the conversion functions and you should revisit them:

Speed of sound is 340.29 m/sec => US_ROUNDTRIP_CM = 58.77

that means that US_ROUNDTRIP_CM should be rounded to 59 iso 58 and US_ROUNDTRIP_IN 149 iso 148?

These rounding errors add up !!

Small experiment with different conversion functions

void setup()
{
  Serial.begin(9600);
}

unsigned int x;

void loop()
{
  for (int i=0; i<=30000; i+=1000)
  {
    Serial.print(i);
    Serial.print(",\t");
    
    x = convert_cm0(i);
    Serial.print(x);
    Serial.print(",\t");
    
    x = convert_cm1(i);
    Serial.print(x);
    Serial.print(",\t");
    
    x = convert_mm(i);
    Serial.print(x);
    Serial.print(",\t");

    x = convert_cm2(i);
    Serial.print(x);
    Serial.println();
  }
  while(1);
}

// reference
unsigned int convert_cm2(unsigned int echoTime)
{
  unsigned long us_roundtrip_100meter = 587734; 
  unsigned long distance = (echoTime*1e4 + us_roundtrip_100meter/2)/ us_roundtrip_100meter;
  return (unsigned int) distance ;
}

// original with rounding
unsigned int convert_cm0(unsigned int echoTime)
{
  return (echoTime+29)/ 58;   // added rounding
}

// using 59 ?
unsigned int convert_cm1(unsigned int echoTime)
{
  return (echoTime + 29)/ 59;   // added rounding
}

// use millimeters 
unsigned int convert_mm(unsigned int echoTime)
{
  return (echoTime*10L + 294)/ 588;   // added rounding
}

Output

0,	0,	0,	0,	0
1000,	17,	17,	17,	17
2000,	34,	34,	34,	34
3000,	52,	51,	51,	51
4000,	69,	68,	68,	68
5000,	86,	85,	85,	85
6000,	103,	102,	102,	102
7000,	121,	119,	119,	119
8000,	138,	136,	136,	136
9000,	155,	153,	153,	153
10000,	172,	169,	170,	170
11000,	190,	186,	187,	187
12000,	207,	203,	204,	204
13000,	224,	220,	221,	221
14000,	241,	237,	238,	238
15000,	259,	254,	255,	255
16000,	276,	271,	272,	272
17000,	293,	288,	289,	289
18000,	310,	305,	306,	306
19000,	328,	322,	323,	323
20000,	345,	339,	340,	340
21000,	362,	356,	357,	357
22000,	379,	373,	374,	374
23000,	397,	390,	391,	391
24000,	414,	407,	408,	408
25000,	431,	424,	425,	425
26000,	448,	441,	442,	442
27000,	466,	458,	459,	459
28000,	483,	475,	476,	476
29000,	500,	492,	493,	493
30000,	517,	508,	510,	510

The 58 code gives 7 cm too much at 510 cm (~1.4 % error)
The 59 code gives 2 cm too little at 510 cm (~0.5% error)
The mm code gives no error at 510 cm (<= 0.2%)

The "mm" code needs long math where the "59"code only needs int math,

conclusion =>
use 59 iso 58 as it has a lower a systematic error (factor 3) with the same codesize & speed.

Same exercise to be done for inches too :slight_smile: