Ultrasonic Sensor not working

Hi I am trying to implement obstacle detection for my GoPiGo car and have created a script for it. However, when I run my CarMain() it is giving a ‘get_grove_value error’ reading invalid error. If anyone could please help that would be great.



2 Likes

What version of the GoPiGo do you have?

What operating system are you using?

What port is the sensor plugged into?

What have you already tried to do to fix it?

I’m using GoPiGo3.

The operating system I am using is Raspian (Legacy) and its working fine with my lane detection and other features so far.

The port the sensor is plugged into is the AD2 port in the GoPiGo3 board.

I’ve tried running the basic_ultrasonic script from the dexter examples but it came up with an error for that aswell but stated there was a syntax error in the code. I’ve also tried changing the port in my code and physically changing the sensor to connect to different ports but this didn’t work it still came up with the same error unfortunately. I’ve also tried researching the problem but couldn’t find a solution to it anywhere.

2 Likes

Ahh!  A syntax error?

Just for grins and giggles, try running it from a terminal by typing python2 [program_name]

Actually, make sure your terminal window is in the same directory and type python2 [./program_name]

Tell us what happens.

Which Raspberry Pi are you using?  That’s important.

1 Like

Any chance you can try my python3 grove US prog?

wget https://raw.githubusercontent.com/slowrunner/rosbot-on-gopigo3/main/systests/us/easy_Ultrasonic_Ranger.py

then with the Grove Ultrasonic Ranger plugged into AD2:

python3 easy_Ultrasonic_Ranger.py

you do have the grove version not the HC-SR04 version, right?

YES:

NO!

1 Like

I’ve tried that and it’s coming up with another error can’t find main
I’m using the Raspberry Pi 4 Model B.

1 Like

So first off your Ultrasonic program has the line:

if sensor.is_too_close == True:

You need parens there:

if sensor.is_too_close() == True:

BUT there is an interesting result when I ran a simple test using that function, that resulted in the thing blowing up:

US Sensor reports too close - 494 mm
Traceback (most recent call last):
  File "safe_distance.py", line 22, in <module>
    test()
  File "safe_distance.py", line 11, in test
    if us.is_too_close() == True:
  File "/usr/local/lib/python3.7/dist-packages/gopigo3-1.3.0-py3.7.egg/easysensors.py", line 804, in is_too_close
  File "/usr/local/lib/python3.7/dist-packages/gopigo3-1.3.0-py3.7.egg/gopigo3.py", line 975, in get_grove_value
gopigo3.ValueError: get_grove_value error: Object not detected within range

So I don’t like that function - I suggest replacing those calls with:

  if my_too_close(sensor,127) == True:

with:

def my_too_close(sensor,safe_mm=500):
    try:
        return (sensor.read_mm() < safe_mm)
    except Exception as e:
        print("Exception:", str(e))
        return True

Using this func still saw an invalid value exception but only one and it handled it and continued on:

$ more my_safe_distance.py 
#!/usr/bin/env python3

from easygopigo3 import EasyGoPiGo3
from time import sleep



US_PORT = "AD2"

def my_too_close(sensor, safe_mm=500):
    try:
        return (sensor.read_mm() < safe_mm)
    except Exception as e:
        print("Exception:", str(e))
        return True


def test(sensor):
  if my_too_close(sensor,127) == True:
    print("US Sensor reports too close - {} mm".format(us.read_mm()))

if __name__ == '__main__':
    egpg = EasyGoPiGo3(use_mutex=True)
    us = egpg.init_ultrasonic_sensor(US_PORT)

    while True:
        test(us)

$ python3 my_safe_distance.py 
get_grove_value error: Invalid value
US Sensor reports too close - 120 mm
US Sensor reports too close - 120 mm
US Sensor reports too close - 111 mm
US Sensor reports too close - 105 mm
US Sensor reports too close - 99 mm
US Sensor reports too close - 94 mm
US Sensor reports too close - 88 mm
US Sensor reports too close - 84 mm
US Sensor reports too close - 84 mm
US Sensor reports too close - 96 mm
US Sensor reports too close - 90 mm
US Sensor reports too close - 90 mm

