PICAR-X Ultrasonic Sensor - Slow and erratic readings at 3.3v

Recent purchase of Picar-X, good kit.
I’m just running through the various tests and the ultrasonic module is erratic.
The module is a HC-SR04 and specs imply a 5v supply, the module as per the instructions is wired to 3.3v. When running example 4, I seem to get a good reading but will quite often report an odd value then report -2 for a while, whilst reading low values reponse is slow about 500ms.

Could the board be faulty? Have I been shipped a 5v version rather than a 3.3v version.

Using PI 5 8gb and Robot-HAT is v4 but with speaker in top (v4.5?)
Update your docs say 5v: Ultrasonic Module — SunFounder PiCar-X Kit documentation

If it helps? the values -1 and -2 are error status values

while self.echo.gpio.value == 0:
pulse_start = time.time()
if pulse_start - timeout_start > self.timeout:
return -1
while self.echo.gpio.value == 1:
pulse_end = time.time()
if pulse_end - timeout_start > self.timeout:
return -1
if pulse_start == 0 or pulse_end == 0:
return -2

1 Like

Found that code, make me wonder under what circumstances either would return 0.
They way it currently works makes it impossible to use the car with ultrasound as it keeps jumping into reverse.

It never returns a zero.

It sits in a loop whilst the echo is inactive. Returning -1 if a timeout.

Then it sits in a timer loop whilst the echo is active, measuring the pulsewidth, returning -2 if timeout is exceeded.

If neither timeout i.e no errors then it continues to run and returns the distance in centimeters as a positive value.

Minimum module distance is specified as 2cm, so all positive values are distances and negative ones are errors.

Hope that helps.

It does, is this expected behaviour from the SR04, it makes the example code pointless and it often incorrectly detects objects (returns -2) and this makes the car fly around in reverse.

I did notice that the obstacles avoidance example was written 2 years ago and the -2 error was added, one year ago, so maybe the example needs updating. I don’t own a picar so cant verify and so I’m not 100% certain which libraries the picar pulls in.

Probably better to await Sunfounder answer, not my ramblings :wink:

1 Like

After some investigation I found a bug in their code

   if pulse_start == 0 or pulse_end == 0:
        return -2

    during = pulse_end - pulse_start
    cm = round(during * self.SOUND_SPEED / 2 * 100, 2)
    return cm

def read(self, times=10):
    for i in range(times):
        a = self._read()
        if a != -1:
            return a
    return -1

Notice that the test if a !=-1: does not cope with -2 so would return on the 1st instance of such an event. No 10 tries there.

Changing it to:
def read(self, times=10):
for i in range(times):
…a = self._read()
…if a > 0:
…return a
return a

Improves the reliability of the output no end. -ve values still need to be coped with else where and a moving average would further improve reliability, but at this point its better.

Nice find! Possibly report formally on their github page?

Done so. Not used github before.