1 2 Previous Next 17 Replies Latest reply on Nov 26, 2014 3:29 PM by toadaze

    Python HC-SR04 Sonar Setup

    toadaze

      Since I couldn't figure out how to use the HCSR04 Class Reference (pyupm_hcsr04.py) in the libmraa library, I came up with the following program to access the gpio pins directly with mraa. It prints/displays the distance in centimeters. It seems to report fairly accurate distances from 0 out to 7-8 centimeters. But anything farther seems to report about the same as 7-8 centimeters. I know this sensor has worked out to at least 80cm on other devices. I imagine my timing is off.

       

      #hcsr04.py

       

      import pyupm_i2clcd as lcd

      import mraa

      import time

      import sys

       

      # display - lcd

      lcdDisplay = lcd.Jhd1313m1(0, 0x3E, 0x62)

       

      # digital output - trig

      trigPin = mraa.Gpio(5)

      trigPin.dir(mraa.DIR_OUT)

      trigPin.write(0)

       

      # digital input - echo

      echoPin = mraa.Gpio(6)

      echoPin.dir(mraa.DIR_IN)

       

      time.sleep(0.3)

       

      trigPin.write(1)

      time.sleep(0.00001)

      trigPin.write(0)

       

      while echoPin.read() == 0:   

       

          pulseOff = time.time()

         

      while echoPin.read() == 1:

       

          pulseOn = time.time()

         

      timeDifference = pulseOn - pulseOff

      centimeters = timeDifference * 17000

      print centimeters

      centimetersStr = str(centimeters)

      lcdDisplay.setCursor(0, 0)

      lcdDisplay.write(centimetersStr)

       

      In any case, getting back to my original problem, has anyone tried 'pyupm_hcsr04.py'?  It's located on the Edison in '/usr/lib/python2.7/site-packages' along with a lot of classes for other sensors.  I can see it wants 3 arguments; trig pin, echo pin and an interrupt function. It's the interrupt function I can't figure out.  I would like to get it working and compare its results with my program above.

        • 1. Re: Python HC-SR04 Sonar Setup
          deium

          toadaze

          I was shown this Testing Report today. The HC-SR04 was tested in the Shields Testing Report Document 330937-002, which found compatible with G2 and Edison but not G1.

          From the sketch code there, you might find your timing problem.

          --- sketch begin

          /*
          HC-SR04 for Arduino 
          Original project from http://www.swanrobotics.com 

          This project demonstrates the HC-SR
          The distance presented in the code is in mm, but you can uncomment the line
          for distance in inches.
          The schematics for this project can be found on http://www.swanrobotics.com 
          This example code is in the public domain.
          */ 

          const int TriggerPin = 8;      //Trig pin
          const int EchoPin = 9;         //Echo pin

          long Duration = 0; 

          void setup(){  
            pinMode(TriggerPin,OUTPUT);  // Trigger is an output pin
            pinMode(EchoPin,INPUT);      // Echo is an input pin
            Serial.begin(9600);          // Serial Output

          void loop() { 
            digitalWrite(TriggerPin, LOW);                   
            delayMicroseconds(2);
            digitalWrite(TriggerPin, HIGH);          // Trigger pin to HIGH
            delayMicroseconds(10);                   // 10us high 
            digitalWrite(TriggerPin, LOW);           // Trigger pin to HIGH  
            Duration = pulseIn(EchoPin,HIGH);        // Waits for the echo pin to get high
                                                     // returns the Duration in microseconds
            long Distance_mm = Distance(Duration);   // Use function to calculate the distance 
            Serial.print("Distance = ");             // Output to serial
            Serial.print(Distance_mm); 
            Serial.println(" mm");  
            delay(1000);                             // Wait to do next measurement

          long Distance(long time)
          {
            // Calculates the Distance in mm  
            // ((time)*(Speed of sound))/ toward and backward of object) * 10     

            long DistanceCalc;                      // Calculation variable  
            DistanceCalc = ((time /2.9) / 2);     // Actual calculation in mm  
            //DistanceCalc = time / 74 / 2;         // Actual calculation in inches 
            return DistanceCalc;                    // return calculated value
          }

          --- sketch ends

          • 2. Re: Python HC-SR04 Sonar Setup
            CMata_Intel

            Hi toadaze;

             

            All your application is in python? In the Shields Test as deiumsaid you will find an example using an HC-SR04 module with the respective results, so you could use the IDE and create your own sketch.

            The interrupt function allows you to handle falling or raising edge interrupts.

             

            Regards;

            CMata

            • 3. Re: Python HC-SR04 Sonar Setup
              toadaze

              Thanks deium and cMata_Intel for the link.  I just tried the referenced Arduino sketch for the HC-SR04 and found something interesting. It runs great on an Arduino UNO and reports distances just as I would expect on out to at least 80cm.

               

              So then I moved the HC-SR04 back over to my Edison-Arduino and uploaded the same sketch using the modified Arduino IDE. It runs but gives results similar to what I experienced with my Python program in my above original post. It seems to work at very close distances but keeps reporting the same distance out past say 5cm.

               

              So, the HC-SR04 doesn't work correctly on my Edison-Arduino with an Arduino sketch using simple timing loops or with a Python program using the mraa-upm library.

               

              My next step is going to be getting out my old scope and measuring the trig pulse width. Its supposed to be 10usec. I suspect Edison-Arduino timing may be causing 'delayMicroseconds(10)' in the Arduino sketch to be too short or too long.  Same with the Python 'time.sleep(0.00001)' which should also be 10usec.

               

              The HC-SR04 requires a 10usec pulse on its trig pin to initiate a sonic burst.  So far I haven't found a datasheet that gives a tolerance for the 10usec.

               

              Stay tuned...

              • 4. Re: Python HC-SR04 Sonar Setup
                toadaze

                OK - here you go. According to my scope, 'delayMicroseconds(10)' on an Arduino UNO is indeed 10usec. However, 'delayMicroseconds(10)' on my Edison-Arduino is about 100usec or 10 times as long as it should be.

                 

                The Arduino UNO achieves this using a 16mhz crystal controlled clock.  The Arduino-Edison should be using some type of timing algorithm to achieve the same thing. But obviously something is off - both simulating an Arduino as well as Python timing.

                 

                Intel guys - can you check this on your equipment?

                 

                Thanks

                • 5. Re: Python HC-SR04 Sonar Setup
                  arfoll

                  Welcome to the world of linux & linux userspace programming . We cannot guaraantee how long delays will be. Sadly the HC-SR04 and similar sensors typically won't work like this.

                  • 6. Re: Python HC-SR04 Sonar Setup
                    toadaze

                    arfoll - yes, you are right, and I did realize using a high level program like my Python example above or the emulated Arduino example would be an issue with such timing. I was hoping whoever developed the mraa-upm sensor specific libraries like 'pyupm_hcsr04.py' in '/usr/lib/python2.7/site-packages' on the Edison was accessing the pins at a low enough level to avoid some unpredictable Linux system level delays. Several of those libraries are for other sensors that would also require tight timing. Surely these were tested?

                    • 7. Re: Python HC-SR04 Sonar Setup
                      deium

                      toadaze, I am not a python programmer, but skimming your code

                       

                      time.sleep(0.3)                           // sleep for 300 ms
                      trigPin.write(1)                            // pin high - start
                      time.sleep(0.00001)                   //    10 usec
                      trigPin.write(0)                            // pin low - end

                      while echoPin.read() == 0:               // while we are waiting
                          pulseOff = time.time()                   // keep setting pulseoff to now

                      while echoPin.read() == 1:                // once we get a response
                          pulseOn = time.time()                   // keep setting pulseOn to now

                      timeDifference = pulseOn - pulseOff         // <== seems like a duration of the echo
                      centimeters = timeDifference * 17000       // the time difference is in what unit?
                      print centimeters
                      centimetersStr = str(centimeters)
                      lcdDisplay.setCursor(0, 0)
                      lcdDisplay.write(centimetersStr)

                      • 8. Re: Python HC-SR04 Sonar Setup
                        arfoll

                        @ - There is no way from user space to avoid a non real time OS descheduling or doing weird things with timings of userspace programs. The module exists because we made it work 'ok' on a galileo gen1 and this was deemed to be acceptable. Honestly I'm tempted to remove it as it's AFAIK the only UPM module (the servo is the other 'odd' module) that depends on bitbanging. Most of the sensors are i2c/SPI based for this exact reason. If you require tight timings, non real time OS's & userspace programming are no good.

                         

                        The aim of UPM is to give people a kickstart in using some of these sensors, it's far from perfect. Please feel free to file issues on github.com/intel-iot-devkit/upm if you find something that doesn't work.

                         

                        Disclaimer: I work for Intel and am the architect of libmraa & UPM.

                        • 9. Re: Python HC-SR04 Sonar Setup
                          deium

                          toadaze, I am wondering if you tried the following - I am not a python programmer

                          Setting your time just before you echo, sleep while no echo, grab time when echo begins

                           

                          #hcsr04.py

                          import pyupm_i2clcd as lcd
                          import mraa
                          import time
                          import sys

                          # display - lcd
                          lcdDisplay = lcd.Jhd1313m1(0,0x3E, 0x62)

                          # digital output - trig
                          trigPin = mraa.Gpio(5)
                          trigPin.dir(mraa.DIR_OUT)
                          trigPin.write(0);

                          # digital input - echo
                          echoPin = mraa.Gpio(6)
                          echoPin.dir(mraa.DIR_IN)

                          time.sleep(0.3)
                          pulseOff = time.time()

                          trigPin.write(1)
                          time.sleep(0.00001)
                          trigPin.write(0)

                          while echoPin.Read() == 0;
                            time.sleep(0);

                          pulseOn = time.time();

                          timeDifference = pulseOn - pulseOff
                          Distance = timeDifference * 170145
                          centimeters = Distance / 10

                          print centimeters
                          centimetersStr = str(centimeters)
                          lcdDisplay.setCursor(0,0)
                          lcdDisplay.write(centimetersStr)

                          • 10. Re: Python HC-SR04 Sonar Setup
                            deium

                            arfoll, Since it worked good enough with Gen1, that would say that it would be good enough for the Quark that is about to be enabled on the Edison ?

                            If so, won't it have a second life in a few weeks?

                            • 11. Re: Python HC-SR04 Sonar Setup
                              arfoll

                              Try to set trigPin.useMmap(True). This will enabled memory mapped gpio read/write and should be much faster. It'll help.

                              • 12. Re: Python HC-SR04 Sonar Setup
                                arfoll

                                , no UPM uses libmraa which for the moment is pure Linux only. It will not support programming the Quark MCU in this way at least not in the short term. As you can see the code for that module hasn't been touched since June and will get removed when I get round to it (unless someone shows me a cool way to make it work? It's an opensource project and I'm always open to cool ideas )

                                • 13. Re: Python HC-SR04 Sonar Setup
                                  toadaze

                                  Thanks arfoll.  I understand. I've dealt with the same thing on other boards.

                                   

                                  I do have a suggestion. I know priorities may not be with Python, but would it be possible to have some simple examples of how to use the libraries on the Edison in the '/usr/lib/python2.7/site-packages' folder?  Since many or most of those are for specific sensors, it isn't always easy to figure out how to use them in Python.

                                   

                                  Thanks again.

                                  • 14. Re: Python HC-SR04 Sonar Setup
                                    deium

                                    arfoll, well I haven't been at this long enough yet to find all the cool ways, but my programming is on the Edison module over ssh, via Linux and the older Borland Kylix 3 platform.  The libmraa library for me has been a lifeline.

                                    1 2 Previous Next