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