Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Netduino and Ping))) Ultrasonic Sensor?


  • Please log in to reply
21 replies to this topic

#1 ddoodm

ddoodm

    New Member

  • Members
  • Pip
  • 8 posts
  • LocationSydney, Australia.

Posted 19 August 2010 - 07:26 AM

Hey everyone! I'm really liking the Netduino so far. Especially the multi-threading functionality. However, I've run into a problem trying to find a way to read the echo from a Ping Ultrasonic Sensor.

I noticed that in the original Arduino Ping sample sketch, they used this:
duration = pulseIn(pingPin, HIGH);
What is the equivalent in C# Micro?

Thanks for any help! I'd really appreciate it.
- Deinyon

#2 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 19 August 2010 - 07:51 AM

Hey everyone! I'm really liking the Netduino so far. Especially the multi-threading functionality. However, I've run into a problem trying to find a way to read the echo from a Ping Ultrasonic Sensor.

The following code can be used to measure pulse width. I have written it from head, because I don't have my Netduino by me right now, so please excuse any mistakes.

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

namespace NetduinoApplication
{
  public class Program
  {
    private static InterruptPort port;
    private static long ticks;

    public static void Main()
    {
      // TODO: Change the pin as needed
      port = new InterruptPort(Pins.GPIO_PIN_D0, false, ResistorModes.PullUp, InterruptModes.InterruptEdgeBoth);
      port.OnInterrupt += port_OnInterrupt;

      // Sleep, wait for interrupt
      Thread.Sleep(Timeout.Infinite);
    }

    static void port_OnInterrupt(uint data1, uint state, DateTime time)
    {
      if(state == 0)
      {
        // Falling edge - end of pulse
        var pulseWidth = time.Ticks - ticks; // TODO: Abs() to handle overflow
        var pulseWidthMilliseconds = pulseWidth/TimeSpan.TicksPerMillisecond;
        Debug.Print(pulseWidthMilliseconds.ToString());
      }
      else
      {
        // Rising edge - start of pulse
        ticks = time.Ticks;
      }
    }
  }
}


#3 ddoodm

ddoodm

    New Member

  • Members
  • Pip
  • 8 posts
  • LocationSydney, Australia.

Posted 19 August 2010 - 07:55 AM

The following code can be used to measure pulse width.


Thanks so much for that CW2! Really appreciate the code.

#4 Websteria

Websteria

    Member

  • Members
  • PipPip
  • 25 posts

Posted 19 August 2010 - 02:46 PM

We really need a wiki / svn library for all of these code libraries which are compatible with the netduino!!! :-D

#5 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 19 August 2010 - 02:55 PM

Hi Websteria, welcome to the community. ...we're working on it. We're making sure that the login databases, etc. are integrated and we have a good set of community guidelines in place first, but we will be making http://sandbox.netduino.com available as a wiki in the hopefully near future :) In the meantime: GitHub, CodePlex, and others are great places to share...and if you need your upload limit bumped up on the forums to post more code samples just let me know... Chris

#6 Chris Seto

Chris Seto

    Advanced Member

  • Members
  • PipPipPip
  • 405 posts

Posted 19 August 2010 - 06:11 PM

Hi Chris, I might recommend a pulseIn() addition to the Netduinp's firmware. This has come up plenty of times over at TinyCLR, too. pulseIn() is one of those universal functions that everyone seems to use that came from the Arduino. Same goes for map()

#7 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 20 August 2010 - 07:52 AM

I might recommend a pulseIn() addition to the Netduinp's firmware. This has come up plenty of times over at TinyCLR, too. pulseIn() is one of those universal functions that everyone seems to use that came from the Arduino.

If I understand it correctly, pulseIn() is a blocking function that does something like (pseudo-code, pulse active high):

while(!pin) { };
var timeStart = now;
while(pin) { };
var duration = now - timeStart;
I don't think such function has to be present in the firmware, because not everyone will use it due to its limitations - it cannot be used to measure short pulses, because of the performance constraints of the .NET Micro Framework and it cannot be used to reliably measure 'long' pulses either, because it will be interrupted at any time by the runtime, after its time slice (20 ms) expires and another thread will be scheduled for execution.

I understand this function is very useful at the beginning, to learn how things work (I was no different), but for other than fairly trivial applications, it is useless - soon one realizes that he needs to use asynchronous model (interrupts, events, threads) to achieve good results for tasks which were done sequentially on other hardware platforms (like 8-bit micros). Especially, given the .NET Micro Framework architecture.

I would suggest to place code of such a function in a separate "extensions" library, not the firmware itself - if it is not enough to have it published as code snippet somewhere on the web...

#8 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 20 August 2010 - 11:12 AM

[Follow-up] I would rather see support for timer Capture Mode implemented in the firmware Posted Image

