Community
cancel
Showing results for 
Search instead for 
Did you mean: 
BWill15
New Contributor II
1,031 Views

How to use hcsr04 with mraa and upm in python

I want to use the hc-sr04 with mraa and upm in python. There are no ultrasonic https://github.com/intel-iot-devkit/upm/tree/master/examples/python python examples provided on Github.

I found this source code for ultrasonic sensors in the upm Github repository: https://github.com/intel-iot-devkit/upm/tree/5a5637a4319e0cfdf50e6efac09eb106bd80131d/src/groveultra... groveultrasonic and https://github.com/intel-iot-devkit/upm/tree/5a5637a4319e0cfdf50e6efac09eb106bd80131d/src/hcsr04 hcsr04.

Can someone provide some example code for the Intel Galileo Gen 2?

Edit: maybe this helps:

http://iotdk.intel.com/docs/master/upm/python/pyupm_hcsr04.html pyupm_hcsr04 module — upm v0.5.1-4-g1aa445b documentation

http://iotdk.intel.com/docs/master/upm/python/pyupm_groveultrasonic.html?highlight=ultrasonic# module-pyupm_groveultrasonic pyupm_groveultrasonic module — upm v0.5.1-4-g1aa445b documentation

https://software.intel.com/en-us/iot/hardware/sensors/hcsr04-ultrasonic-sensor IoT - HC-SR04 Ultrasonic Sensor | Intel® Developer Zone

Tags (3)
11 Replies
idata
Community Manager
94 Views

Hi,

 

 

I found no sample codes of the hc-sr04 sensor for Python. Take a look at this thread /message/340756# 340756 https://communities.intel.com/message/340756# 340756 . Another user has already asked how to use this sensor with Python. Take a look at the suggestion and threads posted.

 

 

Let us know your results.

 

 

Sergio

 

BWill15
New Contributor II
94 Views

I didn't have good luck with the links you mentioned.

I found this code and modified it slightly:

# http://stackoverflow.com/questions/32300000/galileo-and-ultrasonic-error-when-distance-less-than-4cm http://stackoverflow.com/questions/32300000/galileo-and-ultrasonic-error-when-distance-less-than-4cm

import mraa

import time

trig = mraa.Gpio(0)

echo = mraa.Gpio(1)

trig.dir(mraa.DIR_OUT)

echo.dir(mraa.DIR_IN)

def distance(measure='cm'):

trig.write(0)

time.sleep(0.002)

trig.write(1)

time.sleep(0.00001)

trig.write(0)

sig = None

nosig = None

et = None

while echo.read() == 0:

nosig = time.time()

while echo.read() == 1:

sig = time.time()

if sig == None or nosig == None:

return 0

# et = Elapsed Time

et = sig - nosig

if measure == 'cm':

distance = et * 17150

elif measure == 'in':

distance = et / 0.000148

else:

print('improper choice of measurement!!')

distance = None

return distance

while True:

t1 = time.time()

print(distance('cm'))

print time.time() - t1

Is it possible to do it with an interrupt? Now I i'm doing nothing until the echo is received.

BWill15
New Contributor II
94 Views

I tried this. The code works, but the destance isn't right.

# http://stackoverflow.com/questions/32300000/galileo-and-ultrasonic-error-when-distance-less-than-4cm http://stackoverflow.com/questions/32300000/galileo-and-ultrasonic-error-when-distance-less-than-4cm

import mraa

import time

import sys

class ElapsedTime:

begintime = 0.0

endtime = 0.0

elatime = 0.0

echoPin = 3

echo = mraa.Gpio(echoPin)

echo.dir(mraa.DIR_IN)

trig = mraa.Gpio(2)

trig.dir(mraa.DIR_OUT)

et = ElapsedTime()

# inside a python interrupt you cannot use 'basic' types so you'll need to use

# objects

def mraaISR(gpio):

et.endtime = time.time()

et.elatime = et.endtime - et.begintime

print("Interrupt detected")

# print et.endtime - et.begintime

def distance(measure='cm'):

global et

try:

print("Starting ISR for pin " + repr(echoPin))

echo.dir(mraa.DIR_IN)

# https://github.com/intel-iot-devkit/mraa/blob/master/examples/python/hello_isr.py https://github.com/intel-iot-devkit/mraa/blob/master/examples/python/hello_isr.py

echo.isr(mraa.EDGE_RISING, mraaISR, echo)

et.begintime = time.time()

trig.write(0)

time.sleep(0.002)

trig.write(1)

time.sleep(0.00001)

trig.write(0)

time.sleep(2)

echo.isrExit()

except ValueError as e:

print(e)

if measure == 'cm':

distance = et.elatime * 17150

elif measure == 'in':

distance = et.elatime / 0.000148

else:

print('Improper choice of measurement!!')

distance = None

return distance

while True:

print(distance('cm'))

time.sleep(0.5)

idata
Community Manager
94 Views

You mean to say that the distance values are incorrect even though the code compiles? I noticed in your last thread you modified the last while statement. Make sure this doesn't change the expected results. Do you receive incorrect values with both "cm" and "in"?

 

 

According to the datasheet the formulas are uS / 58 = centimeters or uS / 148 =inch or the range = high level time * velocity (340M/S) / 2. Also the module cannot measure distances lower to 2cm. Make sure these formulas are correct and that you have the latest mraa version available.

 

 

