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