#9 ddoodm

ddoodm

    New Member

  • Members
  • Pip
  • 8 posts
  • LocationSydney, Australia.

Posted 23 August 2010 - 10:45 AM

Hey guys! Sorry for the really late reply. Unfortunately, I'm having problems with CW2's code. The LED on the Ping Ultrasonic Sensor just stays green, and after placing a few breakpoints, it never reaches the interrupt function. I think you need to send 'true' or 'on' to the Ping for 5 microseconds before reading values from it. But I can't find any way to delay in microseconds. Thanks for your help again if possible!

#10 Zeb Tanner

Zeb Tanner

    New Member

  • Members
  • Pip
  • 2 posts

Posted 13 September 2010 - 05:08 AM

I picked up a Ping ultrasonic sensor (and a few other toys) at Radio Shack tonight.

After a bit of time futzing around with things, I seem to have it working with the code below. The sensor is connected to Ground, +5V, and Digital I/O D7.

The program displays (in the debugger output window) the measured distance, in cm, once every 5 seconds. (If you can't find your debugger output window ... go to the Debug Menu in Visual Studio, and pick Debug->Windows->Output.)

I'm now pointing the sensor at all kinds of random stuff, just to see how well it works.

Much fun.


using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

namespace NetduinoApplication2
{
    public class Ping
    {
        private TristatePort _port;

        // Pass in the pin to which the rangefinder is attached.
        public Ping(Cpu.Pin pin)
        {
            _port = new TristatePort(pin, false, false, ResistorModes.Disabled);
        }

        // Returns distance in mm
        public int mm_Distance()
        {

            // First we need to pulse the port ... high, low.  It seems to work fine, without adding any delay.
            _port.Active = true;                // Put port in write mode
            _port.Write(true);                  // Pulse pin
            _port.Write(false);

            _port.Active = false;                        // Put port in read mode;    
            bool v1 = false;
            while (v1 == false) { v1 = _port.Read(); }   // Wait for line to go high.
            long tick1 = System.DateTime.Now.Ticks;      // Save start ticks.

            bool v2 = true;
            while (v2 == true) { v2 = _port.Read(); }    // Wait for line to go low.
            long tick2 = System.DateTime.Now.Ticks;      // Save end ticks. 

            int ticks = (int)(tick2 - tick1);
            // Now, just have to convert ticks to mm
            //   Per wikipedia: speed of sound, dry air, 20 deg C, 343 m /s
            //   Per msdn: one .NET "Tick" = 0.1 micro seconds.
            // Which works out to ... 
            // ... 1 mm of travel each 29.15 ticks
            // ... divide by 2 for round-trip ... 58.3 ticks per mm

            return ticks * 10 / 583;
        }
    }

    public class Program
    {
        public static void Main()
        {
            Ping ping = new Ping(Pins.GPIO_PIN_D7);
            while (true)
            {
                int cm = ping.mm_Distance() / 10;
                Debug.Print(cm.ToString() + "cm");
                Thread.Sleep(5000);
            }
        }
    }
}



#11 Hai Nguyen

Hai Nguyen

    Advanced Member

  • Members
  • PipPipPip
  • 54 posts

Posted 13 September 2010 - 09:18 PM

So did it work well? I have couple of these sensors are on the way, I wonder how accurate/responsive these are, hope I didn't waste my $30.00 just because I went for the cheap ones ($15/piece, upto 3 meters distance).

#12 Zeb Tanner

Zeb Tanner

    New Member

  • Members
  • Pip
  • 2 posts

Posted 14 September 2010 - 01:32 AM

So did it work well?

I have couple of these sensors are on the way, I wonder how accurate/responsive these are, hope I didn't waste my $30.00 just because I went for the cheap ones ($15/piece, upto 3 meters distance).


It will definitely suit my desire to play!

Accuracy is almost certainly limited by the timing loop in my code ... not the sensor itself. Based on observed results, it seems to be in the ballpark of 1000 ticks per iteration which works out to about +- 2cm. By eyeball +- 2cm, feels about right. (I didn't, however, use a ruler.) Results are pretty consistent back-to-back -- no weird numbers jumping out. That'll work for a lot of stuff.

I assume some kind of a firmware level routine to time an input pulse would provide much better accuracy.

I tried, but could not get CW2's idea of using the InterruptPort to more accurately time the pulse. It seems like it would be a better way to do it. HOWEVER, for this sensor, on one pin, the port has to transition from writing a pulse, to receiving the result in time to catch the leading edge of the return pulse.

I tried creating an OutputPort to write the request pulse, calling Dispose() on the OutputPort and creating an InterruptPort to receive the respose. It seemed like I was only catching the trailing edge. If I get a bit of time, I'll play a bit more. Failing that, I suppose it's an excuse to learn how to bang on the firmware. :-)

#13 blackstag

blackstag

    New Member

  • Members
  • Pip
  • 2 posts

Posted 14 September 2010 - 01:36 PM

Thats good work will test it with a couple different ultrasonics I have laying around.

#14 Hai Nguyen

Hai Nguyen

    Advanced Member

  • Members
  • PipPipPip
  • 54 posts

Posted 14 September 2010 - 02:26 PM

Thats good work will test it with a couple different ultrasonics I have laying around.



Great, +-2cm is not big of a deal for what I am aiming to do as long as it responses fast and clean signal, nothing unpredictable. will see when I got mine on the mail.

What are the ranges of your sensors?
I have couple of these on the way: http://www.futurlec....e_Sensors.shtml

Thanks, Hai

#15 Eric Burdo

Eric Burdo

    Advanced Member

  • Members
  • PipPipPip
  • 130 posts

Posted 14 September 2010 - 06:41 PM

Thats good work will test it with a couple different ultrasonics I have laying around.


I have 2 as well... maybe I should try "talking" to them? :)
~ Eric D. Burdo ~ http://brick-labs.com/

