11 Replies Latest reply on Apr 29, 2016 2:33 AM by BrechtW

    How to use hcsr04 with mraa and upm in python

    BrechtW

      I want to use the hc-sr04 with mraa and upm in python. There are no ultrasonic python examples provided on Github.

       

      I found this source code for ultrasonic sensors in the upm Github repository: groveultrasonic and hcsr04.

       

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

       

      Edit: maybe this helps:

      pyupm_hcsr04 module — upm v0.5.1-4-g1aa445b documentation

      pyupm_groveultrasonic module — upm v0.5.1-4-g1aa445b documentation

      IoT - HC-SR04 Ultrasonic Sensor | Intel® Developer Zone

        • 1. Re: How to use hcsr04 with mraa and upm in python
          Intel Corporation
          This message was posted on behalf of Intel Corporation

          Hi,

          I found no sample codes of the hc-sr04 sensor for Python. Take a look at this thread 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
           

          • 2. Re: How to use hcsr04 with mraa and upm in python
            BrechtW

            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
            
            
            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.

            • 3. Re: How to use hcsr04 with mraa and upm in python
              Intel Corporation
              This message was posted on behalf of Intel Corporation

              It is possible to handle interrupts with mraa using Python. Take a look at this example https://github.com/intel-iot-devkit/mraa/blob/master/examples/python/hello_isr.py .
              You can also look at section 4.2 of https://software.intel.com/en-us/articles/internet-of-things-using-mraa-to-abstract-platform-io-capabilities

              Sergio
               

              1 of 1 people found this helpful
              • 4. Re: How to use hcsr04 with mraa and upm in python
                BrechtW

                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
                
                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
                        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)
                
                
                • 5. Re: How to use hcsr04 with mraa and upm in python
                  Intel Corporation
                  This message was posted on behalf of Intel Corporation

                  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
                   

                  • 6. Re: How to use hcsr04 with mraa and upm in python
                    BrechtW

                    I only use the metric system. The inches are a result of 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://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

                    1 of 1 people found this helpful
                    • 7. Re: How to use hcsr04 with mraa and upm in python
                      Intel Corporation
                      This message was posted on behalf of Intel Corporation

                      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
                       

                      • 8. Re: How to use hcsr04 with mraa and upm in python
                        Intel Corporation
                        This message was posted on behalf of Intel Corporation

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

                        Sergio
                         

                        • 9. Re: How to use hcsr04 with mraa and upm in python
                          BrechtW

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

                          • 10. Re: How to use hcsr04 with mraa and upm in python
                            Intel Corporation
                            This message was posted on behalf of Intel Corporation

                            Let us know your results.

                            Sergio
                             

                            • 11. Re: How to use hcsr04 with mraa and upm in python
                              BrechtW

                              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-second
                              
                              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-second
                              
                              @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://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
                              
                              
                              
                              
                              
                              
                              
                              1 of 1 people found this helpful