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

Measures "jumping"?


  • Please log in to reply
5 replies to this topic

#1 BernardG

BernardG

    Advanced Member

  • Members
  • PipPipPip
  • 34 posts

Posted 26 July 2011 - 11:06 AM

I have seen this before with a thermometer reading, now I have the same with a ultrasonic sensor.
The code works well and the variations are on a few millimeters, but I would like to know what I could do to eliminate, or at least reduce as much as possible those variations.

Here is my code (I am using a cheap HC-SR04 sensor)

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


// Written by BG on July the 25th 2011 to test the HC-SR04 sensor
namespace Netduino_UltraSonicSensor
{
    public class Program
    {
        private static int ticks;
        
        private static InterruptPort EchoPin = new InterruptPort(Pins.GPIO_PIN_D10, true, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);
        private static OutputPort TriggerPin = new OutputPort(Pins.GPIO_PIN_D12, false);
        
        public static void Main()
        {
            EchoPin.OnInterrupt += new NativeEventHandler(port_OnInterrupt);
            EchoPin.DisableInterrupt();
            while (true)
            {                
                Distance();
                //Debug.Print("distance = " + myDistance + " mm.");
                Thread.Sleep(1000);
            }
        }

        public static void Distance()
        {
            EchoPin.EnableInterrupt();
            TriggerPin.Write(false);
            Thread.Sleep(2);
            TriggerPin.Write(true);
            Thread.Sleep(10);
            TriggerPin.Write(false);
            Thread.Sleep(2);
        }
            
        private static void port_OnInterrupt(uint port, uint state, DateTime time)
        {
            if (state == 0) // falling edge, end of pulse
            {
                int pulseWidth = (int) time.Ticks - ticks;
                // valid for 20°C
                //int pulseWidthMilliSeconds = pulseWidth * 10 / 582;
                //valid for 24°C
                int pulseWidthMilliSeconds = (pulseWidth * 10 / (int)578.29);
                Debug.Print("Distance = " + pulseWidthMilliSeconds.ToString() + " millimètres." );
            }
            else
            {
                ticks = (int)time.Ticks;
            }
            EchoPin.ClearInterrupt();
        }

    }
}

and here are my readings:

Posted Image

I use 5v as it does not work in 3.3v, and I am a total beginner in electronics, so if there is a proper way to stabilize the 5 volts alimentation, I am all ears...

Thanks for any help.

#2 BernardG

BernardG

    Advanced Member

  • Members
  • PipPipPip
  • 34 posts

Posted 26 July 2011 - 11:10 AM

Forgot to say that I checked with a meter, and the measurement is accurate to +- 5 millimeters, maybe a bit less. (+-3)

#3 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 26 July 2011 - 12:15 PM

Hello Bernard. I don't think the 5V supply would be a problem. I'd look a bit deeper for the sensor specs, but I wouldn't worry about. The precision of the reading is according to the values you get. Being an ultrasonic sensor, many factors could shift the measure from the nominal value. Just think to the air: the measure is based on the speed of the sound in the air (340m/s). That's *NOT* constant: may vary with temperature, pressure, humidity, etc. Another factor that produces "noise" on the readings is the inability of having good time measurements by the managed framework (.Net Micro Framework). You cannot rely on the timing, because the is the Garbage Collector sometime working. That could lead to delays on the interrupt. The easiest way to get a more stable reading is to apply an average on the samples. Unfortunately an average act as a low-pass filter, and this leads to a slower responsiveness meter reading. Anyway, a good algorithm that I've used many times with success is the following: const int N = 4; distance = (distance_old * (N-1) + distance_read) / N; Where the "distance_read" is the value unaveraged, just as the sensor gives you. "distance" is the official value (averaged), that should be shown to the user. Finally, "distance_old" is the copy of "distance" at the latter calculation. The parameter N may vary upon tastes. The higher is N, the higher is the stabilization, but also that leads a much slower responsiveness. I'd suggest to keep it from 3 to 10. Cheers
Biggest fault of Netduino? It runs by electricity.

#4 ItsDan

ItsDan

    Advanced Member

  • Members
  • PipPipPip
  • 101 posts

Posted 26 July 2011 - 02:48 PM

There's a good chance that variation is within the precision of the sensor and you won't eliminate it without a more expensive/precise sensor. However what you can do is round the value, or filter it, of which I'd suggest the latter. Make the outputted reading an average of the last 10 readings, see where that gets you.
Follow the adventures of the Box of Crappy Surplus

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

#5 BernardG

BernardG

    Advanced Member

  • Members
  • PipPipPip
  • 34 posts

Posted 26 July 2011 - 03:00 PM


const int N = 4;
distance = (distance_old * (N-1) + distance_read) / N;

Where the "distance_read" is the value unaveraged, just as the sensor gives you. "distance" is the official value (averaged), that should be shown to the user. Finally, "distance_old" is the copy of "distance" at the latter calculation.
The parameter N may vary upon tastes. The higher is N, the higher is the stabilization, but also that leads a much slower responsiveness.
I'd suggest to keep it from 3 to 10.
Cheers


Thanks for your answer, Mario. I had done something like that for the temperature sensor, reading values everything second on a minute, and returning the average. it works pretty well. I am working on doing something similar here.

Also I added a thermometer to get a more accurate speed of sound calculation.

#6 BernardG

BernardG

    Advanced Member

  • Members
  • PipPipPip
  • 34 posts

Posted 26 July 2011 - 03:01 PM

There's a good chance that variation is within the precision of the sensor and you won't eliminate it without a more expensive/precise sensor. However what you can do is round the value, or filter it, of which I'd suggest the latter. Make the outputted reading an average of the last 10 readings, see where that gets you.


Thanks, I am working around that idea. I was just hoping for something more "technical", if I can say so.

Bernard




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.