4

Background: We have an embedded system that converts linear positions (0 mm - 40 mm) from a potentiometer voltage to its digital value using a 10-bit analog to digital converter.

    ------------------------
0mm |                      | 40 mm
    ------------------------

We show the user the linear position at 1 mm increments. Ex. 1mm, 2mm, 3mm, etc.

The problem: Our system can be used in electromagnetically noisy environments which can cause the linear position to "flicker" due to noise entering the ADC. For example, we will see values like: 39,40,39,40,39,38,40 etc. when the potentiometer is at 39 mm.

Since we are rounding to every 1 mm, we will see flicker between 1 and 2 if the value toggles between 1.4 and 1.6 mm for example.

Proposed software solution: Assuming we can not change the hardware, I would like to add some hysteresis to the rounding of values to avoid this flicker. Such that:

If the value is currently at 1mm, it can only go to 2mm iff the raw value is 1.8 or higher. Likewise, if the current value is 1mm it can only go to 0mm iff the raw value is 0.2 or lower.

I wrote the following simple app to test my solution. Please let me know if I am on the right track, or if you have any advice.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PDFSHysteresis
{
    class Program
    {
        static void Main(string[] args)
        {
            double test = 0;
            int curr = 0;
            Random random = new Random();

            for (double i = 0; i < 100; i++)
            {
                test = test + random.Next(-1, 2) + Math.Round((random.NextDouble()), 3);
                curr = HystRound(test, curr, 0.2);

                Console.WriteLine("{0:00.000} - {1}", test, curr);
            }

            Console.ReadLine();
        }

        static int HystRound(double test, int curr, double margin)
        {

            if (test > curr + 1 - margin && test < curr + 2 - margin)
            {
                return curr + 1;
            }
            else if (test < curr - 1 + margin && test > curr - 2 + margin)
            {
                return curr - 1;
            }
            else if (test >= curr - 1 + margin && test <= curr + 1 - margin)
            {
                return curr;
            }
            else
            {
                return HystRound(test, (int)Math.Floor(test), margin);
            }
        }
    }
}

Sample output:

Raw      HystRound
======   =========
00.847   1
00.406   1
01.865   2
01.521   2
02.802   3
02.909   3
02.720   3
04.505   4
06.373   6
06.672   6
08.444   8
09.129   9
10.870   11
10.539   11
12.125   12
13.622   13
13.598   13
14.141   14
16.023   16
16.613   16
4

3 回答 3

1

How about using the average of readings for the last N seconds, where N could be fairly small / sub-second depending on your sample rate?

You can use a simple linear average, or something more complex, depending on your needs. Several moving average algorithms are detailed on Wikipedia:

http://en.wikipedia.org/wiki/Moving_average

Depending on your sensitivity / responsiveness needs, you could reset the average if a new reading exceeds the running average by X%.

于 2012-05-01T21:38:06.397 回答
0

I had to deal with something similar sometime ago where I had to read voltage output from a circuit and display a graph on a computer screen. The bottom line is, this really depends on your system requirements. If the requirement is "1mm" accuracy then there is nothing you could really do. Otherwise, as mentioned above, you could go with several methods that can help you out lessen the flickering. You can:

  • Calculate the average of these values over a certain period of time the user can configure.
  • Allow the user to set a "Sensitivity threshold". This threshold can be used to decide on weather to consider the new value as valid or not. In your example, the threshold can be set to 2mm in which case values such as 39, 40, 39, 38 would read as 39mm
  • Also, have you thought about putting an external stabilizer between your application and the hardware itself?
于 2012-05-01T21:50:05.240 回答
0

I think Gareth Rees gave an excellent answer to a very similar question: how to prevent series of integers to have the same value to often

于 2013-08-08T08:27:55.657 回答