Sergio

 

BWill15
New Contributor II
94 Views

I only use the metric system. The inches are a result of http://stackoverflow.com/questions/32300000/galileo-and-ultrasonic-error-when-distance-less-than-4cm the code I based my code on.

The change in the wile statement didn't affect the results. It now measures only every half a second instead of as fast as possible.

I tested the code without the interrupt and it is accurate. I checked it with a ruler of 30 cm. I think these conversion could also be used in the interrupt method. Only the way of measuring the time between the trigger and the echo is diferent. The conversion remains the same.

us/58

= s/0.000058

= s* (1/0.000058)

= s * (17241)

+/-=s * 17150

I think the conversion isn't the problem.

This is my working code without an interrupt.

import mraa

import time

trig = mraa.Gpio(2)

echo = mraa.Gpio(3)

trig.dir(mraa.DIR_OUT)

echo.dir(mraa.DIR_IN)

def distanceUS():

tZero = time.time()

# reading sensor in Python takes about 6 ms (US = Utrasonic Sensor)

# http://stackoverflow.com/questions/32300000/galileo-and-ultrasonic-error-when-distance-less-than-4cm http://stackoverflow.com/questions/32300000/galileo-and-ultrasonic-error-when-distance-less-than-4cm

# http://playground.arduino.cc/Main/UltrasonicSensor http://playground.arduino.cc/Main/UltrasonicSensor

trig.write(0)

time.sleep(0.000004) # in Arduino 2 microseconds, double this value to be sure

trig.write(1)

time.sleep(0.00001) # in Arduino 5 microseconds, double this value to be sure

trig.write(0)

sig = None

nosig = None

etUS = None

while echo.read() == 0:

nosig = time.time()

while echo.read() == 1:

sig = time.time()

if sig == None or nosig == None:

return 0

# et = Elapsed Time

etUS = sig - nosig

distance = etUS * 17150

return distance

while True:

t1 = time.time()

print(distanceUS())

print time.time() - t1

PS: the "US" stands for Utrasonic Sensor

idata
Community Manager
94 Views

This issue might be related to the speed of the pins of the sensor. Can you connect a logic analyzer to compare the pulse of the data sent by the sensor to the values set in the code?

 

 

If the code is correct, then the issue is likely the reading of the signal. You can connect a logic analyzer or an oscilloscope to compare these values.

 

 

Sergio

 

idata
Community Manager
94 Views

Were you able to resolve this issue and use the hc-sr04?

 

 

Sergio

 

BWill15
New Contributor II
94 Views

I didn't try it yet. For now I'm using the polling method instead of the interrupt based method.

idata
Community Manager
94 Views

Let us know your results.

 

 

Sergio

 

BWill15
New Contributor II
94 Views

This method uses polling with a time-out:

Change the @timeout(0.020) based on your application. Maximal recommended value is 0.035.

@timeout(0.020)

timeout.py

from functools import wraps

import errno

import os

import signal

# http://stackoverflow.com/questions/11901328/how-to-timeout-function-in-python-timeout-less-than-a-se... http://stackoverflow.com/questions/11901328/how-to-timeout-function-in-python-timeout-less-than-a-se...

class TimeoutError(Exception):

pass

def timeout(seconds=10, error_message=os.strerror(errno.ETIME)):

def decorator(func):

def _handle_timeout(signum, frame):

raise TimeoutError(error_message)

def wrapper(*args, **kwargs):

signal.signal(signal.SIGALRM, _handle_timeout)

signal.setitimer(signal.ITIMER_REAL,seconds) # used timer instead of alarm

try:

result = func(*args, **kwargs)

finally:

signal.alarm(0)

return result

return wraps(func)(wrapper)

return decorator

hcsr04.py

import mraa

import time

from timeout import timeout

trig = mraa.Gpio(3)

echo = mraa.Gpio(4)

trig.dir(mraa.DIR_OUT)

echo.dir(mraa.DIR_IN)

# http://stackoverflow.com/questions/11901328/how-to-timeout-function-in-python-timeout-less-than-a-se... http://stackoverflow.com/questions/11901328/how-to-timeout-function-in-python-timeout-less-than-a-se...

@timeout(0.020)

def distanceUS():

tZero = time.time()

# reading sensor in Python takes about 6 ms (US = Utrasonic Sensor)

# http://stackoverflow.com/questions/32300000/galileo-and-ultrasonic-error-when-distance-less-than-4cm http://stackoverflow.com/questions/32300000/galileo-and-ultrasonic-error-when-distance-less-than-4cm

# http://playground.arduino.cc/Main/UltrasonicSensor http://playground.arduino.cc/Main/UltrasonicSensor

trig.write(0)

time.sleep(0.000004) # in Arduino 2 microseconds, double this value to be sure

trig.write(1)

time.sleep(0.00001) # in Arduino 5 microseconds, double this value to be sure

trig.write(0)

sig = None

nosig = None

etUS = None

while echo.read() == 0:

nosig = time.time()

while echo.read() == 1:

sig = time.time()

if sig == None or nosig == None:

return 0

# et = Elapsed Time

etUS = sig - nosig

distance = etUS * 17150

return distance

while True:

try:

print distanceUS()

except Exception, e:

# print 'time out!'

continue

Reply