Round hysteresis to solve flickering values ​​due to noise

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

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

We show the user a linear position in increments of 1 mm. Ex. 1 mm, 2 mm, 3 mm, etc.

Problem: Our system can be used in electromagnetically noisy environments, which can lead to "flickering" of the linear position due to noise entering the ADC. For example, we will see such values ​​as: 39,40,39,40,39,38,40, etc., When the potentiometer is 39 mm.

Since we round to 1 mm, we will see a flicker between 1 and 2 if the value switches between 1.4 and 1.6 mm, for example.

Proposed software solution: Assuming we cannot change the hardware, I would like to add a hysteresis to the rounding of the values ​​to avoid this flicker. In this way:

If the value at the moment is 1 mm, it can go only up to 2 mm, if the initial value is 1.8 or higher. Similarly, if the current value is 1 mm, it can only go up to 0 mm, if the original value is 0.2 or lower.

I wrote the following simple application 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);
            }
        }
    }
}

Output Example:

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
+3
source share
3 answers

, N , N / ?

, . :

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

/ reset , X%.

+1

- -, . , . "1 " , . , , , . :

  • , .
  • " ". , . 2 , , 39, 40, 39, 38, 39mm
  • , ?
0

I think Gareth Rhys made an excellent answer to a very similar question: how to prevent the series frequency of integers

0
source

All Articles