Theoretically you could just put a try/except around the sensor.is_too_close() call and do the same thing.

3 Likes

I’ve just tried that and it’s coming up with ‘invalid value’. I’ll attach an image of my car so you can see my sensor attached. I’m not too sure if it’s the wire that I’m using I bought a sensor wire from Pi hut and have attached that to my GoPiGo3 board but not sure if its compatible with the sensor if that could be an issue. Here is the output on my terminal when I run it on my Raspberry Pi. Also I have attached the sensor to port AD1.


.


1 Like

NO NO NO - bad sensor - that’s an HC-SR04 - doesn’t like to do single wire trigger and read -

You need the Grove Ultrasonic Ranger

1 Like

Oh really? I had no idea I just assumed I would be able to use this because my supervisor gave me it in the keyestudio 37 in 1 sensor kit. I will order that sensor now and then when it has come I will try that code thank you. Is there a particular wire that I need for it? Or will the one I have that is connected to my HC-SR04 sensor be ok?

There is a special cable, but you may have them in the 37 in 1 kit:

1 Like

When you get your Grove US sensor - you can try out this method of using the existing is_to_close() func:

 $ python3 safe_distance.py 
US Default Safe Distance: 500
US Safe Distance Set To: 127
Invalid Reading
get_grove_value error: Invalid value
US Sensor reports too close - 119 mm
US Sensor reports too close - 112 mm
US Sensor reports too close - 104 mm
US Sensor reports too close - 96 mm
US Sensor reports too close - 86 mm
US Sensor reports too close - 88 mm
US Sensor reports too close - 114 mm
US Sensor reports too close - 96 mm
US Sensor reports too close - 107 mm
US Sensor reports too close - 123 mm
^CTraceback (most recent call last):
  File "safe_distance.py", line 28, in <module>
    sleep(0.1)
KeyboardInterrupt
pi@PIOSLGCY:~/GoPiLgc/systests/us $ more safe_distance.py 
#!/usr/bin/env python3

from easygopigo3 import EasyGoPiGo3
from time import sleep



US_PORT = "AD2"

def test():
  try:
      if us.is_too_close() == True:
        print("US Sensor reports too close - {} mm".format(us.read_mm()))
  except Exception as e:
        print("Exception: {}".format(str(e)))

if __name__ == '__main__':
    egpg = EasyGoPiGo3(use_mutex=True)
    us = egpg.init_ultrasonic_sensor(US_PORT)

    print("US Default Safe Distance: {}".format(us.get_safe_distance()))
    us.set_safe_distance(127)  # 5 inches
    print("US Safe Distance Set To: {}".format(us.get_safe_distance()))


    while True:
        test()
        sleep(0.1)

pi@PIOSLGCY:~/GoPiLgc/systests/us $ 

Interestingly it is not throwing an exception most of the time…
There were a bunch of:

Invalid Reading
get_grove_value error: Invalid value
Invalid Reading
get_grove_value error: Invalid value
Invalid Reading
get_grove_value error: Invalid value
Invalid Reading
get_grove_value error: Invalid value
Exception: get_grove_value error: Object not detected within range
Exception: get_grove_value error: Object not detected within range
Exception: get_grove_value error: Object not detected within range
Exception: get_grove_value error: Object not detected within range
Exception: get_grove_value error: Object not detected within range
Exception: get_grove_value error: Object not detected within range
Exception: get_grove_value error: Object not detected within range
Exception: get_grove_value error: Object not detected within range
Exception: get_grove_value error: Object not detected within range
Exception: get_grove_value error: Object not detected within range
Exception: get_grove_value error: Object not detected within range

until I stuck my hand in front of the sensor.

Perhaps this is why Dexter stopped promoting the ultrasonic distance sensor and went instead to using the Infrared Time Of Flight based sensor. It is a lot more expensive, but it has much better max range, faster read rate, and better accuracy. (But might suffer from an occasional I2C glitch…)

