1 2 Previous Next 28 Replies Latest reply on Dec 12, 2014 10:36 AM by KurtE

    Ping Sensor - pinMode too slow?  (both Arduino and MRAA)

    KurtE

      Not sure if I should continue this under the thread: Who knows Edison's GPIO base address

      Or as I have done create a new one.

       

      I thought I would check out some of the code in the above thread by HoverSky but I don't believe I have the same sensor, but I did have an old Ping Sensor sitting around, so I thought I would try a ping...

       

      I was getting poor responses from this sensor, and I am pretty sure the issue is the time it takes to convert the IO pin from Output to Input...  So I instrumented the code some and you can see just how long it takes a long time for the device to switch from output mode to input mode.   In fact in many cases it is taking longer than the actual ping.

       

      As I mentioned, I have tried both MRAA and Arduino versions of code, with same results.

      I have also confirmed the digital pin mode change takes awhile, by toggling another IO pin around calls to pinMode (or mraa_gpio_dir)

       

      In case anyone is interested, here is a Quick and Dirty Arduino version:

      #define PING_PIN 2
      #define DBG_PIN 3
      
      // Quick and dirty ping
      void setup() {
        delay(2000);
        Serial.begin(115200);
      
        pinMode(PING_PIN, OUTPUT_FAST);
        pinMode(DBG_PIN, OUTPUT_FAST);
      
        //Test OUTPUT speed
        for(int i=0; i< 10; i++) {
          digitalWrite(DBG_PIN, HIGH);
          digitalWrite(DBG_PIN, LOW);
        } 
        //Test PinMode speed
        for(int i=0; i< 5; i++) {
          digitalWrite(DBG_PIN, HIGH);
          pinMode(PING_PIN, INPUT_FAST);
          digitalWrite(DBG_PIN, LOW);
          pinMode(PING_PIN, OUTPUT_FAST);
        } 
        delay(1000);  // make sure ping sensor is OK
      }
      
      unsigned long DoPing() {
        digitalWrite(DBG_PIN, LOW);  // make sure we are low...
        pinMode(PING_PIN, OUTPUT_FAST);
        digitalWrite(PING_PIN, HIGH);
        delayMicroseconds(3);
        digitalWrite(PING_PIN, LOW);
        delayMicroseconds(1);
        pinMode(PING_PIN, INPUT_FAST);
      
        // Now sure how many yet... 
        unsigned long ulLoopCnt = 1000000;
        while(!digitalRead(PING_PIN) && --ulLoopCnt)
          ;  // maybe yield...
      
        unsigned long ulStart = micros(); 
        if (!ulLoopCnt)
          return (unsigned long)-1;
        digitalWrite(DBG_PIN, HIGH);  
      
        ulLoopCnt = 1000000;
        while(digitalRead(PING_PIN) && --ulLoopCnt)
          ;  // maybe yield...
      
        unsigned long ulEnd = micros(); 
        if (!ulLoopCnt)
          return (unsigned long)-1;
        digitalWrite(DBG_PIN, LOW);  
      
        return (ulEnd - ulStart);
      }  
      
      void loop() {
        Serial.println(DoPing(), DEC);
        delay(250);  
      }
      
      

       

       

      Here is showing the timing in one case:

      Edison Ping.jpg

      The A1 marker is when in the code where I end the short pulse to start up a ping operation.  In the same line of the Logic Analyzer where the Pin sensor is starting to give you the reults where you are supposed to measure the width.  The A2 point is in the code where I switched the Ping IO line to Input mode nd hard looped waiting for it to go high at which point I save a few variables and then toggle the debug IO line high.... As you can see this is about half way through the actual pulse.  On the first line you can see where the pulse goes low, and and in the second line you can see where the code detected it and set the debug line low.  So the main difference between the going high and going low timings is the call to pinMode.  Note: There is currently a call to delayMicroseconds(1) as an experiment as was not sure if it was getting the IO line low before the switch to input mode.

       

      Not sure what else to try here...  Luckily I was doing this for a simple test and don't have any plans for the Ping sensor.

       

      Kurt

        • 1. Re: Ping Sensor - pinMode too slow?  (both Arduino and MRAA)
          DiegoV_Intel

          Hi KurtE,

           

          Thanks for sharing these results. I have had some issues using an ultrasonic sensor with the Galileo and the Edison for this reason. There is a kind of workaround which is using two pins instead of one. One pin will be the input and the other one the output, so there is no need to switch the pin mode between input and output using that way.

           

          Regards,

          Diego.

          • 2. Re: Ping Sensor - pinMode too slow?  (both Arduino and MRAA)
            KurtE

            Thanks,

             

            I still would like to see if there is some way to speed this up.

             

            Note: For this test I was using Arduino breakout board.  The mini breakout may be faster for this as less things it has to set.

             

            But would be nice if there was some quick switch from output to input, that maybe only has to change one or two settings, hopefully in a fast way.

             

            I personally do not need this sensor.  For distance would probably use others like the I2C based ones.  However there are other devices that do switch from input to output, that this would cause to not work on the Edison.

             

            Example: Orion Robotics (Basic Micro)PS2 controller, which uses one IO line.  Actually they use a half duplex serial interface that on most processors they do it using a hacked up  version of softwareserial (BMSerial).  Likewise their Servos, use RC signals, but do have feedback capabilities (example current position).  They do this by outputting a predefined short pulse, switch to input and wait for the servo to respond with a pulse...

             

            Again thanks,  As I mentioned I may still try some more hacking here.

            • 3. Re: Ping Sensor - pinMode too slow?  (both Arduino and MRAA)
              KurtE

              I have been playing around with this and do find lots of stuff going out to the two log files associated with Arduino sketch. (/tmp/log.txt and /tmp/log_er.txt)

               

              These are associated with the trace system (trace.h and trace.c)  So I thought I would see how long the switch from Output to Input is taking and how much of that was due to all of the trace information.

              So I bracketed the call with micros() calls to get the timing.

               

              I also hacked the program that if I have any Serial input, if first char is - I turn off tracing; trace_enable(0);

               

              If the character is in the range 0 to 2, I use that as the new trace level. trace_set_level.

              Note: trace_set_level is in the source file but not in the header, so I did an extern "C" of it in my sketch.

               

              Then after each ping, I print out Trace level, how long the pinMode took, average at that level, and the ping.  Here is what I am seeing:

              At start up (unless you change variant.h, the default is level 2(VARIANT_TRACE_LEVEL)

               

              What I am seeing is: TL= 2 DTP= 5704(5601) Ping=7572

              So the pinMode call is taking about 5.6ms

               

              If I change to mode 0 (Errors only) :  TL= 0 DTP= 4895(4838) Ping=5870

              That drops the call time to about 4.8ms (drop of about .8ms)

               

              If I turn it off:  TL= -1 DTP= 4350(4496) Ping=6467

              That drops me down to about 4.5ms which says tracing is taking over 1ms on each call.

               

              This also implies that errors are getting printed out for each call to pinMode?  Here is what is being printed:

              sysfs-error: err set drive fs_path=/sys/class/gpio/gpio214/drive
              
              sysfs-error: err set drive fs_path=/sys/class/gpio/gpio250/drive
              
              sysfs-error: err set drive fs_path=/sys/class/gpio/gpio218/drive
              
              sysfs-error: sysfsGpioSetCurrentPinmux: gpio128, mode=2
              sysfs-error: set pinmux mode0 fs_path=/sys/kernel/debug/gpio_debug/gpio128/current_pinmux
              
              sysfs-error: err set drive fs_path=/sys/class/gpio/gpio214/drive
              
              

               

              Most of these are just saying we are setting a mode.... Don't think that is an error.

               

              The Bad handle for pin2, is because every time we call pinMode, it calls of to turn off PWM on the pin.  But it finds that pin 2 is not in the table of PWM pins and errors out.  Again I don't think this should be reported as error. Maybe should be: TRACE_LEVEL_DEBUG (2)

               

              Also suggestion maybe default tracelevel should be 0 or 1 and many of the current traces should be below the default trace.

               

              I can post the updated example code if you would like.  Still looking into other stuff going on as 4.5ms is way too slow to work with devices like this.

               

              Kurt

              • 4. Re: Ping Sensor - pinMode too slow?  (both Arduino and MRAA)
                KurtE

                Notes to self and questions to Intel and/or MRAA people...

                When I do pinMode(2, INPUT_FAST)  - The current stuff it does includes:

                Checks a couple different ways there is no VariantPinMode nor VariantPinEnableFastGPIO actually not on any pin here...)

                 

                Then it does a MuxSelect which does: Extracted from Variant.cpp

                
                
                
                
                //gpio, value, type
                
                
                
                    { 214, LOW, FN_GPIO }, // Tristate disabled for all pins
                    { 250, HIGH, FN_GPIO_OUTPUT }, // Output enabled
                    { 250, LOW, FN_GPIO_INPUT }, // Output disabled
                    { 218, HIGH, FN_GPIO_INPUT_PULLUP}, // Pullup enabled
                    { 218, LOW, FN_GPIO_INPUT_PULLDOWN }, // Pulldown enabled
                    { 218, NONE, FN_GPIO_OUTPUT | FN_GPIO_INPUT_HIZ }, // Pullup disabled
                    { 128, PIN_MODE_0, FN_GPIO }, // GPIO mode
                    { 214, HIGH, FN_GPIO } // Tristate enabled for all pins
                };
                

                 

                So the 214 line Opens/Rewind/write/close - two files: /sys/class/gpio/gpio214/direction /sys/class/gpio/gpio214/drive

                It also sets the value, using a file that is already open(I think), rewind/write

                 

                250 Line with input does the same as 214

                 

                218 (INPUT_HIZ) Also opens files and the like

                 

                128 line Sets the MUX to say we are doing GPIO

                 

                214 does the same as the 214 line above.

                 

                Finally the code will actually change the actual pin from Output to input.  Again it opens file (/sys/class/gpio/gpio128/direction) and

                sets value..

                 

                --------------------------------------------

                Appears to me there is lots of performance enhancements possible

                The 214 lines are done all the time, always output, dont need to keep setting output, nor setting the drive.

                250 is also always output again somehow know this and only change value

                 

                218 - Have to look at difference of High/Low versus none, but some shortcuts should be able to be done.  Besides going from OUTPUT to INPUT_HIZ is the same rule, same values, so should be able to avoid this whole step.

                 

                128 - Again INPUT to OUTPUT is still GPIO so don't need to do this

                 

                Changing Direction: In the memory mapped code there are three offsets in the per pin data (Clear/Set/Read)  Are there others?  Can you set the direction through this?

                 

                Again just notes to myself and maybe beginning of look at ways to bypass some of the MUX stuff when switching between related modes.

                 

                Kurt

                • 5. Re: Ping Sensor - pinMode too slow?  (both Arduino and MRAA)
                  KurtE

                  Again not sure if any one is interested, but I did make some progress here on my own copy of the Arduino IDE...

                   

                  That is if you look at the timings I showed for the pinMode in posting 3 and now compare it to my current stuff you see:

                   

                  TL= -1 DTP= 1398(1419) Ping=9125

                  So for trace turned off I now average about 1.42ms versus before 4.35ms

                   

                  With it at default trace level now I have:

                  TL= 2 DTP= 1438(1479) Ping=9091

                  So about 1.48ms versus 5.6ms  so again I pretty good gain.

                   

                  Note: It the detection of pin going high is still a ways after it happens as you can see in:

                  Edison Ping.jpg

                  But it is getting closer and maybe somewhat useable, not sure how much more I can do here...

                   

                  What I did was to get rid of some pointless messages, like (telling me a pin is going to mode0) or a pin is not a PWM pin everytime I change the mode of any pin...

                   

                  But more importantly change the code to a couple of functions, to instead of passing in Edison pin number, pass in pointer to PinDescription, where I cache the information and if the pin is already at that state don't redo it...

                   

                  I don't know if anyone would like to see the changes I made?

                   

                  Kurt

                  • 6. Re: Ping Sensor - pinMode too slow?  (both Arduino and MRAA)
                    KurtE

                    DiegoV_Intel and Others,

                     

                    Quick question on trying out changes to the Arduino IDE software.

                     

                    As you can tell from my above posting, doing the caching of data and minimizing some of the logging of stuff, can really improve the performance of some of the different commands that use the Pin Mux definitions and the like. 

                     

                    The question, is, Is there some place I should post or email or put up on github, my  version or changes, such that someone might want to take a look and optionally integrate some of it into a future IDE release? 

                     

                    Likewise when I continue to make more progress of having support for mini breakout board, which I have the replacement one I purchased.  I just need to solder in some breakout pins... 

                     

                    Kurt

                     

                    P.S. - I am trying a different hack way to see I can get faster pulse, which so far I have not gotten to work.  Instead of going into output mode (Do pulse), go into input mode.  I thought i would try stay in input mode, set PU high, set PD Low, turn off PU... So  far on  Arduino board not helping much...

                    • 7. Re: Ping Sensor - pinMode too slow?  (both Arduino and MRAA)
                      DiegoV_Intel

                      Hi KurtE,

                       

                      Regarding your previous post, I invite you to share the changes you made. I believe the tests you have been doing are really interesting, and could be useful for other users as well.

                       

                      Now, regarding your latest question about send the changes you made, you can post them here; in the Edison Community, or you could send an email to Edison Support. For the second option you should fill the form in this link: Intel Support. Feel free to choose whichever you want.

                       

                      Regards,

                      Diego.

                      • 8. Re: Ping Sensor - pinMode too slow?  (both Arduino and MRAA)
                        Reach41

                        I suggest you continue to post ALL your work here.  I have yet to see anyone who sells the Arduino-flavored board address the issue with overflowing the memory.  This is the one place, with you one of the main players, where the slightly more advanced can get answers.

                         

                        Thanks,

                         

                        Gary

                        PS: Why are you playing with the Arduino IDE, and not Eclipse or some such?

                        • 9. Re: Ping Sensor - pinMode too slow?  (both Arduino and MRAA)
                          KurtE

                          Thanks DiegoV_Intel  I may do a combination of both approaches.  The question I have, is how to post code changes.

                           

                          One approach would be to make a zip file that has all of the changed files.  That is what I would do on many forums, but don't see any way to attach files other than pictures.  Could put the zip file up on some remote server like dropbox or the like, but I don't trust too many of these...

                           

                          With changes to mraa, I put them up on github.  I would(have) cloned the project, create a new branch, upload the changes and when happy, would do a pull request back to the main project... (which I have done before)

                           

                          So with Arduino IDE stuff, could create github project with all or part of the IDE.  Example maybe just the .../hardware/arduino branch

                          Probably only the Edison branch to start with as I have not made changes to X86 yet....

                          This is probably the easiest way for people to track the changes... Does this sound OK with you?

                           

                          Reach41 - Yes I will continue post the different things I do up here, as hopefully others can make use of any improvements and/or avoid some of the many pitfalls I run into.

                           

                          Actually I bounce back and forth using different ways to do stuff.   Why? As a retired software engineer who still enjoys tinkering, but who has no specific project that I have to get done, I  enjoy doing stuff that hopefully others can make use of.  

                           

                          (Dribble removed) - I was going to mention, that I have been experimenting with robots, mostly Hexapods/Quads for several years now, and have tried out quite a few different boards....

                           

                          Why Arduino IDE - Because probably any changes made here will hopefully positively impact the most people.  That is the instructions for starting up to use this board, goes through the steps of using the IDE...    Also it helps me to understand some of the capabilities and see if it those capabilities are available in MRAA and if not, try to add it...  I am also thinking that when Trossen Robotics releases their Edison board and if I can make the IDE work well with their board, some of the others I have done stuff with can easily choose to use that board.   Several of them have just recently transitioned from the Lynxmotion/Basic Micro Boards that use basic, to Arduino 328 boards.  A few of them are also now experimenting using some carrier boards for the Teensy 3.1. 

                           

                          But I also spend a lot of my time Native to the Edison.  that is I use PuTTY and WinSCP to talk to the Edison and use external editors like Programmers Notepad or Geany to edit the files and use makefiles to build...  I have my main linux project up on github (Raspberry_Pi), that I have setup to be able to build code for seveal of my robots (Hexapods, Arm, Rover) on several different linux boards.  Actually I keep meaning to take a pass through this project and clean it up and  maybe convert to using cmake, which hopefully can hide some of the issues like finding the gcc compiler...

                           

                          As I mentioned earlier in this thread, MRAA also has performance issues associated with being able to switch between input and output fast enough for these sensors.  I will probably take a little time now and see if  I can make similar changes to it.  Also now that I have a working mini breakout board will try it out here too.  Probably better chance to make it work here as fewer things have to change...

                           

                          I have not done very much yet with Eclipse, when I earlier tried to use it for different platforms it often was not obvious how to configure it to work with the different boards... I will probably get back to it soon as it looks like a pretty good IDE...

                           

                          Again sorry for the dibble that made it through here

                          • 10. Re: Ping Sensor - pinMode too slow?  (both Arduino and MRAA)
                            DiegoV_Intel

                            Hi KurtE,

                             

                            That sounds fine. Regarding attaching files, you can do it. Just go to advanced editor when you are writing your reply, and then click in the attach button. Take a look to the screenshots below. For the rest, I believe all your tests are really helpful so I invite you to keep posting them.

                             

                            Advanced editor:

                            Attach files 1.png

                            Attach button:

                            Attach files 2.png

                             

                            Regards,

                            Diego.

                            • 11. Re: Ping Sensor - pinMode too slow?  (both Arduino and MRAA)
                              KurtE

                              Thanks,

                               

                              It is funny, I thought the attach was there, but then for some reason it did not show up there and now it does...

                               

                              Warning, this is again a Work In Progress.  I have included some of the stuff for both the speed ups here, plus the beginnings of setup to work with the mini breakout board.  I know some of the breakout stuff works, but I need to get back to testing it...  Yesterday I soldered on the power connector and breakout pins on the new one.  Will begin testing again and flush out some more of it.  I know I probably need to add more stuff in to each pin for PU/PD definitions. Will have to see how that plays out as how that is done is completely different than Arduino board.... But different thread.

                               

                              AGAIN WIP WIP WIP

                              • 12. Re: Ping Sensor - pinMode too slow?  (both Arduino and MRAA)
                                Reach41

                                Kurt, thanks for the dribble.  If I started a private Yahoo group, would you be interested in joining it?

                                 

                                I'm a robotics guy, retired mech engr from Northrop-Grumman, etc.  Not professional, but as a hobby of 25 years or so.  I bought the Edison because it's perfect for battery-driven projects.  I have a couple of Mega's on my latest robot, one of which is handling encoders on 4 wheels, commanding the motors, and integrating data from a MEMS 9 axis sensor.  The other is processing IR ranging module data (3 modules mounted on a pan/tilt mechanism), dealing with a text to speech board, and running an LCD.  I have yet to add several sonar sensors for obstacle detection, but they're coming.  The two Mega's would be adequate, but not for handling an occupancy grid 1000 feet on a side -- practically no memory on the Mega for that kind of thing, (not to mention the time it would take to optimize such a grid) or even one very much smaller.

                                 

                                With your help, I have SPI working on the Edison, and communicating with the two Mega's run in slave mode.  That's the only contact the Edison will have with the outside world, as the Megas send up sensor data, and respond to executive commands from the Edison.  I am, for now, using the Edison-colored Arduino IDE, but I wonder if I wouldn't be a whole lot better off running the Edison in a native mode, rather than through an interpreter.  I have Eclipse set up and compiling, even ran the blink routine.  But haven't yet spent the time to figure out running programs out of reset...  Also, WIFI interface for sending data back to my desktop (WIN7) from the Edison might be helpful, if I can figure all that out as well (have the connection set up per Intel's Windows setup guide).

                                 

                                Keep up the good work!  You are a critical resource for people like me who've been around the yard awhile, but aren't focused specifically on operating systems, linux, or various IDEs.

                                • 13. Re: Ping Sensor - pinMode too slow?  (both Arduino and MRAA)
                                  KurtE

                                  Thanks Reach41,

                                   

                                  As for Private groups, not sure.  I am a pretty private person, so mostly try to do all my Robotics stuff publicly.  Not sure if that makes sense.   But I do join different forums and groups if it is toward stuff I am playing with, so depending on what your groups is???

                                   

                                  I started playing with the Edison as I do a lot of my Robotics stuff with some of the people up at Trossen Robotics and their new robot is going to use an Edison, with their own breakout board.  They are also saying that the robot will have an Arbotix Pro board with an Arm Cortex-M3 board, doing most of the IO...  So from their description I am not sure what features will actually be on their Edison board.  But in the mean time I am trying to learn as much as I can about the Edison and hopefully through my learning others learn some stuff as well.

                                   

                                  I will continue to experiment with the different features and hopefully make a few more contributions along the way.  Currently looking at some potential changes to MRAA for speed to see if the ping can work...

                                   

                                  Thanks for the offering to my profile for the skill "Linux Expert", but I will probably decline it as I feel more like a: Linux not quite as green as before title, as there is so much of Linux that I am a complete novice at, like building and extending kernel.... But again Thanks.

                                  • 14. Re: Ping Sensor - pinMode too slow?  (both Arduino and MRAA)
                                    deium

                                    well, KurtE, I had trouble nominating the "linux: not quite as Green as before".  Must be the forum

                                    1 2 Previous Next