Today LED's, tomorrow, the world!!! Well, OK, maybe servos.

#16 Hai Nguyen

Hai Nguyen

    Advanced Member

  • Members
  • PipPipPip
  • 54 posts

Posted 15 September 2010 - 10:18 PM

Crap, just found out on selleratings that the store where i bought my sensors from, It is very famous for being slow on delivery. It could take months for me to receive my sensors.

#17 greg

greg

    Advanced Member

  • Members
  • PipPipPip
  • 169 posts
  • LocationChicago, IL

Posted 15 September 2010 - 10:52 PM

Crap, just found out on selleratings that the store where i bought my sensors from, It is very famous for being slow on delivery. It could take months for me to receive my sensors.


I'd still go with Maxbotix. :P

#18 Omar (OZ)

Omar (OZ)

    Advanced Member

  • Members
  • PipPipPip
  • 564 posts

Posted 14 December 2010 - 11:58 PM

I get a constant data sett: 370cm 369cm 369cm 371cm 371cm 369cm 369cm It isn't working right... could you explain a little more on how the conversion works? Or if you have any clue why my data is wrong that would help too ;) Thanks EDIT: It was that the sensor was making contact between some connections because it was mounted on the bracket that parallax sells. Luckily I didn't kill it.

#19 ItsDan

ItsDan

    Advanced Member

  • Members
  • PipPipPip
  • 101 posts

Posted 22 February 2011 - 11:59 PM

Thanks for sharing this code. I just recently started wanting to learn about microcontrollers. I ordered the Arduino starter kit from SparkFun and before it had even arrived I'd seen a Netduino mentioned in MAKE magazine, saw it was .NET and had it overnighted from Amazon. As a long time .NET developer I just loved the idea of a .NET based microcontroller. Anyways I'm still in the experimenting stage but using the code above I was able to read pulse-widths being sent from a FlySky CT6 radio transmitter/receiver and convert it into a usable scale.
Follow the adventures of the Box of Crappy Surplus

Total BOCS Traveled Distance: 9708 miles | States Visited: 5
Track the Box

#20 joe_khese

joe_khese

    New Member

  • Members
  • Pip
  • 4 posts

Posted 23 December 2011 - 05:57 PM

hello guys, i am new to netduino, and i have been trying to write a code for the ping ultrasonic sensor but it doesn't work. can you pls take a look at it and tell me what u think?

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

namespace pingtest
{
    
    public class Program
    {
        private static TristatePort sig = new TristatePort(Pins.GPIO_PIN_D5, false, false, Port.ResistorMode.Disabled);

       static  long t1;
        static long t2;
        static long tick;
        static bool state;
        public static void Main()
        {
           // bool low = false;
           // bool high = true;
            

            while (true)
            {
                //output
                sig.Active = true;

                // write a 1 and //sleep for 10ms
                sig.Write(true);
                Thread.Sleep(10);

                // WRITE A LOW
                sig.Write(false);

                //input state
                sig.Active = false;

                // read sig into state
                state = sig.Read();

                calc();

                Thread.Sleep(Timeout.Infinite);


               

            }
        }
        public static void calc()
        {
            while (state == false)
            {
                //low = sig.Read();
                t1 = System.DateTime.Now.Ticks;
            }

            while (state == true)
            {
                //high = sig.Read();
                t2 = System.DateTime.Now.Ticks;
            }

            tick = (t2 - t1) / 688845000000;
            Debug.Print(tick.ToString());
           
            
        }

    }

}

Edited by Chris Walker, 15 January 2012 - 10:31 AM.
Added [code][/code] tags





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.