2 Likes

Okay I will try that thank you! By the way I’ve tried looking everywhere for that sensor and it’s out of stock on Pi hut and other places. I’ve asked my supervisor if he has any in his office I could borrow so fingers crossed. But I’ll try that code when I have received it thank you!

2 Likes

Have you considered this one?

It’s in stock at the Pi Hut and not terribly expensive - and it works!

The through-hole mounting holes line up with the holes on the Pi Camera module so you can put them together and have a distance sensor with a camera in one assembly.

It even comes with the Googly Eyes, which is a strong selling point in my opinion. (:wink:)

3 Likes

I wish I’d seen this before! I managed to order the grove sensor off of ebay this morning. It does look good though I do like the googly eyes. I might still consider it though!

By the way I was also wondering if there is a specific sensor I would need for traffic light detection, I’m not sure if I will implement this feature or not yet it depends on if I have enough time.

3 Likes

Yes there are some possibilities, BUT is there a reason you are not taking full advantage of that vision sensor?

Looking at your program fragments, it looks as though you are grabbing an image frame and processing it for lane curvature to derive steering commands.

There is a technique of analyzing an image for a blob crossing from above to below a horizontal line in the image that many people use for obstacle detection. That algorithm uses two consecutive images.

Additionally, I am pretty sure there is already a complete OpenCV red/yellow/green stoplight recognizer, either HAAR Cascade or perhaps a CNN recognizer. An even simpler example is here
(A secret- launch the light detection using multi-processing to take advantage of multiple cores of the Pi processor.)

(I also built a “multi-sensor” around the PiCam that included color reco that does not use OpenCV here.)

Don’t know if you would get extra credit for a crash detector, but you could use stall/slip detection of the wheels to detect crashing and call it a “safety equipment concept”.

2 Likes

Hi I’ve tried using the ultrasonic sensor ranger.py code and it is reading values fine with my grove sensor. I’m trying to implement in my carMain() so that when an obstacle is too close to the car the car will stop. I have tried using the functions you have shown me and it’s still driving into things at the moment. I’ve tried calling Movement.stop as well but that doesn’t seem to work with it.






1 Like

I have to start by telling you your code is a bit of a mess

  • two EasyGoPiGo3() objects instantiated, (why do you need two?)
  • Is there another EasyGoPiGo3() object you expected was instantiated in Movement.py? Super not good idea!
  • two EasyGoPiGo3() objects instantiated, one with use_mutex=True, one without
  • a car_main() that is not really a main (“main()” means everything happens inside of main(). Everything)
    You have an EasyGoPiGo3 object and an ultrasonic sensor as “wild code”
  • virtual main() - not a good idea, especially for a complex program
  • sequential “while True:” in the virtual main() at the end of the CarMain.py module
  • the old safe_sensor_distance line? not used now correct?

As to the error: let’s think about this for a minute.

Invoking CarMain.py creates an EasyGoPiGo3 and the ultrasonic sensor
(You don’t have any print statements to log successful setup - guessing success)
Execution continues in the “virtual main” calling car_main()
Which gets a frame from the camera
Analyses the frame for lane curvature
Then commands some magical Movement.direction()

  • You didn’t show Movement.py, but you didn’t pass the GPG robot object to it so how can it drive it?

Which is probably where it is crashing, but the “Shell” capture does not show where in your code it crashed.

1 Like

I have 2 EasyGoPiGo() objects because I thought I needed 2: 1 for the motors and another for the sensor. Here is my Movement.py code. In this I have a gpg object which is for the left and right motors of the car. I have used ‘GPG’ as another object for the ultrasonic sensor. Do I need to pass the same object as the ultrasonic sensor to the Movement.py? I will try and put the code under the car_main(). No the safe_sensor_distance isn’t used I just commented the old code out in car_main() to test the methods you’ve shown me to see if it would work. I will try and add print statements as well to test if it’s working.


2 Likes

I’ve also tried the example obstacle avoidance program but it’s coming up with errors for this as well when I try running it.