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

Ultrasonic sensor code.


  • Please log in to reply
3 replies to this topic

#1 Jamo

Jamo

    Member

  • Members
  • PipPip
  • 13 posts

Posted 29 June 2013 - 11:47 AM

Over the last few days I've been knocking together a little class to run an HC-SR04 ultrasonic sensor, although I'm sure other brands/models would work too.

 

It works awesome except that when I add a second sensor the code just follows the second sensor and ignores the first.

 

Can anyone help?

/* UltraSonic Sensor Helper *  * Ultrasonic Sensor Interface, based on the HC-SR4 Ultrasonic Sensor  * Returns a range 200 - 400mm *  * Tested on Netduino 1 *  * Connections: * Netduino     UltraSonic Sensor * Digital Pin  Trigger * Digital Pin  Echo * 5V DC        VCC (3.3V DC works awesome as well) * GND          GND * */using System;using System.Threading;using Microsoft.SPOT;using Microsoft.SPOT.Hardware;using SecretLabs.NETMF.Hardware;using SecretLabs.NETMF.Hardware.Netduino;namespace SensorHelper{    /// <summary>    /// Ultrasonic Sensor Interface. Returns a range 200 - 400 mm. Based on the HC-SR4.     /// </summary>    public class UltraSonic    {        // initialise        private static InterruptPort EchoPulse;        private static Cpu.Pin trigPin;        private static Cpu.Pin echoPin;        private static long distance;               // in mm        private static long pulseWidthInTicks;      // ticks are microseconds / 10        private static long ticksCurrent;           // Current and Previous used to determine the pulse width        private static long ticksPrevious;          //        public UltraSonic(Cpu.Pin trigger, Cpu.Pin echo)        {            trigPin = trigger;          // Set digital pins for this particular sensor            echoPin = echo;                            ListenForEcho(echoPin);     // Start interrupt listening on echo pin        }        /// <summary>        /// Find the distance to an object from 200 - 400mm in range        /// </summary>        /// <returns>Range to object in mm</returns>        public int GetDist()        {            pingTriggerPin(trigPin);    // Send a short pulse on the digital pin                        return (int)distance;       // the distance in mm        }        /// <summary>        /// Sends a short ping to make the sensor search for an object        /// </summary>        /// <param name="trigPin">Digital pin connected to the sensors trigger pin</param>        private static void pingTriggerPin(Cpu.Pin trigPin)        {            // Send a short ping pulse on trigger pin             OutputPort pulseOut = new OutputPort(trigPin, false);            pulseOut.Write(true);   // Start ping            //Thread.Sleep(1);      // Ping length of 1ms, 5ms and no sleep (all work the same)                                    // (data sheet recommends ping of 10 mircoseconds / 0.01ms)            pulseOut.Write(false);  // Stop ping                        pulseOut.Dispose();             }        /// <summary>        /// Starts an interrupt on a digital pin to listen for the echo pulse from sensor        /// </summary>        /// <param name="echoPin">Digital pin connected the the sensors echo pin</param>        private static void ListenForEcho(Cpu.Pin echoPin)        {            // Listen for echo/pulseIn            EchoPulse = new InterruptPort(echoPin, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);            EchoPulse.OnInterrupt += EchoPulse_OnInterrupt;                 // Wait for echo response        }        /// <summary>        /// Interrupt for determining the length on the echo pulse        /// </summary>        /// <param name="data1">No sure what data1 is exactly</param>        /// <param name="state">Rising or Faliing edge of echo pulse</param>        /// <param name="time">Current time</param>        private static void EchoPulse_OnInterrupt(uint data1, uint state, DateTime time)        {                                 // Falling edge - end of echo pulse            if (state == 0)            {                              ticksCurrent = time.Ticks;                pulseWidthInTicks = ticksCurrent - ticksPrevious;           // This is where the echo pulse duration is determined                long pulseWidthMicroseconds = pulseWidthInTicks / 10;       // Convert to microseconds                if (pulseWidthMicroseconds < 250)  // Test for jitter                 {                    return;                }                else                {                    // The speed of sound is 340 m/s or 3400cm/ms or 3.4cm/us                     // Coverting to microseconds per centimetre (1 / 0.034) gives ~29 us/cm.                    // The sound ping travels out, bounces off and object and returns back to the sensor,                     // so to find the distance of the object we take half of the distance travelled.                    distance = (pulseWidthMicroseconds / 3) / 2;                }            }            // Rising edge - start of echo pulse            else            {                 ticksPrevious = time.Ticks;            }                }    }}

I'm using it like this...

            while (true)            {                int ping1 = ultraSonic1.GetDist(); // Range 200 - 400 mm                int ping2 = ultraSonic2.GetDist();                Debug.Print("Sensor 1: " + ping1.ToString() + "ttSensor 2: " + ping2.ToString());                toolBox.Pause(500);            }


#2 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 29 June 2013 - 02:58 PM

Hi! Found a few things to be a little odd, I'm not sure they'll solve your problem though. You are creating the trigger port each time GetDist() is called. If you wish to share the same trigger pin among multiple class instances, declare the trigger port member as static instead and make sure it only gets created once. Create both the trigger and echo ports in your constructor and store them in private members. Remove the pin members since there's no point in remembering those any more. About interrupts, when adding an event handler, you are only registering a method to be called if and when an interrupt occurs. You are not, as your comment implies, waiting for it to happen at that point. This also means you should move event handler registration to the constructor as well. How are the the instances ultraSonic1 and ultraSonic2 created, what parameters are passed to the constructor?

#3 Jamo

Jamo

    Member

  • Members
  • PipPip
  • 13 posts

Posted 30 June 2013 - 03:02 AM

Thanks for the advice. I will change the code to be as you say. With regard to the ultrasonic1 & ultrasonic2 instances they are as follows..

/*  Connections:    D0      SerialPort Rx *                  D1      SerialPort Tx *                  D2      motorLatch *                  D3      motorClock *                  D4      Ultrasonic sensor1 trigger pin *                  D7      motorEnable *                  D8      motorData *                  D5      pwm0A   Stepper Left *                  D6      pwm0B *                  //D9      pwm1A   Servos (only 4 pwm at a time :( ) *                  //D10     pwm1B      *                  D9      pwm2A   Stepper Right *                  D10     pwm2B *                  D11     Ultrasonic sensor1 echo pin *                  D12     Ultrasonic sensor2 trigger pin *                  D13     Ultrasonic sensor2 echo pin *                   *  Serial Communication:   COM1, 9600, Parity.None, 8, StopBits.One */// Default includesusing System;using System.Threading;using Microsoft.SPOT;using Microsoft.SPOT.Hardware;using SecretLabs.NETMF.Hardware;using SecretLabs.NETMF.Hardware.Netduino;// Project includesusing MotorShieldHelper;using MotionHelper;using SerialPortHelper;using ToolBoxHelper;using SensorHelper;namespace Robot{    public class Program    {        public static void Main()        {            ToolBox toolBox = new ToolBox();            UltraSonic ultraSonic1 = new UltraSonic(Pins.GPIO_PIN_D4, Pins.GPIO_PIN_D11);            UltraSonic ultraSonic2 = new UltraSonic(Pins.GPIO_PIN_D12, Pins.GPIO_PIN_D13);            while (true)            {                int ping1 = ultraSonic1.GetDist(); // Range 200 - 400mm                int ping2 = ultraSonic2.GetDist();                Debug.Print("Sensor 1: " + ping1.ToString() + "ttSensor 2: " + ping2.ToString());                toolBox.Pause(500);            }        }    }}

Thanks very much for the help.

 

James



#4 c2rosa

c2rosa

    Member

  • Members
  • PipPip
  • 15 posts

Posted 25 May 2014 - 11:43 PM

Thanks.....This worked well for me too.






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.